Wat is RFID?

RFID staat voor Radio-frequentie identificatie, ofwel identificatie door middel van radiogolven.
Voorbeelden zijn een kaart die je in bij een deur van een hotelkamer houdt om deze te openen en chips in de oren van vee. RFID kaarten bevatten een nummer dat wereldwijd uniek is. De fabrikant garandeert dat. Er bestaan echter ook type kaarten, waarbij je dat nummer zelf kunt veranderen. En dat zijn nu juist de kaarten waarmee je leuke projecten kunt maken.
Je hebt nodig: een RFID lezer en bijbehorend kaartje en/of druppel. Er worden verschillende frequenties en systemen gebruikt, die niet uitwisselbaar zijn. De meest gebruikte frequenties zijn 13,56 MHz en 125 kHz. Bij de laatste is een grotere spoel nodig, welke meestal los bij de RFID lezer zit. Aan de druppels en kaarten kun je niet of nauwelijks zien welke van de twee frequenties gebruikt worden. Goed opletten bij de aanschaf dus. Beide systemen werken erg goed. Ik beschrijf eerst de 13,56 versie in twee totaal verschillende uitvoeringen, daarna de 125 kHz versie.

13,65 MHz (RF-ID-RC522) lezer/schrijver

Je kunt vrij goedkoop aan deze lezer/schrijver komen. De bijbehorende kaarten en druppels kosten minder dan 1 euro. Om deze kaartlezer te kunnen gebruiken moet je een bibliotheek downloaden, bijvoorbeeld MFRC522.h. Deze gaat ervan uit dat je de kaartlezer als volgt aansluit op de Arduino Uno: uiteraard GND naar GND en 3,3 V naar 3,3 V; verder RST naar 9; SDA naar 10; MOSI naar 11; MISO naar 12 en SCK naar 13. Op andere Arduino's is het vaak anders. Het werk allemaal vrij goed.

RFID opstelling
Links: de Arduino met het leesprogramma; rechts de RFID lezer, de druppel (blauw) en de kaart (wit).

Ik heb tot nu toe alleen het lezen getest. Hieronder zie je een paar resultaten.
Mijn witte kaartMijn druppelMijnID kaart, met UID weggelakt
Van links naar rechts: de kaart, de druppel en mijn ID kaart (UID weggelakt).
Erg leuk voor groepsopdrachten op school: wie krijgt toegang tot welke ruimte?

PN532 NFC RFID module

Deze module kan drie interfaces gebruiken: High Speed UART (TX en RX), I²C en SPI. Deze zijn via een microschakelaar te kiezen. Het I²C adres is 0x24. Bij aankoop is UART geselecteerd en kun je zo beginnen. Je hebt de bibliotheek PN532_HSU nodig die je op GitHub kunt verkrijgen. De bibliotheken voor de drie interfaces moet anders worden geïstalleerd dan normaal. Lees goed hoe dat moet op Github. In totaal moet je 5 bibliotheken krijgen. Met deze bibliotheken kun je diverse soorten kaarten lezen. Je kunt ook een Mifare kaart voorzien van NDEF data, zodat je deze met je smartphone kunt uitlezen. Helaas kun je de bibliotheken niet zonder wijzigingen gebruiken omdat de selector (#ifdef 0 of #ifdef 1 aangepast moet worden). Na aanpassen volgens de online manual bevatten de programma's nog veel fouten. Het is storend als voorbeeld programma's niet meteen werken.

Let op: alles is 5 volt tolerant, behalve SPI. Als je SPI wilt gebruiken met een Arduino zet er dan een level converter tussen of gebruik weerstanden. Het is mij niet gelukt SPI aan de praat te krijgen met de WeMos D1 mini, ook niet met een andere bibliotheek. Met I²C lukt het met de WeMos, maar niet erg stabiel. Met HSU lukt het wel goed. Omdat je dan eigenlijk twee seriële poorten nodig hebt kun je het best SoftwareSerial gebruiken. Hiervoor heb je dan weer een andere PN535 bibliotheek nodig: PN532_SWHSU.h. Ik heb het voorbeeldprogramma hierbij enigszins verbeterd (zie hieronder). Ik heb het getest met een WeMos D1 mini en een Arduino Uno. Bij de Arduino had ik in de sketch D1 en D2 vervangen door 2 en 3 (de nummers van de pinnen waar ik TX en RX op had aangesloten). Ik heb I²C ook getest met een Arduino Uno, met een ander voorbeeldprogramma en dat werkte direct goed.
Als je verandert van bijvoorbeeld HSU naar I²C dan moet je de schakeling even van de stroombron afhalen anders krijg je mogelijk de melding dat de module "niet gevonden" wordt.
#include <SoftwareSerial.h>
#include <PN532_SWHSU.h>
#include <PN532.h>

SoftwareSerial SWSerial( D1, D2 ); // D1 = RX, deze gaat naar TX op de PN535; D2 is TX, deze gaat naar RX op de PN535)
PN532_SWHSU pn532swhsu( SWSerial );
PN532 nfc( pn532swhsu );

void setup(void) {
  Serial.begin(115200);
  nfc.begin();
  uint32_t versiondata = nfc.getFirmwareVersion();
  if (! versiondata) {
    Serial.print("\nIk kan geen PN535 vinden");
    while (1); // Stop hier -- maar de WeMos start zichzelf steeds opnieuw op
  }

  Serial.print("\nPN535 gevonden!");
  Serial.print("Firmware versie "); Serial.print((versiondata >> 16) & 0xFF, DEC);
  Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC);

  nfc.SAMConfig(); // configureer voor het lezen van RFID kaarten of druppels
  Serial.println("Houd een RFID kaart of druppel bij de sensor...");
}

