Aus Raspberry Pi Geek 04/2018

RFID-Card-Reader mit RasPi 3 und 125-kHz-Reader-Shield (Seite 2)

dtoverlay=pi3-miniuart-bt
enable_uart=1

Anschließend speichern Sie die Datei (in Nano etwa über [Strg]+[X],[Y],[Eingabe]) und verlassen den Editor wieder. Zum Abschluss starten Sie den Raspberry Pi neu, um die UART-Schnittstelle zu aktivieren.

RFID-Karten auslesen

Nun genügt ein kurzes Python-Skript, um die Daten eines RFID-Transponders über die Antenne des Shields auf den RasPi 3 einzulesen. Das Beispiel in Listing 3 liest die ID einer Karte mit dem Format HITAG 2 ein und gibt diese auf der Konsole aus.

Das Format HITAG 2 bietet einen frei beschreibbaren Speicherbereich, der sich beispielsweise zu Buchungszwecken oder zur Abrechnung verwenden lässt (Buchung von Speisen in einem Bistro oder in einer Mensa). Dabei wird Geld auf die Karte gebucht und später bei der Bestellung einer Speise verrechnet. Das in diesem Artikel beschriebene Projekt diente ebenfalls der Buchung beziehungsweise Nachbuchung von Speisen, zwar in einem etwas anderen Kontext und System, aber vergleichbar mit einem Bezahlvorgang in einer Mensa für Studenten.

Sie speichern das Skript unter einem beliebigen Dateinamen und rufen es aus dem Ordner, in dem es liegt, in einem Terminal mit dem Befehl Python3 Name.py auf.

Listing 3

 

#!/usr/bin/env python3
import wiringpi as wiringpi2
import RPi.GPIO as GPIO
import time
import sys
import argparse
# set for GPIO Pin to use based on jumper connection
# GPIO_PIN = 0 # Jumper 2 (GPIO17)
GPIO_PIN = 1 # Jumper 1 (GPIO18)
# GPIO_PIN = 2 # Jumper 3 (GPIO21 (Rv1) / GPIO27 (Rv2))
# GPIO_PIN = 3 # Jumper 4 (GPIO22)
# Reader Options:
def WaitForCTS():
  # continually monitor the selected GPIO pin
  # and wait for the line to go low
  while wiringpi2.digitalRead(GPIO_PIN):
    # do nothing
    time.sleep(0.001)
  return
def RFIDSetup():
  # call setup for the WiringPi2 software
  response = wiringpi2.wiringPiSetup()
  # set the GPIO pin for input
  wiringpi2.pinMode(GPIO_PIN, 0)
  # open the serial port and set the speed accordingly
  fd = wiringpi2.serialOpen('/dev/serial0', 9600)
  # clear the serial buffer of any left over data
  wiringpi2.serialFlush(fd)
  if response == 0 and fd > 0:
    # if wiringpi is setup and the opened channel
    # is greater than zero (zero = fail)
    print ("Pi setup complete on channel %d" %fd)
  else:
    print ("Unable to setup communications")
    sys.exit()
  return fd
def FactoryReset(fd):
  # send the factory reset command
  WaitForCTS()
  wiringpi2.serialPutchar(fd, 0x46)
  wiringpi2.serialPutchar(fd, 0x55)
  wiringpi2.serialPutchar(fd, 0xAA)
  time.sleep(0.1)
  print ("FACTORY RESET COMPLETE ")
  print ("")
  return
# read RFID tag
def ReadTagPageZero(fd):
  notag = True
  print("Bitte Tag einlesen...")
  while notag:
    WaitForCTS()
    wiringpi2.serialPutchar(fd, 0x52)
    wiringpi2.serialPutchar(fd, 0x00)
    time.sleep(0.1)
    # list of values
    values = []
    result = wiringpi2.serialGetchar(fd)
    if result == int("0xD6", 16):
      print("Tag erkannt")
      # read data and insert into list
      while wiringpi2.serialDataAvail(fd):
        value = wiringpi2.serialGetchar(fd)
        values.insert(0, value)
      notag = False
      new_value = 0
      # shift data to get a correct int value
      for j in values:
        new_value *= 256
        new_value += j
      # fill the value up to 13 numbers
      new_value = str(new_value).zfill(13)
      print("\n\nTag gelesen... Wert: %s\n\n" % new_value)
      # wait 2 seconds to read another RFID-Card
      time.sleep(2)
      ReadTagPageZero(comms)
  return
