This is a basic access control project to read and use the unique IDs of RFID cards including the University of Auckland ID cards.
It uses an RFIDRC522 module that can read 13.56MHz cards and the code is based on the RC522 Arduino library found HERE. It can also write data to the sectors of blank types of these cards for offline data storage or counting, but for this project, we will just be reading the ID numbers of the cards.
First of all these RC522 modules are 3.3v. This means they need a 3.3V microcontroller or 5V to 3.3V level shifting hardware such as these modules. In my case, I’ve chosen to use a 3.3V ESP8266 based microcontroller board for its WiFi capabilities for the second half of this project. This RC522 board and library use the SPI (serial peripheral interface) to communicate which have specific pins that need to be connected to on the module and microcontroller.
The ESP8266 code is a little different from standard Arduino code in that it requires the pins to be defined with the capital letter “D” in front of the pin number, eg. D9.
The following table shows the typical pin layout used:
PCD | Arduino | Teensy | |||||||
---|---|---|---|---|---|---|---|---|---|
MFRC522 | Uno / 101 | Mega | Nano v3 | Leonardo / Micro | Pro Micro | 2.0 | ++ 2.0 | 3.1 | |
Signal | Pin | Pin | Pin | Pin | Pin | Pin | Pin | Pin | Pin |
RST/Reset | RST | 9 | 5 | D9 | RESET / ICSP-5 | RST | 7 | 4 | 9 |
SPI SS | SDA | 10 | 53 | D10 | 10 | 10 | 0 | 20 | 10 |
SPI MOSI | MOSI | 11 / ICSP-4 | 51 | D11 | ICSP-4 | 16 | 2 | 22 | 11 |
SPI MISO | MISO | 12 / ICSP-1 | 50 | D12 | ICSP-1 | 14 | 3 | 23 | 12 |
SPI SCK | SCK | 13 / ICSP-3 | 52 | D13 | ICSP-3 | 15 | 1 | 21 | 13 |
ESP8266 | Arduino | |
---|---|---|
Wemos D1 mini | Yun | |
Signal | Pin | Pin |
RST/Reset | D3 | Pin9 |
SPI SS | D8 | Pin10 |
SPI MOSI | D7 | ICSP4 |
SPI MISO | D6 | ICSP1 |
SPI SCK | D5 |
The code is basically the same as the demo but has the verbose (commenting) serial outputs controlled with the “#define debug X” setting at the top ( where X is either 1 = on or 0 = off). There is also a two-row array (table) that holds the RFID ID numbers and corresponding user names, both as strings (text). The image below from programmingelectronics.com shows how a multi-dimensional array works.
Below is the test code to read and check RFID ID numbers against the ID’s coded into an array. Arduino sketch can also be downloaded here:
/* * * This example has been ammended by Jamie Coombe to include * - WiFI off * - Serial Baud rate to 115200 * - ID numbers and Card holders held in array * - Debug setting to limit serial data * -------------------------------------------------------------------------------------------------------------------- Example sketch/program showing how to read data from a PICC to serial. -------------------------------------------------------------------------------------------------------------------- This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid Example sketch/program showing how to read data from a PICC (that is: a RFID Tag or Card) using a MFRC522 based RFID Reader on the Arduino SPI interface. When the Arduino and the MFRC522 module are connected (see the pin layout below), load this sketch into Arduino IDE then verify/compile and upload it. To see the output: use Tools, Serial Monitor of the IDE (hit Ctrl+Shft+M). When you present a PICC (that is: a RFID Tag or Card) at reading distance of the MFRC522 Reader/PCD, the serial output will show the ID/UID, type and any data blocks it can read. Note: you may see "Timeout in communication" messages when removing the PICC from reading distance too early. If your reader supports it, this sketch/program will read all the PICCs presented (that is: multiple tag reading). So if you stack two or more PICCs on top of each other and present them to the reader, it will first output all details of the first and then the next PICC. Note that this may take some time as all data blocks are dumped, so keep the PICCs at reading distance until complete. @license Released into the public domain. Typical pin layout used: ----------------------------------------------------------------------------------------- MFRC522 Arduino Arduino Arduino Arduino Arduino Reader/PCD Uno/101 Mega Nano v3 Leonardo/Micro Pro Micro Signal Pin Pin Pin Pin Pin Pin ----------------------------------------------------------------------------------------- RST/Reset RST 9 5 D9 RESET/ICSP-5 RST SPI SS SDA(SS) 10 53 D10 10 10 SPI MOSI MOSI 11 / ICSP-4 51 D11 ICSP-4 16 SPI MISO MISO 12 / ICSP-1 50 D12 ICSP-1 14 SPI SCK SCK 13 / ICSP-3 52 D13 ICSP-3 15 */ #include <SPI.h> #include <MFRC522.h> #include <ESP8266WiFi.h> #define RST_PIN D9 // Configurable, see typical pin layout above #define SS_PIN D10 // Configurable, see typical pin layout above /* * Card ID stored in a 2D array * First Row = Card numbers as Hex * Second ROw = Card name as txt * Example card - D0 EA 69 32 * Example Token - C9 0D 8D C2 * John Smith ID - XX XX XX XX XX XX * */ //increase the array columns [2][X+] and add more ID's and Names String cardIDs [2][3] = { {"D0 EA 69 32", "C9 0D 8D C2", "XX XX XX XX XX XX"}, {"Example Card", "Example Token", "John Smith"} }; // Debug setting, 1=Verbose output, 0=minimun output #define debug 0 MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance MFRC522::MIFARE_Key key; // Setup loop void setup() { // Turn off the WiFi comunication by putting it to sleep WiFi.forceSleepBegin(); Serial.begin(115200); // Initialize serial communications with the PC while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4) SPI.begin(); // Init SPI bus mfrc522.PCD_Init(); // Init MFRC522 card // Prepare the key (used both as key A and as key B) // using FFFFFFFFFFFFh which is the default at chip delivery from the factory for (byte i = 0; i < 6; i++) { key.keyByte[i] = 0xFF; } delay(100); Serial.println("Ready"); //dump_byte_array(key.keyByte, MFRC522::MF_KEY_SIZE); Serial.println(); } // Main loop void loop() { // Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle. if ( ! mfrc522.PICC_IsNewCardPresent()) return; // Select one of the cards if ( ! mfrc522.PICC_ReadCardSerial()) return; MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); if (debug) { // Show some details of the PICC (that is: the tag/card) Serial.print(F("Card UID:")); dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size); Serial.println(); Serial.print(F("PICC type: ")); Serial.println(mfrc522.PICC_GetTypeName(piccType)); } // Check for compatibility if ( piccType != MFRC522::PICC_TYPE_MIFARE_MINI && piccType != MFRC522::PICC_TYPE_MIFARE_1K && piccType != MFRC522::PICC_TYPE_MIFARE_4K && piccType != MFRC522::PICC_TYPE_ISO_14443_4) { Serial.println(F("No valid tag")); return; } else if (piccType == MFRC522::PICC_TYPE_ISO_14443_4) { if(debug) Serial.println(F("Valid UoA 7-bit tag type")); } MFRC522::StatusCode status; String content = ""; get_UID(content); // Halt PICC mfrc522.PICC_HaltA(); // Stop encryption on PCD mfrc522.PCD_StopCrypto1(); } // Outputs raw data void dump_byte_array(byte *buffer, byte bufferSize) { for (byte i = 0; i < bufferSize; i++) { Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], HEX); } } // Function that checks the ID number and gives feedback of the ID name void get_UID(String content) { for (byte i = 0; i < mfrc522.uid.size; i++) { content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ")); content.concat(String(mfrc522.uid.uidByte[i], HEX)); } content.toUpperCase(); int x; // Vairable to store search location // Gets the number of entries (columns) into the ID storage array int arrayLength = sizeof (cardIDs[0]) / sizeof (cardIDs[0][0]); for (x = 0; x < arrayLength; x++) { if (content.substring(1) == cardIDs[0][x]) { Serial.println(cardIDs[1][x]); return; } } // If it get to this stage and the array check has reached the end of the array // then it did not find the ID number if (x >= (arrayLength - 1)) { Serial.println("Unknown ID!"); Serial.println(); } } /* * ToDo * - WiFi ID code check from master / AP */