void loop(void) {
  boolean success;
  uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 };  // Buffer
  uint8_t uidLength;                        // Lengte van de UID (4 of 7 bytes, hangt af van ISO14443A kaart type)
  success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, &uid[0], &uidLength);

  if (success) {
    Serial.println("Kaart gedetecteert");
    Serial.print("UID Lengte: "); Serial.print(uidLength, DEC); Serial.println(" bytes");
    Serial.print("UID Code: ");
    for (uint8_t i = 0; i < uidLength; i++) {
      Serial.print(" 0x");
      Serial.print(uid[i], HEX);
    }
    Serial.println();
    Serial.println("\nHoud een RFID kaart of druppel bij de sensor...");
    delay(1000);
  }
}

125 kHz (RMD6300) lezer

Deze module ziet er op het eerste gezicht ingewikkeld uit en er staat geen enkele informatie bij de pinnen. Maar toch is het aansluiten erg eenvoudig: Het blokje van 3 pinnen rechts onderaan is voor de voeding. Sluit de middelste pin aan op VCC en de linkse op GND. Op de twee pinnen links onder sluit je de spoel aan (het maakt niet uit hoe). Als je het geheel op een breadboard plaats dan kun je twee jumper kabeltjes gebruiken om het witte stekkertje te verbinden met het breadboard. Van de vijf pinnen bovenaan gebruik je alleen de pin die helemaal rechts zit. Verbind deze met digitale pin 2 van de Arduino. Meer is niet nodig! Als je wilt weten wat de andere pinnen doen: de twee linkse pinnen van de 5 pinnen bovenaan kun je ook gebruiken voor VCC en GND; de middelste pin is niet aangesluiten en de vierde pin is RX (maar die gebruik je niet). Op de pin onder rechts kun je een led aansluiten (er is al en weerstand van 100 Ω aanwezig). De led is altijd aan, maar hij knippert als er een kaart of druppel in de buurt is. Helaas is de knipperfrequentie 1000 Hz, dus vrijwel onzichtbaar.

RFID opstelling
Op het breadboard Arduino pro mini met de RFID lezer; rechts de RFID spoel.

Hieronder staat een eenvoudige sketch waarmee je de module kunt testen. Hij geeft een rij getallen die uniek zijn voor de kaart of de druppel. Hiermee kun je al allerlei leuke projecten doen, bijvoorbeeld in de klas.
#include <SoftwareSerial.h>
SoftwareSerial RFID(2, 3); // alleen RX (= TX van de module) wordt gebruikt

void setup() {
  RFID.begin(9600);
  Serial.begin(9600);
}

void loop()
{
  if ( RFID.available() ) {
    delay(50); // Dit zorgt ervoor dat je niet gemakkelijk meer dan 1 keer de code leest.
    int i = RFID.read(); // Lees het volgende getal
    Serial.print(i); Serial.print(" "); // Print het identifcatienummer van de druppel
    if (i == 3) { // De code eindigt altijd met een 3
      Serial.println();
      while ( RFID.read() >= 0); // Een keer is genoeg (kaart moet inmiddels weg zijn)
    }
  }
}
Hieronder zie je het resultaat van 10 verschillende druppels.

De getallen die je hierboven ziet bevatten ook controlegetallen en stuurgetallen. Als je de codes inzichtelijker wilt maken (en beter bruikbaar) dan kun je het beste een bibliotheek gebruiken. Een simpele bibliotheek is RFIDRdm630.h. Deze is bedoeld voor de RDM630, maar werkt ook met de RDM6300 en een aantal andere RFID lezers. Je ziet dat de uitvoer veel overzichtelijker is. Het gevonden kaartnummer komt overeen met het opschrift op de druppel. Erg handig dus. Zie hieronder de gebruikte schets.
#include "RFIDRdm630.h"
RFIDtag tag;  // RFIDtag object
RFIDRdm630 reader = RFIDRdm630(2, 3); // Resultaat komt binnen op poort 2

void setup() {
  Serial.begin(9600);
}

void loop() {
  if (reader.isAvailable()) {
    tag = reader.getTag();
    Serial.print("TAG: ");
    Serial.print(tag.getTag()); // TAG in ASCII formaat
    Serial.print(" Druppel nummer: ");
    Serial.println(tag.getCardNumber()); // Druppel nummer als decimaal getal
    Serial.println();
  }
}
Dit zie je op de seriële monitor: met deze druppel:
In het midden van de "TAG" zie je het kaartnummer, maar dan als hexadecimaal getal (4FFCFA).
Omdat mijn druppels niet schrijfbaar zijn heb ik dat ook niet getest.