Skip to content

Commit fcd0a07

Browse files
committed
docs: add rfid component
1 parent 9065f8c commit fcd0a07

File tree

2 files changed

+110
-1
lines changed

2 files changed

+110
-1
lines changed

code

Submodule code updated 40 files

content/german/components/rfid.md

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,109 @@
1+
---
2+
title: RFID Reader/Writer
3+
tags: ["spi"]
4+
---
5+
6+
## Funktionsweise
7+
8+
Bei RFID, abgekürzt für Radio Frequency Identification, handelt es sich um eine Technologie, welche es ermöglicht automatisch und kontaktlos
9+
mit einer Karte entsprechende Informationen auszutauschen. Dies wird zum Beispiel bei weit bekannten NFC Tags verwendet, jedoch auch für
10+
Anwendungen wie das kontaktlose Zahlen per Kreditkarte.
11+
12+
Ein grosser Vorteil ist hierbei, dass die jeweiligen Karten/Tags, auch Transponder genannt, so klein wie ein Reiskorn sein können und keine
13+
eigene Stromversorgung benötigen. Im CrowPi ist die Komponente `MFRC522` verbaut, welche ein hochfrequentes elektronisches Wechselfeld bei
14+
13.56 MHz erzeugt, um damit einerseits die Karte mit Strom zu versorgen und andererseits mit dieser zu kommunizieren. Somit können
15+
beispielsweise die beiden beigelegten Tags des CrowPi ausgelesen und beschrieben werden mit beliebigen Daten.
16+
17+
Die Technologie dahinter ist sehr komplex und die entsprechenden Informationen dazu sind auf mehrere Standards aufgeteilt, hauptsächlich
18+
`ISO-14443` für den allgemein Aufbau und die Kommunikation sowie die entsprechenden Spezifikationen von NXP Semiconductors, dem Hersteller
19+
des Lese- und Schreibgeräts sowie von den meisten RFID Karten. Die Einhaltung dieser Standards ist hierbei sehr wichtig, da eine RFID Karte
20+
bei falschen Schreiboperationen auch permanent beschädigt werden kann.
21+
22+
Es besteht hier jedoch kein Grund zur Sorge, da sich diese Komponente um all die komplexen Aufgaben im Hintergrund kümmert und eine einfache
23+
sowie zuverlässige Schnittstelle bietet, um mit solchen RFID Karten zu interagieren. So bietet `RfidComponent` die Möglichkeit an, Karten zu
24+
erkennen und ein beliebiges Java-Objekt darauf zu speichern oder wieder zu lesen.
25+
26+
## Voraussetzungen
27+
28+
### DIP Switches
29+
30+
Für diese Komponente werden keine spezifischen DIP-Switches benötigt, sodass diese in der Standardkonfiguration belassen werden können:
31+
32+
{{< dip-switches >}}
33+
34+
## Verwendung
35+
36+
Nachfolgend wird die Verwendung der Klasse {{< javadoc class="com.pi4j.crowpi.components.RfidComponent" >}} beschrieben.
37+
38+
### Konstruktoren
39+
40+
| Konstruktor | Bemerkung |
41+
|:--------------------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------|
42+
| `RfidComponent(com.pi4j.context.Context pi4j)` | Initialisiert einen RFID Reader/Writer mit der Standard Reset-Pin und SPI Adresse sowie SPI Bandbreite für den CrowPi. |
43+
| `RfidComponent(com.pi4j.context.Context pi4j, int spiChannel, int spiBaud)` | Initialisiert einen RFID Reader/Writer mit einer benutzerdefinierten SPI Adresse und Bandbreite ohne Reset-Pin. |
44+
| `RfidComponent(com.pi4j.context.Context pi4j, Integer gpioResetPin, int spiChannel, int spiBaud)` | Initialisiert einen RFID Reader/Writer mit einem benutzerdefinierten Reset-Pin, SPI-Adresse sowie Bandbreite. |
45+
46+
### Methoden
47+
48+
| Methode | Bemerkung |
49+
|:------------------------------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
50+
| `boolean isNewCardPresent()` | Gibt einen boolschen Wert zurück, ob eine neue Karte erkannt wurde, welche noch nicht gelesen wurde. |
51+
| `boolean isAnyCardPresent()` | Gibt einen boolschen Wert zurück, ob irgendeine Karte erkannt wurde. Diese Methode erkennt im Gegensatz zu `isNewCardPresent()` auch bereits gelesene Karten. |
52+
| `RfidCard initializeCard()` | Erzeugt eine neue Instanz von `RfidCard`, welche anschliessend zur Interaktion mit der Karte verwendet werden kann. Erfordert dass `isNewCardPresent` oder `isAnyCardPresent` vorher aufgerufen wurde und `true` zurückgab. |
53+
| `void uninitializeCard()` | Muss zwingend nach dem Abschliessen aller Aktionen mit einer Karte aufgerufen werden, um die Kommunikation mit der Karte sauber zu beenden und neue Karten erkennen zu können. |
54+
| `void onCardDetected(EventHandler<RfidCard> handler)` | Definiert einen Event Handler, welcher jedes Mal aufgerufen wird wenn eine neue Karte erkennt wird. Als erster Parameter wird hierbei die erkannte Karte übergeben. |
55+
| `void waitForNewCard(EventHandler<RfidCard> handler)` | Gleiche Funktionsweise wie `onCardDetected`, blockiert jedoch den aktuellen Thread und wartet bis eine neue Karte erkannt wird, um dann einmalig einen Handler aufzurufen. Diese Methode deaktiviert den aktuellen Event Listener für `onCardDetected`. |
56+
| `void waitForAnyCard(EventHandler<RfidCard> handler)` | Gleiche Funktionsweise wie `waitForNewCard`, akzeptiert jedoch auch eine Karte welche bereits gelesen oder beschrieben wurde und führt auf dieser die Aktion durch. Diese Methode deaktiviert den aktuellen Event Listener für `onCardDetected`. |
57+
| `void reset()` | Setzt die Komponente auf den Ausgangszustand zurück, was bei allfälligen Problemen Abhilfe schaffen kann. Normalerweise nicht erforderlich für den normalen Betrieb. |
58+
59+
### Karten-Methoden
60+
61+
Die Klasse {{< javadoc class="com.pi4j.crowpi.components.internal.rfid.RfidCard" >}} welche als Rückgabewert bei `initializeCard()` oder als
62+
Parameter bei den Event Handlern `onCardDetected()`, `waitForNewCard()` sowie `waitForAnyCard` verwendet wird, bietet verschiedene Methoden
63+
um mit der erkannten Karte zu interagieren. Wichtig zu beachten ist, dass nach Ausführung eines Event Handlers automatisch
64+
`uninitializeCard()` aufgerufen wird, sodass sich die erkannte Karte nicht weiter nutzen lässt.
65+
66+
| Methode | Bemerkung |
67+
|:--------------------------------|:--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
68+
| `String getSerial()` | Gibt die Seriennummer der aktuellen Karte als String zurück. |
69+
| `int getCapacity()` | Gibt die maximale Kapazität der aktuellen Karte in Bytes zurück. |
70+
| `void writeObject(Object data)` | Schreibt das übergebene Objekt in die Karte. Wird dieser Befehl mehrfach aufgerufen, so wird dieses jeweils überschrieben. Das Objekt muss das Interface `Serializable` implementieren. Wirft eine `RfidException` falls die Operation nicht erfolgreich war. |
71+
| `Object readObject()` | Liest das auf der Karte gespeicherte Objekt aus und gibt dieses als generischen `Object`-Typ zurück. Wirft eine `RfidException` falls die Operation nicht erfolgreich war. |
72+
| `T readObject(Class<T> type)` | Gleiche Funktionsweise wie `readObject()`, aber gibt das Objekt gleich mit dem gewünschten Typ zurück. Wurde zum Beispiel mit `writeObject` vorher ein `Animal` gespeichert, so gibt `readObject(Animal.class)` direkt die `Animal`-Instanz zurück. |
73+
74+
## Beispielapplikation
75+
76+
Die nachfolgende Beispielapplikation definiert eine Klasse namens `Person`, um von einer beliebigen Person den Vornamen und Nachnamen, die
77+
Adresse sowie das Geburtsdatum zusammen mit einer zufällig generierten ID zu speichern. Nun werden zuerst zwei Personen generiert und in den
78+
Variablen `personA` sowie `personB` gespeichert, welche beide über verschiedene Daten verfügen.
79+
80+
Anschliessend wird mit der `waitForNewCard` Methode die Anwendung so lange blockiert, bis eine neue Karte vom RFID Gerät erkannt wurde.
81+
Sobald dies der Fall ist, wird die übergebene Funktion ausgeführt, welche die Instanz `personA` von der `Person`-Klasse auf der Karte mit
82+
`writeObject` speichert. Es kann jedes beliebige Java-Objekt gespeichert werden, solange dieses das `Serializable` mit `implements
83+
Serializable` implementiert. Wichtig ist hierbei zu beachten, dass diese Methode eine `RfidException` werfen kann, welche abgefangen werden
84+
muss. Diese tritt auf, wenn die Karte nicht ordnungsgemäss beschrieben werden konnte.
85+
86+
Nachdem die erste Karte beschrieben wurde, wird der gleiche Prozess für die zweite Karte wiederholt. Da mit `waitForNewCard` grundsätzlich
87+
nur neue Karten erkannt werden und eine Karte nach erfolgter Interaktion in einen Schlafzustand geht, kann hier garantiert werden dass nicht
88+
sofort die zweite Person auf die gleiche Karte geschrieben wird, sondern sich eine neue Karte annähern oder die bestehende Karte kurzfristig
89+
entfernt werden muss.
90+
91+
Sobald beide Karten beschrieben wurden, wird ein Event Handler mit `onCardDetected` registriert, welcher asynchron jedes Mal aufgerufen wird
92+
wenn eine neue Karte erkannt wurde. Da der RFID-Standard ein Verfahren gegen Kollisionen besitzt, können sich sogar mehrere Karten
93+
gleichzeitig auf dem Lese- und Schreibgerät befinden. Bei jeder ermittelten Karte wird mit `readObject(Person.class)` versucht, eine vorher
94+
gespeicherte Instanz der `Person`-Klasse auszulesen und in die Variable `person` zu speichern. Wenn dies gelingt, so wird die Person auf der
95+
Konsole ausgegeben. Auch hier muss eine allfällige `RfidException` aufgefangen werden, welche zum Beispiel auftritt, wenn die Daten nicht
96+
gelesen werden können oder korrupt sind.
97+
98+
Nach der Registrierung des Event Handlers schläft die Applikation für 30 Sekunden, um genug Zeit zu geben, die zwei verwendeten Karten
99+
auszuprobieren. Nach Ablauf der Zeit wird der Event Handler wieder sauber entfernt und die Applikation beendet sich.
100+
101+
{{< code file="src/main/java/com/pi4j/crowpi/applications/RfidApp.java" language="java" >}}
102+
103+
## Weitere Möglichkeiten
104+
105+
- Das Beispiel zu einer Art Zutrittskontrolle ausbauen und beispielsweise nur Personen mit einem bestimmten Attribut zulassen.
106+
107+
- Statt dem Speichern von Personen könnten auch andere Daten auf einer Karte abgelegt werden, zum Beispiel eine (nicht sehr sichere)
108+
Implementation einer Bank wo auf jeder Karte der Inhaber sowie der aktuelle Kontostand gespeichert wird. Hierfür wäre die Methode
109+
`waitForAnyCard` praktisch, um eine bereits aufgelegte Karte erneut zu beschreiben.

0 commit comments

Comments
 (0)