### Copy RFID Cards with Standard Authentication Source: https://github.com/miguelbalboa/rfid/blob/master/changes.txt This example demonstrates how to copy RFID cards using standard authentication methods. It requires the MFRC522 library. ```ino #include #include #define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); Serial.println("Place the source card on the reader..."); } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } if ( ! mfrc522.PICC_ReadCardSerial()) { return; } Serial.println("Source card detected."); // Attempt to authenticate and read data from the source card // This is a simplified example; actual cloning might involve more complex sector-by-sector reading and writing. // For full cloning, you would typically read all sectors and then write them to a new card. // Example: Reading the first block of the first sector (if accessible) byte blockAddr = 1; byte buffer[16]; MFRC522::StatusCode status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, blockAddr, &mfrc522.key, (&mfrc522.uid)); if (status == MFRC522::STATUS_OK) { status = mfrc522.MIFARE_Read(blockAddr, buffer, &bufferSize); if (status == MFRC522::STATUS_OK) { Serial.print("Data from block "); Serial.print(blockAddr); Serial.print(": "); for (byte i = 0; i < bufferSize; i++) { Serial.print(buffer[i] < 0x10 ? " 0" : " "); Serial.print(buffer[i], HEX); } Serial.println(); } else { Serial.println("Error reading block."); } } else { Serial.println("Authentication failed."); } mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); Serial.println("Place the destination card on the reader to write..."); // In a real cloning scenario, you would now write the read data to the destination card. // This requires another loop to detect the destination card and use MIFARE_Write. } ``` -------------------------------- ### Arduino Setup Function Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl Configures pin modes for LEDs, button, and relay. Initializes serial communication, SPI, and the MFRC522 reader. Sets initial states for hardware components. ```c++ void setup() { //Arduino Pin Configuration pinMode(redLed, OUTPUT); pinMode(greenLed, OUTPUT); pinMode(blueLed, OUTPUT); pinMode(wipeB, INPUT_PULLUP); // Enable pin's pull up resistor pinMode(relay, OUTPUT); //Be careful how relay circuit behave on while resetting or power-cycling your Arduino digitalWrite(relay, HIGH); // Make sure door is locked digitalWrite(redLed, LED_OFF); // Make sure led is off digitalWrite(greenLed, LED_OFF); // Make sure led is off digitalWrite(blueLed, LED_OFF); // Make sure led is off //Protocol Configuration Serial.begin(9600); // Initialize serial communications with PC SPI.begin(); // MFRC522 Hardware uses SPI protocol mfrc522.PCD_Init(); // Initialize MFRC522 Hardware //If you set Antenna Gain to Max it will increase reading distance //mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max); Serial.println(F("Access Control Example v0.1")); // For debugging purposes ShowReaderDetails(); // Show details of PCD - MFRC522 Card Reader details } ``` -------------------------------- ### Authentication with NTAG 213/215/216 Source: https://github.com/miguelbalboa/rfid/blob/master/changes.txt This example shows how to perform authentication with NTAG 213, 215, and 216 cards, returning the ACK status. It uses the MFRC522 library's authentication functions. ```ino #include #include #define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); Serial.println("Scan an NTAG card to authenticate..."); } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } if ( ! mfrc522.PICC_ReadCardSerial()) { return; } MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); if (piccType == MFRC522::PICC_TYPE_NTAG213 || piccType == MFRC522::PICC_TYPE_NTAG215 || piccType == MFRC522::PICC_TYPE_NTAG216) { Serial.println("NTAG card detected. Attempting authentication..."); // For NTAG21x, authentication typically uses a specific key and page. // The example assumes a default key or a known key for the card. // Replace with your actual key if known. byte defaultKey[6] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}; byte page = 4; // Example page for authentication MFRC522::StatusCode status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_NTAG216_AUTH, page, defaultKey, (&mfrc522.uid)); if (status == MFRC522::STATUS_OK) { Serial.println("Authentication successful. ACK received."); // You can now perform read/write operations on authenticated pages. } else { Serial.print("Authentication failed. Status code: "); Serial.println(status, HEX); } } else { Serial.println("Not an NTAG card or unsupported type."); } mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); } ``` -------------------------------- ### Arduino Setup Function Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Configures Arduino pins for output (LEDs, relay) and input (button), initializes serial communication, SPI, the MFRC522 reader, and the LCD. Sets the RFID reader's antenna gain to maximum. ```cpp void setup() { //Arduino Pin Configuration pinMode(redLed, OUTPUT); pinMode(greenLed, OUTPUT); pinMode(blueLed, OUTPUT); pinMode(wipeB, INPUT_PULLUP); // Enable pin's pull up resistor pinMode(relay, OUTPUT); //Be careful how relay circuit behave on while resetting or power-cycling your Arduino digitalWrite(relay, LOW); // Make sure door is locked - Setting Low as Solenoid is not 100% duty cycle digitalWrite(redLed, LED_OFF); // Make sure led is off digitalWrite(greenLed, LED_OFF); // Make sure led is off digitalWrite(blueLed, LED_OFF); // Make sure led is off //Protocol Configuration Serial.begin(9600); // Initialize serial communications with PC SPI.begin(); // MFRC522 Hardware uses SPI protocol mfrc522.PCD_Init(); // Initialize MFRC522 Hardware lcd.begin(16,2); // Initialize LCD //If you set Antenna Gain to Max it will increase reading distance mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max); // Serial.println(F( "Access Control Example v0.1")); // For debugging purposes, I commented this out to clean up serial output ShowReaderDetails(); // Show details of PCD - MFRC522 Card Reader details } ``` -------------------------------- ### LCD Display Setup Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Clears the LCD and displays 'Scan Card' to prompt the user. This is typically done after system initialization or when the system is ready for a card scan. ```C++ lcd.clear(); // Make sure LCD is cleared lcd.print(F("Scan Card")); // Read "Scan Card" to an LCD ``` -------------------------------- ### Arduino RFID Access Control with Servo Motor Source: https://github.com/miguelbalboa/rfid/blob/master/changes.txt Example demonstrating how to use an RFID reader to control a servo motor, suitable for access control systems. ```ino #include #include #include #define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN, RST_PIN); Servo myservo; void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); myservo.attach(3); // Attach servo to digital pin 3 myservo.write(0); // Start with servo at 0 degrees Serial.println("Scan a card to access..."); } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } if ( ! mfrc522.PICC_ReadCardSerial()) { return; } // Print the UID of the card String uid = ""; for (byte i = 0; i < mfrc522.uid.size; i++) { uid += String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "); uid += String(mfrc522.uid.uidByte[i], HEX); } Serial.print("Card UID: "); Serial.println(uid); // Example: If UID matches a specific card, open the servo // Replace "YOUR_TARGET_UID_HERE" with the actual UID if (uid.indexOf("YOUR_TARGET_UID_HERE") != -1) { Serial.println("Access granted. Opening door..."); myservo.write(90); // Move servo to 90 degrees delay(5000); // Keep door open for 5 seconds myservo.write(0); // Close door } else { Serial.println("Access denied."); } mfrc522.PICC_HaltA(); // Halt PICC mfrc522.PCD_StopCrypto1(); // Stop encryption on PCD } ``` -------------------------------- ### RFID Access Control System Setup Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl This C++ code sets up an Arduino for door access control using an MFRC522 RFID reader, SPI communication, and EEPROM for persistent storage of user UIDs and master card information. It includes typical pin assignments for various Arduino boards. ```C++ #include #include #include /* Instead of a Relay you may want to use a servo. Servos can lock and unlock door locks too Relay will be used by default */ // #include ``` -------------------------------- ### Read New NUID from a PICC to Serial Source: https://github.com/miguelbalboa/rfid/blob/master/changes.txt This example demonstrates how to read a new Unique Identifier (NUID) from a PICC (Proximity Integrated Circuit Card) and display it on the serial monitor. It utilizes SPI communication. ```ino #include #include #define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN, RST_PIN); void setup() { Serial.begin(9600); SPI.begin(); mfrc522.PCD_Init(); Serial.println("Scan a card to read its NUID..."); } void loop() { if ( ! mfrc522.PICC_IsNewCardPresent()) { return; } if ( ! mfrc522.PICC_ReadCardSerial()) { return; } Serial.print("Card UID:"); String uid = ""; for (byte i = 0; i < mfrc522.uid.size; i++) { uid += String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "); uid += String(mfrc522.uid.uidByte[i], HEX); } Serial.println(uid); // Print card type MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); Serial.print("Card Type: "); Serial.println(mfrc522.PICC_GetTypeName(piccType)); // Halt PICC mfrc522.PICC_HaltA(); mfrc522.PCD_StopCrypto1(); } ``` -------------------------------- ### Access Control Variables and RFID Setup Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Initializes variables for access control logic, including flags for matching cards, programming mode, and master card replacement. Sets up the MFRC522 RFID reader instance with specified SPI pins. ```cpp int lockDelay=10000; // lock stays open for 10 seconds. boolean match = false; // initialize card match to false boolean programMode = false; // initialize programming mode to false boolean replaceMaster = false; // initialize master replace mode to false uint8_t successRead; byte storedCard[4]; // Stores an ID read from EEPROM byte readCard[4]; // Stores scanned ID read from RFID Module byte masterCard[4]; // Stores master card's ID read from EEPROM // Create MFRC522 instance. #define SS_PIN 53 // Set SS pin for MFRC522 #define RST_PIN 5 // Set RST pin for MFRC522 MFRC522 mfrc522(SS_PIN, RST_PIN); ``` -------------------------------- ### Change MIFARE Classic Keys Source: https://github.com/miguelbalboa/rfid/wiki/How-to-change-keys? This C++ example demonstrates how to change KeyA and KeyB on a MIFARE Classic PICC. It targets sector 15, blocks 60-63. Ensure you have the correct old keys before attempting to change them, as incorrect keys will result in data loss. ```cpp /** ---------------------------------------------------------------------------- This is a MFRC522 library example; see https://github.com/miguelbalboa/rfid for further details and other examples. NOTE: The library file MFRC522.h has a lot of useful info. Please read it. Released into the public domain. ---------------------------------------------------------------------------- This sample shows how to change KeyA or KeyB on a MIFARE Classic PICC (= card/tag). BEWARE: Data will be written to the PICC, in sector #15 (blocks #60 to #63). 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 #include #define RST_PIN 9 // Configurable, see typical pin layout above #define SS_PIN 10 // Configurable, see typical pin layout above MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance. MFRC522::MIFARE_Key key; // MFRC522::MIFARE_Key keyB; MFRC522::MIFARE_Key newKeyA = {keyByte: {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5}}; MFRC522::MIFARE_Key newKeyB = {keyByte: {0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5}}; /** Initialize. */ void setup() { Serial.begin(9600); // 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 // using FFFFFFFFFFFFh which is the default at chip delivery from the factory for (byte i = 0; i < MFRC522::MF_KEY_SIZE; i++) { key.keyByte[i] = 0xFF; // keyB.keyByte[i] = 0xFF; } Serial.println(F("Scan a MIFARE Classic PICC to demonstrate read and write.")); Serial.print(F("Using key (for A and B):")); dump_byte_array(key.keyByte, MFRC522::MF_KEY_SIZE); Serial.println(); } /** Main loop. */ void loop() { // Look for new cards if (!mfrc522.PICC_IsNewCardPresent()) return; // Select one of the cards if (!mfrc522.PICC_ReadCardSerial()) return; // 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: ")); MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak); 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) { Serial.println(F("This sample only works with MIFARE Classic cards.")); return; } // change keys in section 15 block 63 if (!MIFARE_SetKeys(&key, &key, &newKeyA, &newKeyB, 15)) { return; } // Halt PICC mfrc522.PICC_HaltA(); // Stop encryption on PCD mfrc522.PCD_StopCrypto1(); } /** Helper routine to dump a byte array as hex values to Serial. */ 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); } } bool MIFARE_SetKeys(MFRC522::MIFARE_Key* oldKeyA, MFRC522::MIFARE_Key* oldKeyB, MFRC522::MIFARE_Key* newKeyA, MFRC522::MIFARE_Key* newKeyB, int sector) { MFRC522::StatusCode status; byte trailerBlock = sector * 4 + 3; byte buffer[18]; byte size = sizeof(buffer); // Authenticate using key A Serial.println(F("Authenticating using key A...")); status = (MFRC522::StatusCode)mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, oldKeyA, &(mfrc522.uid)); if (status != MFRC522::STATUS_OK) { Serial.print(F("PCD_Authenticate() failed: ")); Serial.println(mfrc522.GetStatusCodeName(status)); return false; } ``` -------------------------------- ### Signal Success with Blue LED Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl Flashes the blue LED three times to indicate a successful deletion from EEPROM. Ensure all LEDs are initially off before starting the sequence. ```arduino void successDelete() { digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off digitalWrite(redLed, LED_OFF); // Make sure red LED is off digitalWrite(greenLed, LED_OFF); // Make sure green LED is off delay(200); digitalWrite(blueLed, LED_ON); // Make sure blue LED is on delay(200); digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off delay(200); digitalWrite(blueLed, LED_ON); // Make sure blue LED is on delay(200); digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off delay(200); digitalWrite(blueLed, LED_ON); // Make sure blue LED is on delay(200); } ``` -------------------------------- ### Read Card ID from EEPROM Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl Reads a 4-byte card ID from EEPROM based on its number. The starting position is calculated based on the card number. ```C++ void readID( uint8_t number ) { uint8_t start = (number * 4 ) + 2; // Figure out starting position for ( uint8_t i = 0; i < 4; i++ ) { // Loop 4 times to get the 4 Bytes storedCard[i] = EEPROM.read(start + i); // Assign values read from EEPROM to array } } ``` -------------------------------- ### Set LEDs and Lock for Normal Operation Mode Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Configures LEDs and the door lock for normal operation. The blue LED is turned on, red and green LEDs are turned off, and the door is locked. ```cpp void normalModeOn () { digitalWrite(blueLed, LED_ON); // Blue LED ON and ready to read card digitalWrite(redLed, LED_ON); // Make sure Red LED is off digitalWrite(greenLed, LED_OFF); // Make sure Green LED is off digitalWrite(relay, HIGH); // Make sure Door is Locked } ``` -------------------------------- ### Read Master Card UID Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD This snippet reads the Master Card's Unique Identifier (UID) from EEPROM. The UID is stored starting from address 2. ```C++ for ( uint8_t i = 0; i < 4; i++ ) { // Read Master Card's UID from EEPROM masterCard[i] = EEPROM.read(2 + i); // Write it to masterCard // Serial.print(masterCard[i], HEX); } ``` -------------------------------- ### Get PICC's UID Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Reads the Unique Identifier (UID) from a new PICC (RFID card) placed on the reader. Assumes a 4-byte UID. Halts the card after reading. ```cpp uint8_t getID() { // Getting ready for Reading PICCs if ( ! mfrc522.PICC_IsNewCardPresent()) { // If a new PICC placed to RFID reader continue return 0; } if ( ! mfrc522.PICC_ReadCardSerial()) { // Since a PICC placed get Serial and continue return 0; } // There are Mifare PICCs which have 4 byte or 7 byte UID care if you use 7 byte PICC // I think we should assume every PICC as they have 4 byte UID // Until we support 7 byte PICCs // Serial.println(F("Scanned PICC's UID:")); for ( uint8_t i = 0; i < 4; i++) { // readCard[i] = mfrc522.uid.uidByte[i]; Serial.print(readCard[i], HEX); } Serial.println(""); mfrc522.PICC_HaltA(); // Stop reading return 1; } ``` -------------------------------- ### Hardware Definitions and LED Configuration Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl Defines pins for LEDs, relay, and button. Includes conditional compilation for common anode LEDs, setting ON/OFF states accordingly. ```c++ #define COMMON_ANODE #ifdef COMMON_ANODE #define LED_ON LOW #define LED_OFF HIGH #else #define LED_ON HIGH #define LED_OFF LOW #endif #define redLed 7 // Set Led Pins #define greenLed 6 #define blueLed 5 #define relay 4 // Set Relay Pin #define wipeB 3 // Button pin for WipeMode ``` -------------------------------- ### Access Control System Workflow Diagram Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD This diagram illustrates the workflow of the RFID-based door access control system, showing how tags are read, processed, and how access is granted or denied. It also depicts the master tag functionality for managing the EEPROM. ```text /* * -------------------------------------------------------------------------------------------------------------------- * Example sketch/program showing An Arduino Door Access Control featuring RFID, EEPROM, Relay * -------------------------------------------------------------------------------------------------------------------- * This is a MFRC522 library example; for further details and other examples see: https://github.com/miguelbalboa/rfid * * This example showing a complete Door Access Control System Simple Work Flow (not limited to) : +---------+ +----------------------------------->READ TAGS+^------------------------------------------+ | +--------------------+ | | | | | | | | | | +----v-----+ +-----v----+ | |MASTER TAG| |OTHER TAGS| | +--+-------+ ++-------------+ | | | | | | | | | +-----v---+ +----v----+ +----v------+ | +------------+READ TAGS+---+ |KNOWN TAG| |UNKNOWN TAG| | | +-+-------+ | +-----------+ +------------------+ | | | | | | | +----v-----+ +----v----+ +--v--------+ +-v----------+ +------v----+ | |MASTER TAG| |KNOWN TAG| |UNKNOWN TAG| |GRANT ACCESS| |DENY ACCESS| | +----------+ +---+-----+ +-----+-----+ +-----+------+ +-----+-----+ | | | | | | +----+ +----v------+ +--v---+ | |EXIT| |DELETE FROM| |ADD TO| | +----+ | EEPROM | |EEPROM| | +-----------+ +------+ ``` -------------------------------- ### Wipe EEPROM Functionality Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD This code snippet handles the EEPROM wiping process. It requires a button press for 15 seconds to initiate the wipe. If the button is released within this time, the operation is cancelled. A red LED indicates the wiping process. ```C++ //Wipe Code - If the Button (wipeB) Pressed while setup run (powered on) it wipes EEPROM if (digitalRead(wipeB) == LOW) { // when button pressed pin should get low, button connected to ground digitalWrite(redLed, LED_ON); // Red Led stays on to inform user we are going to wipe Serial.println(F("Wipe Button Pressed")); Serial.println(F("You have 15 seconds to Cancel")); Serial.println(F("This will be remove all records and cannot be undone")); delay(15000); // Give user enough time to cancel operation if (digitalRead(wipeB) == LOW) { // If button still be pressed, wipe EEPROM Serial.println(F("Starting Wiping EEPROM")); for (uint8_t x = 0; x < EEPROM.length(); x = x + 1) { //Loop end of EEPROM address if (EEPROM.read(x) == 0) { //If EEPROM address 0 // do nothing, already clear, go to the next address in order to save time and reduce writes to EEPROM } else { EEPROM.write(x, 0); // if not write 0 to clear, it takes 3.3mS } } Serial.println(F("EEPROM Successfully Wiped")); digitalWrite(redLed, LED_OFF); // visualize a successful wipe delay(200); digitalWrite(redLed, LED_ON); delay(200); digitalWrite(redLed, LED_OFF); delay(200); digitalWrite(redLed, LED_ON); delay(200); digitalWrite(redLed, LED_OFF); } else { Serial.println(F("Wiping Cancelled")); // Show some feedback that the wipe button did not pressed for 15 seconds digitalWrite(redLed, LED_OFF); } } ``` -------------------------------- ### Set LEDs for Programming Mode Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Sets the LEDs to indicate that the system is in programming mode: blue LED ON, red and green LEDs OFF. ```cpp void programLeds() { digitalWrite(blueLed, LED_ON); digitalWrite(redLed, LED_OFF); digitalWrite(greenLed, LED_OFF); } ``` -------------------------------- ### Placeholder Code Snippet Source: https://github.com/miguelbalboa/rfid/wiki/TEMPLATE-for-new-code-snippets This is a placeholder for a new code snippet. Add your code and relevant details here. ```c++ // add code here ``` -------------------------------- ### Indicate Successful EEPROM Write with Green LED Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Provides visual feedback for a successful EEPROM write operation by flashing the green LED three times. Ensures other LEDs are off. ```C++ void successWrite() { digitalWrite(blueLed, LED_OFF); digitalWrite(redLed, LED_OFF); digitalWrite(greenLed, LED_OFF); delay(200); digitalWrite(greenLed, LED_ON); delay(200); digitalWrite(greenLed, LED_OFF); delay(200); digitalWrite(greenLed, LED_ON); delay(200); digitalWrite(greenLed, LED_OFF); delay(200); digitalWrite(greenLed, LED_ON); delay(200); } ``` -------------------------------- ### MFRC522 RFID Reader Initialization Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl Defines the SPI pins for the MFRC522 module and creates an instance of the MFRC522 class. ```c++ // Create MFRC522 instance. #define SS_PIN 10 #define RST_PIN 9 MFRC522 mfrc522(SS_PIN, RST_PIN); ``` -------------------------------- ### Indicate Successful EEPROM Write Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl Flashes the green LED three times to visually confirm a successful EEPROM write operation. Ensures other LEDs are off before signaling. ```C++ void successWrite() { digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off digitalWrite(redLed, LED_OFF); // Make sure red LED is off digitalWrite(greenLed, LED_OFF); // Make sure green LED is on delay(200); digitalWrite(greenLed, LED_ON); // Make sure green LED is on delay(200); digitalWrite(greenLed, LED_OFF); // Make sure green LED is off delay(200); digitalWrite(greenLed, LED_ON); // Make sure green LED is on delay(200); digitalWrite(greenLed, LED_OFF); // Make sure green LED is off delay(200); digitalWrite(greenLed, LED_ON); // Make sure green LED is on delay(200); } ``` -------------------------------- ### Card and Mode Variables Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl Declares variables for program mode, read success status, and storage for card IDs (stored, read, and master). ```c++ bool programMode = false; // initialize programming mode to false uint8_t successRead; byte storedCard[4]; // Stores an ID read from EEPROM byte readCard[4]; // Stores scanned ID read from RFID Module byte masterCard[4]; // Stores master card's ID read from EEPROM ``` -------------------------------- ### Cycle LEDs for Program Mode Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Cycles through different LED states (red, blue) with a delay, typically used to indicate a programming or special mode. ```cpp void cycleLeds() { // digitalWrite(redLed, LED_OFF); // Make sure red LED is off // digitalWrite(greenLed, LED_OFF); // Make sure green LED is on Section commented out to never have green LED on unless door is unlocked // digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off // delay(200); digitalWrite(redLed, LED_OFF); // Make sure red LED is off digitalWrite(greenLed, LED_OFF); // Make sure green LED is off digitalWrite(blueLed, LED_ON); // Make sure blue LED is on delay(200); digitalWrite(redLed, LED_ON); // Make sure red LED is on digitalWrite(greenLed, LED_OFF); // Make sure green LED is off digitalWrite(blueLed, LED_ON); // Make sure blue LED is off delay(200); } ``` -------------------------------- ### Display MFRC522 Reader Details Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl Retrieves and prints the software version of the MFRC522 RFID reader. Includes a check for communication failure and halts the system if detected. ```C++ void ShowReaderDetails() { // Get the MFRC522 software version byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg); Serial.print(F("MFRC522 Software Version: 0x")); Serial.print(v, HEX); if (v == 0x91) Serial.print(F(" = v1.0")); else if (v == 0x92) Serial.print(F(" = v2.0")); else Serial.print(F(" (unknown),probably a chinese clone?")); Serial.println(""); // When 0x00 or 0xFF is returned, communication probably failed if ((v == 0x00) || (v == 0xFF)) { Serial.println(F("WARNING: Communication failure, is the MFRC522 properly connected?")); Serial.println(F("SYSTEM HALTED: Check connections.")); // Visualize system is halted digitalWrite(greenLed, LED_OFF); // Make sure green LED is off digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off digitalWrite(redLed, LED_ON); // Turn on red LED while (true); // do not go further } } ``` -------------------------------- ### Activate Normal Mode LED and Lock Door Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl Turns on the blue LED and ensures red and green LEDs are off. Also activates the relay to lock the door. ```C++ void normalModeOn () { digitalWrite(blueLed, LED_ON); // Blue LED ON and ready to read card digitalWrite(redLed, LED_OFF); // Make sure Red LED is off digitalWrite(greenLed, LED_OFF); // Make sure Green LED is off digitalWrite(relay, HIGH); // Make sure Door is Locked } ``` -------------------------------- ### Cycle LEDs for Program Mode Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl Cycles through Red, Green, and Blue LEDs with a delay, typically used to indicate a program or status mode. ```C++ void cycleLeds() { digitalWrite(redLed, LED_OFF); // Make sure red LED is off digitalWrite(greenLed, LED_ON); // Make sure green LED is on digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off delay(200); digitalWrite(redLed, LED_OFF); // Make sure red LED is off digitalWrite(greenLed, LED_OFF); // Make sure green LED is off digitalWrite(blueLed, LED_ON); // Make sure blue LED is on delay(200); digitalWrite(redLed, LED_ON); // Make sure red LED is on digitalWrite(greenLed, LED_OFF); // Make sure green LED is off digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off delay(200); } ``` -------------------------------- ### Main Loop - Wipe Button Check Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Within the main loop, this code checks if the wipe button is pressed. If pressed, it provides feedback and waits for 10 seconds. If the button remains pressed, it resets the master card definition in EEPROM. ```C++ void loop () { do { successRead = getID(); // sets successRead to 1 when we get read from reader otherwise 0 // When device is in use if wipe button pressed for 10 seconds initialize Master Card wiping if (digitalRead(wipeB) == LOW) { // Check if button is pressed // Visualize normal operation is iterrupted by pressing wipe button Red is like more Warning to user digitalWrite(redLed, LED_ON); // Make sure led is off digitalWrite(greenLed, LED_OFF); // Make sure led is off digitalWrite(blueLed, LED_OFF); // Make sure led is off // Give some feedback Serial.println(F("Wipe Button Pressed")); Serial.println(F("Master Card will be Erased! in 10 seconds")); delay(10000); // Wait 10 seconds to see user still wants to wipe if (digitalRead(wipeB) == LOW) { EEPROM.write(1, 0); // Reset Magic Number. } } } while (!successRead); } ``` -------------------------------- ### Include Libraries for RFID Access Control Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Includes necessary libraries for EEPROM, SPI communication, the MFRC522 RFID reader, and the LiquidCrystal display. ```cpp #include #include #include #include ``` -------------------------------- ### LED and Relay Pin Definitions Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Defines the Arduino pins for status LEDs (red, green, blue) and the relay controlling the door lock. Includes definitions for common anode or cathode LEDs. ```cpp #define redLed 27 // Set Red LED pin #define greenLed 29 // Set Green LED pin #define blueLed 25 // Set Blue LED pin #define relay 5 // Set MOSFET Pin #define wipeB 6 // Button pin for WipeMode ``` -------------------------------- ### Check Two Byte Arrays for Equality Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Compares two byte arrays of length 4 to determine if they are identical. Returns true if they match, false otherwise. Ensures the first array is not empty before comparison. ```C++ boolean checkTwo ( byte a[], byte b[] ) { if ( a[0] != 0 ) // Make sure there is something in the array first match = true; for ( uint8_t k = 0; k < 4; k++ ) { // Loop 4 times if ( a[k] != b[k] ) // IF a != b then set match = false, one fails, all fail match = false; } if ( match ) { return true; } else { return false; } } ``` -------------------------------- ### Indicate Failed EEPROM Write Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl Flashes the red LED three times to visually indicate a failed EEPROM write operation. Ensures other LEDs are off before signaling. ```C++ void failedWrite() { digitalWrite(blueLed, LED_OFF); // Make sure blue LED is off digitalWrite(redLed, LED_OFF); // Make sure red LED is off digitalWrite(greenLed, LED_OFF); // Make sure green LED is off delay(200); digitalWrite(redLed, LED_ON); // Make sure red LED is on delay(200); digitalWrite(redLed, LED_OFF); // Make sure red LED is off delay(200); digitalWrite(redLed, LED_ON); // Make sure red LED is on delay(200); digitalWrite(redLed, LED_OFF); // Make sure red LED is off delay(200); digitalWrite(redLed, LED_ON); // Make sure red LED is on delay(200); } ``` -------------------------------- ### Write Default User Pages for NTAG 213/216 Source: https://github.com/miguelbalboa/rfid/wiki/Tag-NTAG-213-216 This function writes factory default data to pages 4 and 5 of NTAG 213 or NTAG 216 tags. It uses conditional compilation based on CARD_TYPE to set the appropriate data for each tag type. Ensure NTAG_PAGELENGTH is defined as 4. ```cpp int NTAGWriteDefaultUserPages() { int status = 0; byte page4[NTAG_PAGELENGTH]; byte page5[NTAG_PAGELENGTH]; #if (CARD_TYPE == 203) page4[0] = 0x01; page4[1] = 0x03; page4[2] = 0xA0; page4[3] = 0x0C; page5[0] = 0x34; page5[1] = 0x03; page5[2] = 0x00; page5[3] = 0xFE; #endif #if (CARD_TYPE == 206) page4[0] = 0x03; page4[1] = 0x00; page4[2] = 0xFE; page4[3] = 0x00; page5[0] = 0x00; page5[1] = 0x00; page5[2] = 0x00; page5[3] = 0x00; #endif status += mfrc522.MIFARE_Ultralight_Write(4, page4, NTAG_PAGELENGTH); status += mfrc522.MIFARE_Ultralight_Write(5, page5, NTAG_PAGELENGTH); return status; } ``` -------------------------------- ### Wipe EEPROM on Button Press Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl This code wipes the EEPROM when the wipe button is pressed during system startup. It provides a 10-second window to cancel the operation. Ensure the wipe button is connected to ground. ```cpp //Wipe Code - If the Button (wipeB) Pressed while setup run (powered on) it wipes EEPROM if (digitalRead(wipeB) == LOW) { // when button pressed pin should get low, button connected to ground digitalWrite(redLed, LED_ON); // Red Led stays on to inform user we are going to wipe Serial.println(F("Wipe Button Pressed")); Serial.println(F("You have 10 seconds to Cancel")); Serial.println(F("This will be remove all records and cannot be undone")); bool buttonState = monitorWipeButton(10000); // Give user enough time to cancel operation if (buttonState == true && digitalRead(wipeB) == LOW) { // If button still be pressed, wipe EEPROM Serial.println(F("Starting Wiping EEPROM")); for (uint16_t x = 0; x < EEPROM.length(); x = x + 1) { //Loop end of EEPROM address if (EEPROM.read(x) == 0) { //If EEPROM address 0 // do nothing, already clear, go to the next address in order to save time and reduce writes to EEPROM } else { EEPROM.write(x, 0); // if not write 0 to clear, it takes 3.3mS } } Serial.println(F("EEPROM Successfully Wiped")); digitalWrite(redLed, LED_OFF); // visualize a successful wipe delay(200); digitalWrite(redLed, LED_ON); delay(200); digitalWrite(redLed, LED_OFF); delay(200); digitalWrite(redLed, LED_ON); delay(200); digitalWrite(redLed, LED_OFF); } else { Serial.println(F("Wiping Cancelled")); // Show some feedback that the wipe button did not pressed for 15 seconds digitalWrite(redLed, LED_OFF); } } ``` -------------------------------- ### Read and Save MIFARE Ultralight Card Data Source: https://github.com/miguelbalboa/rfid/wiki/Useful-code-snippets This snippet reads data from a MIFARE Ultralight card and stores it in a 2D array. It includes functions to reset the array, read card information page by page, and display the stored data. ```c++ byte Card[16][4]; // fills the "Card[16][4]" with 0s void ResetInfo(){ for (int i=0; i<=15; i++){ for (int j=0; j<=4; j++){ Card[i][j]=0; } } } // fills the "Card[16][4]" with data void ReadInfo() { ResetInfo(); MFRC522::StatusCode status; byte buffer[18]; // 16 (data) + 2 (CRC) for (byte page=0; page<=15; page+=4){ byte byteCount = sizeof(buffer); status=NFC.MIFARE_Read(page,buffer,&byteCount); if (status != NFC.STATUS_OK) { Serial.print(F("MIFARE_Read() failed: ")); Serial.println(NFC.GetStatusCodeName(status)); return; } // [page][index] // 0-15 0-3 // Card [16] [4] // // 0-3 page 0 // 4-7 page 1 // 8-11 page 2 // 12-15 page 3 // buffer[16+2] int i_=0; for (int i=page; i<=page+3; i++){ for (int j=0; j<=3; j++){ Card[i][j]=buffer[4*i_ + j]; } i_++; } } // This is to stop the card from sending the info over and over again NFC.PICC_HaltA(); } // shows the "Card[16][4]" after filling it void ShowInfo(){ ReadInfo(); Serial.println("--------------------------"); for (int i=0; i<16; i++){ for (int j=0; j<4; j++){ Serial.print(Card[i][j],HEX); Serial.print(" "); } Serial.println(); } Serial.println("--------------------------"); } ``` -------------------------------- ### Access Denied Function Source: https://github.com/miguelbalboa/rfid/wiki/[Example]-AccessControl-with-LCD Handles the 'Access Denied' state. It turns on the red LED, keeps the blue LED on, and waits for 5 seconds before resetting the Arduino. This function is called when an unrecognized RFID card is scanned in normal mode. ```cpp void denied() { digitalWrite(greenLed, LED_OFF); // Make sure green LED is off digitalWrite(blueLed, LED_ON); // Blue Power LED stays on digitalWrite(redLed, LED_ON); // Turn on red LED delay(5000); // Wait 5 seconds before resetting Arduino resetFunc(); // Reset Arduino to keep from locking up } ```