UID-Nummer, SAK-Nummer, Tag-Typ
Jeder RFID-Tag besitzt eine einzigartige UID-Nummer (UID = Unique Identification), die in Abhängigkeit des Tag-Typs 4 oder 7 Byte lang sein kann. Allerdings ist seit der Einführung der 7 Byte UID-Nummer die 4 Byte UID-Nummer nicht mehr einzigartig und wird daher auch als NUID-Nummer (NUID = Not Unique Identification) bezeichnet. Ich verwende aber der Einfachheit halber die Bezeichnung UID auch bei 4 Byte UID-Nummern.
Die SAK-Nummer ist ein Code, der aus dem RFID-Tag ausgelesen werden kann und den Tag-Type als Zahl angibt. Mit der von mir verwendeten Library kann mit Hilfe der SAK-Nummer der Tag-Typ auch als Klartext ausgegeben werden.
Programmbeispiel 1: Anzeigen der SAK-Nummer, des Tag-Typs und der UID-Nummer
Funktionsbeschreibung:
Mit nachfolgendem Programm können alle 5 Sekunden UID-Nummer, SAK-Nummer und Tag-Typ von erkannten Tags angezeigt werden. Die von mir zum Testen verwendeten Tags sind vom Typ MIFARE Classic S50 mit 1 kByte Speicher und 4 Byte langer UID-Nummer.
Im Beispiel 1 finden folgende Funktionen und Variablen der MFRC522-Library Verwendung:
Funktionen:
MFRC522 MFR(byte, byte);
MFR.PCD_init();
MFR.PICC_IsNewCardPresent();
MFR.PICC_ReadCardSerial();
MFR.PICC_GetType(byte):
MFR.PICC_GetTypeName(byte);
Variable:
MFR.uid.size;
MFR.uid.uidByte[i];
MFR.uid.sak;
Beschreibung der Funktionen und Variablen:
MFRC522 MFR(byte ssPin, byte rstPin)
Funktion: Erstellen einer neuen Instanz mit Angabe der Arduino Pin-Nummer für Slave Select und Reset
Parameter: keine
Rückgabe: keine
Beispiel:
#define rstPin 9 //Pin 9 ist Reset Pin
#define ssPin 10 //Pin 10 ist Slave Select Pin
MFRC522 MFR(ssPin, rstPin);
void PCD_init(void)
Funktion: Initialisieren des RFID-Readers
Parameter: keine
Rückgabe: keine
Beispiel:
MFR.PCD_init();
bool PICC_IsNewCardPresent(void)
Funktion: Abfrage, ob ein neuer RFID-Tag erkannt wurde
Parameter: keine
Rückgabe:
TRUE, wenn RFID-Tag erkannt wurde oder FALSE, wenn kein Tag erkannt wurde oder eine Kollision vorliegt (zwei oder mehrere Tags im Erkennungsbereich)
Beispiel:
if (MFR.PICC_IsNewCardPresent()) .....;
bool PICC_ReadCardSerial(void)
Funktion: Abfrage, ob Daten des RFID-Tag gelesen wurden
Parameter: keine
Rückgabe: TRUE, wenn RFID-Tag ausgelesen wurde, sonst FALSE
Beispiel:if (MFR.PICC_ReadCardSerial()) ....;
Bemerkung: Mit dieser Funktion werden die Daten "UID-Länge" (Anzahl in Bytes), "UID-Nummer" und "SAK-Nummer" (Select Acknowledge) vom RFID-Tag ausgelesen und in einer in der Library definierten Struktur (struct) gespeichert. Die Struktur in der Library hat folgenden Aufbau:
typedef struct {
byte size; //Anzahl der Bytes der UID
byte uidByte[10]; //Array, welches die UID-Bytes enthaelt
byte sak; //sak beinhaltet die Information über den Kartentyp
} Uid;
Uid uid; //uid ist der Variablenname der struct Uid
Somit kann auf die Variablen im Anwenderprogramm zugegriffen werden:
Ausgabe der UID-Länge:
Serial.println(MFR.uid.size);
Ausgabe der UID-Nummer:
for (byte i = 0, i < MFR.uid.size; i++)
{
Serial.print(MFR.uid.uidByte[i]);
Serial.print(" ");
}
Serial.println();
Ausgabe der SAK-Nummer:
Serial.println(MFR.uid.sak);
SAK ist eine Zahl, die den Tag-Typ zurückgibt, z.B.:
- 0x08 für MIFARE 1K
- 0x18 für MIFARE 4K
- 0x11 für MIFARE PLUS
byte PICC_GetType(byte sak)
Funktion: Rückgabe des Tag-Typs
Parameter: sak: SAK-Nummer des Tag-Typs
Rückgabe: Libraryspezifische Typ-Nummer
Beispiel: siehe nächste Funktion (PICC_GetTypeName())
const string PICC_GetTypeName(byte typ)
Funktion: Rückgabe des Tag-Typs als Klartext
Parameter: typ: Libraryspezifische Typ-Nummer (siehe obige Funktion PICC_GetType())
Rückgabe: Klartext des Typs
Beispiel:
MFRC522::PICC_Type piccType; //PICC_Type ist in der Library vom Aufzaehlungstyp enum
//Mit der SAK-Zahl wird eine libraryspezifische Typnummer piccType ermittelt
piccType = MFR.PICC_GetType(MFR.uid.sak);
//Mit die libraryspezifischen Typnummer erhält man den Typ-Namen
Serial.println(MFR.PICC_GetTypeName(piccType));
Ausgabe z.B. für MIFARE 1K: MIFARE 1KB
Hier nun das vollständige Programm:
//RFID Programm 1
//Anzeigen der SAK-Nummer, des Tag-Typs und der UID-Nummer
//Code fuer Arduino
//Author Retian
//Version 1.2
#include <MFRC522.h>
#include <SPI.h>
#define rstPin 9 //Reset Pin
#define ssPin 10 //Slave Select Pin
MFRC522 MFR(ssPin, rstPin); //Erzeugt eine neue Instanz von MFRC522
MFRC522::PICC_Type piccType; //PICC_Type ist in der Library vom Aufzaehlungstyp enum
void setup() {
Serial.begin(115200);
SPI.begin();
MFR.PCD_Init(); //Initialisiere Reader
}
void loop() {
Serial.print("Warte auf RFID-Tag .... ");
//Warte, bis RFID-Tag erkannt
while (!MFR.PICC_IsNewCardPresent() || !MFR.PICC_ReadCardSerial());
Serial.println("Tag erkannt!");
//Ausgabe von SAK, Typ und UID
Serial.print("SAK: ");
if (MFR.uid.sak < 16) Serial.print("0"); //Fuehrende Null anzeigen
Serial.println(MFR.uid.sak, HEX);
Serial.print("Typ: ");
piccType = MFR.PICC_GetType(MFR.uid.sak);
Serial.println(MFR.PICC_GetTypeName(piccType));
Serial.print("UID: ");
for (byte i = 0; i < MFR.uid.size; i++)
{
if (MFR.uid.uidByte[i] < 16) Serial.print("0"); //Fuehrende Null anzeigen
Serial.print(MFR.uid.uidByte[i], HEX);
Serial.print(" ");
}
Serial.println("\n");
delay(5000);
}
Ausgabe am Seriellen Monitor:
Abbildung 2-1: Ausgabe am Seriellen Monitor des RFID Programm 1
Die so angezeigten UID-Nummern der RFID-Tags sollte man sich notieren oder als Screenshot speichern, da diese in späteren Beispielen benötigt werden.