Arduino spricht RFID

Der Pragmatische Architekt  –  3 Kommentare
Anzeige

RFIDs lassen sich in vielen Anwendungen nutzen, die Gegenstände oder Personen erfassen, beispielsweise für die Zugriffssteuerung bei einer Tür. Selbstredend gibt es inzwischen preisgünstige Hardware, die eigene Projekte mit RFID-Tags und RFID-Lesegeräten erlaubt.

Der Schöpfer des Begriffs IoT (Internet of Things), Kevin Ashton, war am Auto-ID Center des Massachusetts Institute of Technology (MIT) tätig. Dort hat er einen internationalen Standard für RFID initiiert. Zwischen dem Internet der Dinge und der RFID-Technologie gibt es somit einen historischen Bezug. In dieser Ausgabe soll also zusammenwachsen, was zusammengehört.

Anzeige

Doch was genau ist RFID, und wofür ist es gut? Lassen Sie mich zu diesem Thema in der virtuellen Enzyklopädie blättern.

RFID (engl. radio-frequency identification) bezeichnet laut Wikipedia:

" [...] eine Technologie für Sender-Empfänger-Systeme zum automatischen und berührungslosen Identifizieren und Lokalisieren von Objekten und Lebewesen mit Radiowellen.
Ein RFID-System besteht aus einem Transponder (umgangssprachlich auch Funketikett genannt), der sich am oder im Gegenstand bzw. Lebewesen befindet und einen kennzeichnenden Code enthält, sowie einem Lesegerät zum Auslesen dieser Kennung.
RFID-Transponder können so klein wie ein Reiskorn sein und implantiert werden, etwa bei Haustieren oder Menschen."

Verfolgung von Tierwanderungen mit RFIDs an der Universität von Oklahoma (Bild: www.animalmigration.org)

"Darüber hinaus besteht die Möglichkeit, RFID-Transponder über ein spezielles Druckverfahren stabiler Schaltungen aus Polymeren herzustellen. Die Vorteile dieser Technik ergeben sich aus der Kombination der geringen Größe, der unauffälligen Auslesemöglichkeit (z. B. bei dem am 1. November 2010 neu eingeführten Personalausweis in Deutschland) und dem geringen Preis der Transponder (teilweise im Cent-Bereich). Diese neue Technik kann potentiell den heute weitverbreiteten Barcode ersetzen.
Die Kopplung geschieht durch vom Lesegerät erzeugte magnetische Wechselfelder in geringer Reichweite oder durch hochfrequente Radiowellen. Damit werden nicht nur Daten übertragen, sondern auch der Transponder mit Energie versorgt. Zur Erreichung größerer Reichweiten werden aktive Transponder mit eigener Stromversorgung eingesetzt, die jedoch mit höheren Kosten verbunden sind. [...]"

Im täglichen Leben begegnet uns RFID inzwischen überall. Beispielsweise beim Scannen von Waren an der Kasse oder beim Bezahlen über NFC-Terminals. Heutzutage sind RFID-Hardware und -Karten so günstig, dass sich ihr Einsatz auch in der Welt der Maker, sprich für eigene Projekte rentiert.

Ein preislich attraktives Set zum eigenen Experimentieren firmiert unter dem Suchbegriff RFID-RC522. Dieses Set inklusive Hardwaremodul, einer S50 RFID/NFC-Karte, einem blauen Transponder als Schlüsselanhänger, und Steckleisten (gewinkelt, gerade) erhalten Sie für gerade einmal 5 Euro auf ebay.

Ein RFID-RC522 Set besteht aus einem Reader, zwei RFID-Tags und Steckleisten zum Anlöten

Das über SPI-Bus anzuschließende und etwa 6 cm x 4 cm große Modul benötigt 3,3 V als Versorgungsspannung, verbraucht Betriebsströme zwischen 10 und 30 mA, und hat einen Ruhestrom von 80 µA. Die Übertragungsfrequenz beträgt 13,56 MHz.