# Main Routine
try:
  comms = RFIDSetup()
  FactoryReset(comms)
  ReadTagPageZero(comms)
except KeyboardInterrupt:
  GPIO.cleanup()

Das Skript lädt zunächst einmal die benötigten Bibliotheken (Zeile 3 bis 7), darunter auch WiringPi2, und legt den zu verwendenden GPIO-Pin fest (Zeile 1).

Die Hauptroutine bereitet als Erstes über die Funktion RFIDSetup() WiringPi entsprechend vor, um die Kommunikation zu gewährleisten. Dabei setzt die Funktion insbesondere den GPIO-Pin und initialisiert den verwendeten seriellen Port. Anschließend setzt FactoryReset() das Shield auf die Verwendung des Formats HITAG 2 zurück.

Bei der anschließend aufgerufenen Funktion ReadTagPageZero() (Zeile 24 bis 32) handelt es sich um das eigentliche Herzstück des Skripts zum Auslesen und Aufbereiten der Daten. Die Routine wartet zunächst über die Funktion WaitForCTS()” (Zeile 16 bis 22) auf den Eingang eines Informationsstroms, den Sie dann via wiringpi2.serialGetchar() zeichenweise ausliest und dabei die ID der RFID-Karte ermittelt.

Da die ID auf der Karte im Little-Endian-Format vorliegt, man sie zur Weiterverarbeitung aber häufig im Format Big-Endian benötigt, bereitet das Skript die Daten in der Variablen new_value entsprechend auf (Zeile 80 bis 82). Die ID besteht in der Regel aus 13 Zeichen, weshalb die Routine sie mittels zfill() auf eben diese Zeichenmenge aufstockt (Zeile 84) und dann im Terminal ausgibt (Zeile 85). Nach einer kurzen Pause startet die Routine erneut, um eine weitere RFID-Karte einzulesen (Zeile 88 und 89).

Auf eine Option zum Ändern des Formats oder das Lesen des freien Speicherbereichs verzichtet unser Beispielskript. Anhand der – allerdings recht unübersichtlichen – Dokumentation und des Github-Codes zum Shield [3] lassen sich bei Bedarf entsprechende Funktionen jedoch nachvollziehen.

Fazit

Schon mit einfachen Mitteln lässt sich ein Raspberry Pi 3 zu einem vollwertigen RFID-Card-Reader (Abbildung 2) ausbauen. Das eröffnet viele neue Einsatzmöglichkeiten, etwa für einen Türöffner oder ein kleines Buchungssystem – der Fantasie sind kaum Grenzen gesetzt.

Abbildung 2: Ein Raspberry Pi 3 mit dem 125KHz RFID Reader for Raspberry Pi von CognIoT.

Abbildung 2: Ein Raspberry Pi 3 mit dem 125KHz RFID Reader for Raspberry Pi von CognIoT.

Zwar gibt es schlüsselfertige Systeme, die Sie direkt erwerben und einsetzen könnten, doch die fallen erheblich kostspieliger aus. Mit dem RasPi halten sich die Ausgaben für das Projekt in überschaubaren Grenzen, Installation und Konfiguration lassen sich mit den beschriebenen Mitteln gut umsetzen. 

Der Autor

Nach dem Besuch eines technischen Gymnasiums absolvierte Timo Eggengoor ab 2012 ein duales Informatikstudium mit einer Ausbildung zum Anwendungsentwickler und einem Abschluss als Bachelor of Science. Derzeit befindet er sich im Informatik-Masterstudium und strebt den Abschluss als Master of Science an. Nebenbei arbeitet er in einem IT-Unternehmen.

Glossar

HITAG 2

Verbreitetes RFID-Transponder-Format für das 125-kHz-Spektrum des Halbleiterherstellers NXP für Geräte mit 32-Bit-ID und 256 Bit Speicher.

DIESEN ARTIKEL ALS PDF KAUFEN
EXPRESS-KAUF ALS PDFUmfang: 4 HeftseitenPreis €0,99
(inkl. 19% MwSt.)
RASPBERRY PI GEEK KAUFEN
EINZELNE AUSGABE Print-Ausgaben Digitale Ausgaben
ABONNEMENTS Print-Abos Digitales Abo
TABLET & SMARTPHONE APPS Raspberry Pi Geek bei Google Play Readly Logo
Nach oben