RFID? NFC? What is it?
In this article we would like to show you how to read ID tags. The focus of the article is the PN532 NFC RFID module.
The module is based on the NXP PN532 chip. This chipset is widely used in the field of NFC (Near Field Communication). An NFC-enabled object, often a check card with an NFC chip, is held up to an NFC reader. This allows information to be exchanged in a fraction of a second.
Does that sound abstract? If you have a newer EC card and use it for contactless payment, then you know NFC even from everyday life. By placing the card on the card terminal, the transaction is initiated - quickly and easily.
We would like to take a closer look at the technical processes behind this. The PN532 module is ideally suited for this purpose, as it is both I2C and SPI capable. The desired type of communication can be selected directly on the board of the PN532 by flipping the switches on it. The required switch position of the respective interfaces very you to the right of the circuit diagram, which is located a little further down the page.
The schematic:
Tip: A high resolution version of this picture can be found here. There you can see the pinout a bit better.
The program code (I2C version)
//*******************************************************************************************************
//** Example sketch for reading ID tags. With matching ID PIN 13 is switched on for 2 seconds **
//** is switched on (LED). If ID is wrong, a tone is generated at pin 12. (PASSIVE buzzer / piezzo) **
//** use. Instead of an LED, a door lock can also be switched (via TIP120 switching amplifier **
//*******************************************************************************************************
#include <Wire.h> // Library for I2C protocol
#include <Adafruit_PN532.h> // Library for the NFC/RFID module! !! Please load by Arduino IDE !!!
#define PN532_IRQ (2) // Define the IRQ port
#define PN532_RESET (3) // Define the Reset connector
const int AlarmPin = 12; // Pin 12 output for piezo speaker
const int OutputPin = 13; // Pin 13 output for LED or via TIP120 to a magnetic lock
unsigned long cardid; // Variable for the read TAG ID
unsigned long TAGid1 = 1702536620; // IDs to be accepted can be entered here
unsigned long TAGid2 = 4070796058; // Otherwise leave blank. The ID of single TAGs can be specified with
unsigned long TAGid3 ; // the serial monitor (set 115200 baud)
Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET); // Create instance with I2C protocol
void setup() { // start setup function
pinMode(AlarmPin, OUTPUT); // define PIN as output
pinMode(OutputPin, OUTPUT); // Define PIN as output
Serial.begin(115200); // Open serial transmission with 115200 baud (ser monitor same baud setting!)
Serial.println("Hello!"); // Send text "Hello!" to serial monitor
nfc.begin(); // Start communication with RFID reader
unsigned long versiondata = nfc.getFirmwareVersion(); // Read version number of firmware
if (! versiondata) { // If no response is received
Serial.print("Can't find board !"); // Send text "Can't find..." to serial monitor
while(1); // so long stop
}
Serial.print("Chip PN5 found"); Serial.println((versiondata >> 24) & 0xFF, HEX); // Send text and version info to serialmonitor
Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC); // Monitor if response from board is received
Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC); //
nfc.SAMConfig(); // Configure board to read RFID tags
Serial.println("Waiting for an ISO14443A chip ..."); // Send text that waiting to serial monitor
}
void loop() { // Start loop function
uint8_t success; // Create variable
uint8_t uid[] = { 0, 0, 0, 0, 0 }; // Buffer to store the UID
uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card/chip type)
// Wait for an ISO14443A chip. If one is detected, the variable
// will be filled with the UID. Depending on the length (4 bytes (Mifare Classic) or
// 7 bytes (Mifare Ultralight) the card type is detected.
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
if (success) { // If detected, work off....
Serial.println("Found an ISO14443A card");
Serial.print(" UID Length: "); Serial.print(uidLength, DEC); Serial.println(" bytes");
Serial.print(" UID Value: ");
nfc.PrintHex(uid, uidLength); // print information to serial monitor
if (uidLength == 4) { // If the card/chip has 4 byte length....
// Mifare Classic card
cardid = uid[0]; //
cardid <<= 8; // Set the 4 byte blocks
cardid |= uid[1]; //
cardid <<= 8; // to a single block
cardid |= uid[2]; //
cardid <<= 8; // together
cardid |= uid[3]; //
Serial.print("Appears to be a Mifare Classic #"); //
Serial.println(cardid); // Output the information
Serial.println(""); //
Serial.println(""); //
}
if ((cardid) == (TAGid1)||(cardid) == (TAGid2)||(cardid) == (TAGid3)) // Query whether the TAGs 1..2..3 with the respective
{digitalWrite(OutputPin,HIGH); // matches. Then switch depending on the
delay(2000);
digitalWrite(OutputPin,LOW);} // on or off
else
{tone(AlarmPin, 1000); // And output a tone/frequency if necessary
delay(4000);
noTone(AlarmPin);}
} // End of IF query/loop
} // End of the loop
The program code (SPI version)
//*******************************************************************************************************
//** Example sketch for reading ID tags. If the ID matches, PIN 13 will be ** for 2 seconds
//** is switched on (LED). If ID is wrong, a tone is generated at pin 12. (PASSIVE buzzer / piezzo) **
//** use. Instead of an LED, a door lock can also be switched (via TIP120 switching amplifier **
//*******************************************************************************************************
#include <Wire.h> // library for I2C protocol
#include <SPI.h> // Library for SPI protocol
#include <Adafruit_PN532.h> // Library for the NFC/RFID module !!! Please load by Arduino IDE !!!
const byte PN532_SCK = 2; //
const byte PN532_MOSI =3; // Define the connections for
const byte PN532_SS = 4; // the SPI connection to the RFID
const byte PN532_MISO =5; // board
const int AlarmPin = 12; // define the connections for
const int OutputPin = 13; // the (switching) outputs
unsigned long cardid; // variable for the read TAG-ID
unsigned long TAGid1 = 1702536620; // IDs to be accepted can be entered here
unsigned long TAGid2 = 4070796058; // Otherwise leave blank. The ID of single TAGs can be specified with
unsigned long TAGid3 ; // the serial monitor (set 115200 baud)
Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS); // Create instance with SPI protocol
void setup() { // Start setup function
pinMode(AlarmPin, OUTPUT); // Define PIN as output
pinMode(OutputPin, OUTPUT); // Define PIN as output
Serial.begin(115200); // Open serial transmission with 115200 baud (ser monitor same baud setting!)
Serial.println("Hello!"); // Send text "Hello!" to serial monitor
nfc.begin(); // Start communication with RFID reader
unsigned long versiondata = nfc.getFirmwareVersion(); // Read version number of firmware
if (! versiondata) { // If no response is received
Serial.print("Can't find board !"); // Send text "Can't find..." to serial monitor
while(1); // so long stop
}
Serial.print("Found chip PN5"); Serial.println((versiondata >> 24) & 0xFF, HEX); // Send text and version info to serialmonitor
Serial.print("Firmware ver. "); Serial.print((versiondata >> 16) & 0xFF, DEC); // Monitor when response comes from board
Serial.print('.'); Serial.println((versiondata >> 8) & 0xFF, DEC); //
nfc.SAMConfig(); // Configure board to read RFID tags
Serial.println("Waiting for an ISO14443A chip ..."); // Send text that waiting to serial monitor
}
void loop() { // Start loop function
uint8_t success; // Create variable
uint8_t uid[] = { 0, 0, 0, 0, 0 }; // Buffer to store the UID
uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card/chip type)
// Wait for an ISO14443A chip. If one is detected, the variable
// will be filled with the UID. Depending on the length (4 bytes (Mifare Classic) or
// 7 bytes (Mifare Ultralight) the card type is detected.
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
if (success) { // If detected, work off....
Serial.println("Found an ISO14443A card");
Serial.print(" UID Length: "); Serial.print(uidLength, DEC); Serial.println(" bytes");
Serial.print(" UID Value: ");
nfc.PrintHex(uid, uidLength); // print information to serial monitor
if (uidLength == 4) { // If the card/chip has 4 byte length....
// Mifare Classic card
cardid = uid[0]; //
cardid <<= 8; // Set the 4 byte blocks
cardid |= uid[1]; //
cardid <<= 8; // to a single block
cardid |= uid[2]; //
cardid <<= 8; // together
cardid |= uid[3]; //
Serial.print("Appears to be a Mifare Classic #"); //
Serial.println(cardid); // Output the information
Serial.println(""); //
Serial.println(""); //
}
if ((cardid) == (TAGid1)||(cardid) == (TAGid2)||(cardid) == (TAGid3)) // Query whether the TAGs 1..2..3 with the respective
{digitalWrite(OutputPin,HIGH); // matches. Then switch depending on the
delay(2000);
digitalWrite(OutputPin,LOW);} // on or off
else
{tone(AlarmPin, 1000); // And output a tone/frequency if necessary
delay(4000);
noTone(AlarmPin);}
} // End of IF query/loop
} // End of loop