Der RFID-RC522 und seine Pin-Belegung (Bild: https://home.ctw.utwente.nl)

Wer mit dem RFID-Leser auch andere Kartentypen/RFIDs einsetzen möchte, hat die Wahl zwischen den Typen S50, S70, UltraLight, Pro, und Desfire.

Wie immer soll die Praxis im Vordergrund stehen. Es geht um die Simulation eines Türöffnungssystems. Die Rolle des Verschlussmechanismus übernimmt dabei ein Servo-Motor. Eine rote und eine grüne LED visualisieren den jeweiligen Status. Zu Beginn ist die Tür verschlossen, und die rote LED leuchtet. Der Sketch wartet darauf, dass Personen mittels RFID-Tag Eintritt erhalten möchten. Erkennt die Schaltung ein RFID-Tag in ihrer Nähe, erfolgt das Auslesen deren Wertes.

  • Enthält die gelesene RFID-Karte eine zulässige Kennung, hört die rote LED auf zu leuchten, worauf gleichzeitig die grüne LED zu leuchten beginnt. Der Servo-Motor bewegt sich um 180° in eine Richtung. Danach wartet die Steuerung für 3 Sekunden und bewegt den Servo wieder in die 180° entgegengesetzte Richtung zurück. Danach erlischt die grüne LED, und die rote LED beginnt zu leuchten. Die Tür ist wieder verschlossen.
  • Enthält die gelesene RFID eine nicht akzeptierte Kennung, blinkt die rote LED zur Signalisierung fünfmal, bevor sie wieder in ein Dauerleuchten wechselt.
Die Schaltung im Test
Diagnoseausgabe im laufenden Betrieb

Um das hier beschriebene Projekt durchzuführen, benötigen Sie folgendes Material:

  • Arduino MEGA (oder Arduino Uno oder Arduino Leonardo)
  • LED rot
  • LED grün
  • kleiner Servo-Motor
  • RFID-RC522 Set (siehe oben)
  • 2 Widerstände (mít 220 Ω, 330 Ω, oder 470 Ω)
  • 11 Stück Schaltdraht (je 20-30cm)
  • kleines Breadboard

Bei einem Arduino Mega sind folgende Verbindungen notwendig.

Arduino Mega           RFID-RC522 (RFID-Leser) 
GND GND
5 RST
3,3 V 3,3 V
53 SDA
52 SCK
51 MOSI
50 MISO

Beim Uno müssen Sie die Schaltung etwas modifizieren und SDA an Digital-Pin 10, SCK an 13, MOSI an 11 und MISO an 12 legen. Des Weiteren verbinden Sie RST des RFID-Readers mit Digital-Pin 9 des Uno, wodurch sich ergibt:

Arduino Uno           RFID-RC522 (RFID-Leser) 
GND GND
9 RST
3,3 V 3,3 V
10 SDA
13 SCK
11 MOSI
12 MISO

In der Schaltung kommen noch folgende Verbindungen hinzu. Dargestellt sind die Verbindungen für den Arduino Mega. Beim Uno verwenden Sie einfach andere digitale Ausgänge.

  • Die blaue GND-Schiene am Steckboard verbinden Sie mit GND des Mega.
  • Die rote Spannungsschiene am Steckboard verbinden Sie mit dem 5-Volt-Spannungsausgang des Mega beziehungsweise Uno.
  • Der Servo-Motor ist direkt verbunden mit dem digitalen Datenausgang 11 des Mega (beim Uno z.B. Pin 6), zudem mit GND und 5V am Breadboard.
  • Die rote LED wird direkt mit Pin 13 des Mega angesteuert (Uno: Pin 8), die grüne LED mit Pin 12 des Mega (Uno: Pin 7). Beide LEDs sind über einen Widerstand mit der GND-Schiene des Breadboards verbunden.

Insgesamt ergibt sich daher folgende Schaltung:

Schaltung mit Mega, RFID-RC522, Servo-Motor, LEDs

Normalerweise lassen sich RFID-Reader des Typs MFRC522 problemlos mit der 3,3-V-Spannung des Arduino-Boards betreiben, während gleichzeitig die Verbindungen für den SPI-Bus des Moduls direkt am Arduino-Board anliegen. Wer auf Nummer sicher gehen will, verwendet einen Logic-Level-Konverter, wie wir ihn beispielsweise in den Schaltungen zu Bluetooth kennen gelernt haben. Das Kürzel MF in MFRC522 steht übrigens für die Produktfamilie MIFARE von NXP Semiconductors, dem Hersteller des Chips. Näheres dazu finden Sie auch auf dieser Wikipedia-Seite. Ein englischsprachiges Datenblatt gibt es über diesen Link.

Es lohnt sich nicht, das Board mit dem MFRC522-Chip selbst systemnah zu programmieren, da Miguel Balboa zu diesem Zweck eine Bibliothek anbietet, die Sie auf dieser GitHub-Seite finden. Das Herunterladen der Bibliothek erfolgt über folgenden Link. Anschließend lässt sich die expandierte Bibliothek (Verzeichnis rfid-master) in die Arduino IDE importieren.

Navigieren Sie dazu in der IDE zu Sketch | Include Library | Add .ZIP Library und geben Sie den Pfad zur Bibliothek ein.

Zunächst soll ein erster Sketch erlauben, die IDs der RFID-Tags auszulesen. Nähert sich der Anwender mit der RFID-Karte dem Lesemodul, gibt das Programm in der loop()-Schleife deren ID aus.

  • In setup() erfolgt die Initialisierung des SPI-Bus, des seriellen Monitors und des RFID-Lesers.
  • In loop() wartet der Sketch auf die Erkennung einer RFID-Karte und gibt deren ID am seriellen Monitor aus.

Am besten, Sie starten den Sketch, öffnen den seriellen Monitor, halten ihre RFIDs in die Nähe des Lesers und merken sich die IDs ihrer Karten. Eine ID brauchen Sie für das eigentliche Projekt und müssen seinen Wert dort als Variable sesam hinterlegen (siehe Programm weiter unten).

Zudem müssen Sie einige Pins im Sketch ändern, sollten Sie statt des Arduino Mega ein anderes Board wie zum Beispiel den Uno verwenden. Dazu gab es schon bei den obigen Erläuterungen Hinweise.

/////////////////////////////////////////////////
//
// Lesen und Ausgeben von RFID-Tags
// auf Basis von MFRC422-Reader
// (c) Michael Stal, 2016
//
//////////////////////////////////////////////////


#include <SPI.h> // Import SPI-Bibiothek
#include <MFRC522.h> // Import RFID-Bibiothek
#include <Servo.h> // Import Servo-Bibliothek

///////// Variablen MFRC522 //////////////////////
const int SDAPIN = 53; // Uno => Pin 10
const int RSTPIN = 9; // Uno => Pin 9
MFRC522 rfidReader(SDAPIN, RSTPIN); // RFID-Empfänger

//////////////////////////////////////////////////
//
// setup()
// Initialisieren von SPI,
// seriellem Monitor,
// RFID-Leser
//
//////////////////////////////////////////////////

void setup()
{
Serial.begin(9600); // Serielle Verbindung
SPI.begin(); // SPI-Verbindung aufbauen
rfidReader.PCD_Init(); // RFID-Reader initial.
}


//////////////////////////////////////////////////
//
// loop()
// Warten auf RFID-Erkennung
//
//////////////////////////////////////////////////

void loop()
{
// Karte erkannt und gelesen
if (rfidReader.PICC_IsNewCardPresent() && rfidReader.PICC_ReadCardSerial()) {

Serial.print("Erkanntes RFID-TAG ist => ");

// Bytes der ID lesen und ausgeben
Serial.print("/");
for (byte i = 0; i < rfidReader.uid.size; i++) {
Serial.print(rfidReader.uid.uidByte, HEX);
Serial.print("/");
}
Serial.println();
}
}

Als Ausgabe sehen Sie am seriellen Monitor die Werte der erkannten RFID-Karten:

Ausgabe des RFID-Leasers am seriellen Monitor

Die Präfixe PCD und PICC in den Bibliotheksroutinen stehen übrigens für Proximity Coupling Device und für Proximity Integrated Circuit Card. Ersteres bezeichnet das Lesegerät, letzteres die RFID-Karte.

Für das eigentliche Projekt können wir den oberen Sketch als Basis wiederverwenden.

Die Variable [i]sesam (im unteren Listing rot hinterlegt) enthält dabei die ID eines RFID-Transponders des Autors. Diese Variable sollten Sie natürlich mit der ID einer eigenen RFID-Karte ersetzen, wie Sie sie im letzten Versuchsaufbau aufgeschrieben haben.

Der nachfolgende Sketch implementiert genau das weiter oben beschriebene Szenario.

In setup()

  • erfolgt die Initialisierung des SPI-Bus, des seriellen Monitors und des RFID-Lesers.

In loop()

  • leuchtet zunächst die rote LED
  • wartet der Sketch auf die Erkennung einer RFID Karte =>
    • Hat die Karte den falschen ID, leuchtet 5 x die rote LED auf
    • Hat die Karte den richtigen ID, erlischt die rote LED, und die grüne beginnt zu leuchten. Der Servomotor dreht sich 180° in eine Richtung, bleibt 3 Sekunden stehen, und dreht sich dann wieder 180° in die Gegenrichtung.

Die weiteren Methoden/Routinen sind selbsterklärend.

Die Diagnoseausgaben können Sie am seriellen Monitor unter 9600 Baud beobachten.

//////////////////////////////////////////////////
//
// Demo für RFID-Tags
// auf Basis von MFRC422-Reader
// (c) Michael Stal, 2016
//
//////////////////////////////////////////////////


#include <SPI.h> // Import SPI-Bibiothek
#include <MFRC522.h> // Import RFID-Bibiothek
#include <Servo.h> // Import Servo Bibliothek

///////// Variablen MFRC522 //////////////////////
const int SDAPIN = 53; // Uno => Pin 10
const int RSTPIN = 9; // Uno => Pin 9
MFRC522 rfidReader(SDAPIN, RSTPIN); // RFID-Empfänger

///////// Aktoren: LEDs, Servo ///////////////////
const int REDLED = 13; // Uno -> Pin 8
const int GREENLED = 12; // Uno -> Pin 7
const int SERVOPIN = 11; // Uno -> Pin 6
Servo door; // Türverschluss (Servo)

//////// ID des richtigen RFID-Tags //////////////
byte sesam[] = {0x26, 0xA7, 0xFB, 0x48};



//////////////////////////////////////////////////
//
// setup()
// Initialisieren von SPI,
// seriellem Monitor,
// RFID-Leser
//
//////////////////////////////////////////////////

void setup()
{

door.attach(SERVOPIN);
pinMode(REDLED, OUTPUT);
pinMode(GREENLED, OUTPUT);
pinMode(SERVOPIN, OUTPUT);

Serial.begin(9600); // Serielle Verbindung

SPI.begin(); // SPI-Verbindung aufbauen

rfidReader.PCD_Init(); // Initial. RFID-Leser
Serial.println("Tuerkontrolle aktiviert");
}



//////////////////////////////////////////////////
//
// acceptedRFID()
// Stimmt gelesene RFID
// mit der voreingestellten ID überein?
//
//////////////////////////////////////////////////

bool acceptedRFID(byte uid[4]) {
return
(rfidReader.uid.uidByte[0] == sesam[0]) &&
(rfidReader.uid.uidByte[1] == sesam[1]) &&
(rfidReader.uid.uidByte[2] == sesam[2]) &&
(rfidReader.uid.uidByte[3] == sesam[3]);
}

//////////////////////////////////////////////////
//
// openDoor()
// Servo um 180° in Richtung drehen
//
//////////////////////////////////////////////////

void openDoor() {
for (int pos = 0; pos <= 180; pos++) {
door.write(pos);
delay(20);
}
}

//////////////////////////////////////////////////
//
// closeDoor()
// Servo um 180° in Gegenrichtung drehen
//
//////////////////////////////////////////////////

void closeDoor() {
for (int pos = 180; pos >= 0; pos--) {
door.write(pos);
delay(20);
}
}

//////////////////////////////////////////////////
//
// signalDoorLocked()
// Zugang versperrt =>
// rote LED leuchtet,
// gruene nicht
//
//////////////////////////////////////////////////

void signalDoorLocked() {
digitalWrite(REDLED, HIGH);
digitalWrite(GREENLED, LOW);
}

//////////////////////////////////////////////////
//
// signalAccessGranted()
// Zugang gewährt =>
// gruene LED leuchtet,
// rote nicht
//
//////////////////////////////////////////////////

void signalAccessGranted() {
digitalWrite(REDLED, LOW);
digitalWrite(GREENLED, HIGH);
}

//////////////////////////////////////////////////
//
// signalAccessRefused()
// Zugang verweigert =>
// rote LED blinkt 5x
//
//////////////////////////////////////////////////

void signalAccessRefused() {
for (int i = 0; i < 5; i++) {
digitalWrite(REDLED, HIGH);
delay(250);
digitalWrite(REDLED, LOW);
delay(250);
}
}


//////////////////////////////////////////////////
//
// loop()
// Warten auf RFID-Erkennung
// Reaktion abhaengig vom ID-Vergleich
//
//////////////////////////////////////////////////

void loop()
{
// Rotes Signal
signalDoorLocked();

// Karte erkannt und gelesen
if (rfidReader.PICC_IsNewCardPresent() && rfidReader.PICC_ReadCardSerial()) {

Serial.print("Erkanntes RFID-TAG ist => ");

// Bytes der ID lesen und ausgeben
Serial.print("/");
for (byte i = 0; i < rfidReader.uid.size; i++) {
Serial.print(rfidReader.uid.uidByte[i], HEX);
Serial.print("/");
}

Serial.println();

// Check ob Karte mit Variable sesam übereinstimmt
if (acceptedRFID(rfidReader.uid.uidByte)) { // ja =>
// Erlaubten Zugriff signalisieren
signalAccessGranted();
Serial.println("Zugriff erlaubt => Tuer oeffnen");
// Oeffnen der Tuere
openDoor();
Serial.println("Tuer 3 Sekunden offen lassen");
// 3 Sekunden Pause
delay(3000);
Serial.println("Tuer schliessen");
// Tuere wieder schliessen
closeDoor();
}
else // nein =>
{
Serial.println("Zugriff verweigert");
// Rote LED blinkt als Warnung
signalAccessRefused();
}
}
}

Natürlich entlasse ich Sie auch diesmal nicht ohne Anregungen für Erweiterungen. Sie haben mehrere Möglichkeiten wie zum Beispiel:

  • Mittels eines Abstandssensors oder einer Laserschranke könnten Sie feststellen, ob die Tür noch geöffnet ist.
  • Sie können eine Software (z.B. für PC oder Raspberry Pi) schreiben, die erlaubt, RFID-Karten dauerhaft oder vorübergehend freizuschalten und sie auch wieder zu sperren. Zudem könnten Sie Zeiten definieren, wann der jeweilige RFID-Tag Zugríff erlaubt und wann nicht. Diese Information liegt verschlüsselt auf dem Server. Die Schaltung auf dem Arduino kommuniziert über WiFi mit der zentralen Software, um zu erfahren, ob gelesene RFID-Karten zum Eintritt berechtigen oder nicht. Die zentrale Software kann alle Vorgänge entsprechend protokollieren. Alternativ nutzen sie einen SD-Reader am Arduino, um Ereignisse lokal am Mikrocontroller zu protokollieren. Selbstredend sollten Sie in diesen Szenarien alle übertragenen Daten verschlüsseln.
  • Um die Reichweite des RFID-Lesers um einige Zentimeter zu erhöhen, können Sie den Code der Bibliotheksdatei MRFC522.cpp ergänzen. In der Methode PCD_Init() vor PCD_AntennaOn() fügen Sie folgende Zeile ein: PCD_WriteRegister(RFCfgReg, (0x07<<4));. Damit erhöhen Sie die Empfindlichkeit des MFRC522-Chips auf seinen Maximalwert. Gerade für die Türschaltung könnte sich das als notwendig erweisen.
  • Und last, but not least könnten Sie statt des Servo-Motors eine echte elektronische Türschließanlage einsetzen.

Mit RFID-Lesern und -Tags lassen sich einige interessante Projekte kreieren. Von Sicherheitssystemen bis hin zur Erfassung von Lebewesen oder beweglichen Gütern sind viele Anwendungen denkbar. Diese Folge konnte gerade einmal die Spitze des Eisbergs illustrieren. Für professionelle und sicherheitskritische Anwendungen dürfte allerdings das preisgünstige RC522-Board an seine Grenzen stoßen. Hier sind teurere und leistungsfähigere Optionen notwendig. Für das Sammeln von Erfahrungen und viele Make-Projekte reichen die Möglichkeit des Chips aber allemal. Viel Spaß beim Experimentieren!

Anzeige