INTRODUCTION
This tutorial will allow you to define unique responses to the detection of an RFID tag by an RFID sensor. To demonstrate this, RFID tags will be identified into two categories, and each category will have a different response. A tag that does not fit into either category will also have a response.
Group 1 = Red LED will light up
Group 2 = Yellow LED will light up
No Group = Both LEDs will flash
For our prototype project, this will simulate vulnerable pedestrians nearing an intersection, and the intersection responding with one of two actions. In the real scenario, these actions might be a warning light or a speaker announcement that indicates to the pedestrian when it is safe to cross.
PARTS LIST
For this tutorial, you will need:
- Arduino Uno
- PN532 RFID/NFC Shield
- Two MIFARE Classic (ISO-14443A) 1K cards
- Solderless Breadboard
- Two LEDs
- Two 330Ω Resistors
- Wires (as needed)
CIRCUIT DIAGRAM
The wiring for this setup is fairly simple. The PN532 RFID/NFC Shield will stack directly on top of the Arduino Uno, but to show the critical connections to the board, the wiring diagram below shows them next to each other.
PARTS SETUP
The picture below shows what the parts look like when they are assembled.
UNDERSTANDING THE RFID TAG MEMORY ORGANIZATION
RFID tags have the ability to store data on them and this data is stored in a hexadecimal system to help maintain the integrity of the data during the exchange between devices. The cards in this tutorial can hold up to 1Kb of data, which is 1025 bytes of data. These bytes are organized into 16 sectors, which are divided into 8 blocks, and each block holds 8 bytes of data.
8 bytes x 8 blocks x 16 sectors = 1024 bytes.
This is important for this tutorial because the unique ID number for each tag is stored in the first 4 bytes of the 0 block in the 0 sector.
CODE
Below is the code that does the following steps:
- Download the Adafruit_PN532 library
- Define pin connections for an I2C connection (I2C protocol allows for multiple “slave” devices to connect to one “master” device)
- Define two response groups by unique tag ID
- Configure board to read RFID tags
- Search for ISO14443A card
- If a card is found, the card is authenticated
- Using the unique ID of the card, determines the response group
- LED response or output to try another card
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
#include <Wire.h> #include <SPI.h> #include <Adafruit_PN532.h> // To use the shield with I2C, define the pins connected // to the IRQ and reset lines. #define PN532_IRQ (2) #define PN532_RESET (3) Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET); #if defined(ARDUINO_ARCH_SAMD) // for Zero, output on USB Serial console, remove line below if using // programming port to program the Zero! #define Serial SerialUSB #endif void setup(void) { pinMode(8, OUTPUT); //Define Red LED output pin pinMode(7, OUTPUT); //Define Yellow LED output pin //Start Serial Monitor and set baud rate Serial.begin(115200); Serial.println("Hello!"); nfc.begin(); //initiate NFC connection //Search for PN532 uint32_t versiondata = nfc.getFirmwareVersion(); if (! versiondata) { Serial.print("Didn't find PN53x board"); while (1); // halt } //If firmware found, print to serial monitor Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX); Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC); Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC); //configure board to read RFID tags nfc.SAMConfig(); Serial.println("Waiting for an ISO14443A Card ..."); Serial.println(""); } void loop(void) { uint8_t success; // Create variable for detected card uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type) //Create Groups for different responses uint32_t Group1 = 1693588743; //Red LED uint32_t Group2 = 436264598; //Yellow LED uint32_t cardidentifier = 0; //Variable for current card being read //Success boolean is defined when a card is found and read success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength); if (success) { // Print that card is found 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); Serial.println(""); if (uidLength == 4) // Mifare Classic Card { Serial.println("This is a Mifare Classic card (4 byte UID)"); // Authenticate the card for read/write access // using the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF // Start with block 4 (the first block of sector 1) since sector 0 // contains the manufacturer data and it's probably better just // to leave it alone unless you know what you're doing Serial.println("Trying to authenticate block 4 with default KEYA value"); uint8_t keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // Redefine success boolean if card is authenticated success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya); if (success) { Serial.println("Sector 1 (Blocks 4..7) has been authenticated"); Serial.println(""); uint8_t data[16]; //Turn UID into a single variable cardidentifier = uid[3]; cardidentifier <<= 8; cardidentifier |= uid[2]; cardidentifier <<= 8; cardidentifier |= uid[1]; cardidentifier <<= 8; cardidentifier |= uid[0]; Serial.print("Card Number "); Serial.print(cardidentifier); Serial.print(": "); if(cardidentifier == Group1) //Flash Red LED { response1(); } else if(cardidentifier == Group2) //Flash Yellow LED { response2(); } else //Flash both LEDs 3 times { noGroup(); } // Pause before reading another card delay(1000); } } else { Serial.println("Ooops ... authentication failed: Try another key?"); } if (uidLength == 7) { // We probably have a Mifare Ultralight card ... Serial.println("Seems to be a Mifare Ultralight tag (7 byte UID)"); Serial.println("Please try another card"); } } } void response1() { digitalWrite(8, HIGH); // Turn on the Red LED delay(1000); digitalWrite(8,LOW); //Turn Red LED off Serial.println("Group 1"); } void response2() //Light up Yellow LED { digitalWrite(7, HIGH); // Turn on the Yellow LED delay(1000); digitalWrite(7,LOW); //Turn Yellow LED off Serial.println("Group 2"); } void noGroup() // Flash LED 3 times { Serial.println("No Group Identified"); Serial.println("Please try another card."); Serial.println(""); digitalWrite(7, HIGH); digitalWrite(8, HIGH); delay(50); digitalWrite(7,LOW); digitalWrite(8,LOW); delay(50); digitalWrite(7, HIGH); digitalWrite(8, HIGH); delay(50); digitalWrite(7,LOW); digitalWrite(8,LOW); delay(50); digitalWrite(7, HIGH); digitalWrite(8, HIGH); delay(50); digitalWrite(7,LOW); digitalWrite(8,LOW); delay(50); } |
VIDEO
The following video will show the RFID sensor in action!