ESP8266 - RFID Door Lock

This tutorial instructs you how to build a door lock system using ESP8266, RFID/NFC RC522 module, a relay, solenoid lock or electromagnetic lock, and optionally LCD. To make it easy for you, the tutorial instructs you to build the RFID door lock from simple to complex steps. In detail, we will do:

ESP8266 NodeMCU rfid door lock

If you want to build door lock system using password, please refer to ESP8266 - Keypad Door Lock.

Hardware Preparation

1×ESP8266 NodeMCU
1×Micro USB Cable
1×RFID/NFC RC522 Kit (reader + tags)
1×RFID Key Fob
1×Solenoid Lock
1×(Alternative) Electromagnetic Lock
1×Relay
1×12V Power Adapter
1×DC Power Jack
1×Jumper Wires
1×(Optional) 5V Power Adapter for ESP8266
1×(Optional) ESP8266 Screw Terminal Adapter

Or you can buy the following sensor kit:

1×DIYables Sensor Kit 30 types, 69 units
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you. We appreciate your support.

Overview of RFID/NFC RC522 Module and Electromagnetic Lock

If you are unfamiliar with the RFID/NFC RC522 Module, electromagnetic lock, solenoid lock (including pinout, how it works, and how to program), then you can learn more by following these tutorials:

Door Lock System Components

The door lock system comprises two primary components:

  • Door Lock: an ESP8266, a relay, a RFID/NFC reader, a solenoid lock or an electromagnetic lock
  • Door Key: RFID/NFC tags
ESP8266 NodeMCU rfid door lock component

How RFID/NFC Door Lock Works

  • The user taps an RFID/NFC tag on the RFID/NFC reader, which reads the UID from the tag.
  • ESP8266 then gets the UID from the reader and compares it with the UIDs that have been set in the code.
  • If the UID matches one of the predefined UIDs, ESP8266 will deactivate the solenoid lock, thus unlocking the door.
  • These tags act as the authorized keys.
  • The relay will be activated by ESP8266 to lock the door after a specific period of time.

Wiring Diagram

  • RFID RC522 Door Lock with Solenoid Lock
The wiring diagram between ESP8266 NodeMCU and RFID RC522 Door soleniod lock

This image is created using Fritzing. Click to enlarge image

See more in ESP8266's pinout and how to supply power to the ESP8266 and other components.

  • RFID RC522 Door Lock with Electromagnetic Lock
The wiring diagram between ESP8266 NodeMCU and RFID RC522 Door Lock System

This image is created using Fritzing. Click to enlarge image

※ NOTE THAT:

Manufacturers may arrange the order of pins differently, so it is important to rely on the labels printed on the module. The pinout diagram depicted above displays the pin arrangement for modules produced by the manufacturer DIYables.

ESP8266 Code - Single Key

/* * This ESP8266 NodeMCU code was developed by newbiely.com * * This ESP8266 NodeMCU code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp8266/esp8266-rfid-door-lock */ #include <SPI.h> #include <MFRC522.h> #define SS_PIN D8 // The ESP8266 pin D8 #define RST_PIN D2 // The ESP8266 pin D2 #define RELAY_PIN D1 // The ESP8266 pin connects to relay MFRC522 rfid(SS_PIN, RST_PIN); byte keyTagUID[4] = {0xFF, 0xFF, 0xFF, 0xFF}; void setup() { Serial.begin(9600); SPI.begin(); // init SPI bus rfid.PCD_Init(); // init MFRC522 pinMode(RELAY_PIN, OUTPUT); // initialize pin as an output. digitalWrite(RELAY_PIN, HIGH); // lock the door Serial.println("Tap an RFID/NFC tag on the RFID-RC522 reader"); } void loop() { if (rfid.PICC_IsNewCardPresent()) { // new tag is available if (rfid.PICC_ReadCardSerial()) { // NUID has been readed MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak); if (rfid.uid.uidByte[0] == keyTagUID[0] && rfid.uid.uidByte[1] == keyTagUID[1] && rfid.uid.uidByte[2] == keyTagUID[2] && rfid.uid.uidByte[3] == keyTagUID[3] ) { Serial.println("Access is granted"); digitalWrite(RELAY_PIN, LOW); // unlock the door for 2 seconds delay(2000); digitalWrite(RELAY_PIN, HIGH); // lock the door } else { Serial.print("Access denied, UID:"); for (int i = 0; i < rfid.uid.size; i++) { Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " "); Serial.print(rfid.uid.uidByte[i], HEX); } Serial.println(); } rfid.PICC_HaltA(); // halt PICC rfid.PCD_StopCrypto1(); // stop encryption on PCD } } }

Detailed Instructions

To get started with ESP8266 on Arduino IDE, follow these steps:

  • Check out the how to setup environment for ESP8266 on Arduino IDE tutorial if this is your first time using ESP8266.
  • Wire the components as shown in the diagram.
  • Connect the ESP8266 board to your computer using a USB cable.
  • Open Arduino IDE on your computer.
  • Choose the correct ESP8266 board, such as (e.g. NodeMCU 1.0 (ESP-12E Module)), and its respective COM port.

In order to determine the UID of an RFID/NFC tag:

  • Upload code to ESP8266 and open Serial Monitor.
  • Tap the tag on the RFID-RC522 module and the UID will be displayed on the Serial Monitor.
COM6
Send
Tap RFID/NFC tag on reader Access denied for user with UID: 3A C9 6A CB
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

Once you have the UID:

  • Alter line 18 of the code above to reflect the UID. For example, replace byte keytagUID[4] = {0xFF, 0xFF, 0xFF, 0xFF}; with byte keytagUID[4] = {0x3A, 0xC9, 0x6A, 0xCB};
  • Upload the modified code to the ESP8266
  • Place an RFID/NFC tag on the RFID-RC522 module
  • Check the output on the Serial Monitor
COM6
Send
Tap RFID/NFC tag on reader Access is granted
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • Verify that the electromagnetic lock is not locked.
  • Tap a different RFID/NFC tag on the RFID-RC522 module.
  • Check out the output on the Serial Monitor.
COM6
Send
Tap RFID/NFC tag on reader Access is granted Access denied for user with UID: BD 1E 1D 22
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

※ NOTE THAT:

  • To facilitate testing, the unlocked time has been set to 2 seconds; however, it should be increased for practical use/demonstration.
  • Installation of the MFRC522 library is necessary. For more information, please refer to the ESP8266 - RFID/NFC RC522 tutorial.

ESP8266 Code - Multiple Keys

Let us envision a room in which only the manager and secretary can gain access.

In this instance, two RFID/NFC tags are required: one for the manager and the other for the secretary. The UIDs of the two tags must be specified in the code.

/* * This ESP8266 NodeMCU code was developed by newbiely.com * * This ESP8266 NodeMCU code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp8266/esp8266-rfid-door-lock */ #include <SPI.h> #include <MFRC522.h> #define SS_PIN D8 // The ESP8266 pin D8 #define RST_PIN D2 // The ESP8266 pin D2 #define RELAY_PIN D1 // The ESP8266 pin connects to relay MFRC522 rfid(SS_PIN, RST_PIN); byte managerKeyUID[4] = {0x3A, 0xC9, 0x6A, 0xCB}; byte secretaryKeyUID[4] = {0x30, 0x01, 0x8B, 0x15}; void setup() { Serial.begin(9600); SPI.begin(); // init SPI bus rfid.PCD_Init(); // init MFRC522 pinMode(RELAY_PIN, OUTPUT); // initialize pin as an output. digitalWrite(RELAY_PIN, HIGH); // lock the door Serial.println("Tap an RFID/NFC tag on the RFID-RC522 reader"); } void loop() { if (rfid.PICC_IsNewCardPresent()) { // new tag is available if (rfid.PICC_ReadCardSerial()) { // NUID has been readed MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak); if (rfid.uid.uidByte[0] == managerKeyUID[0] && rfid.uid.uidByte[1] == managerKeyUID[1] && rfid.uid.uidByte[2] == managerKeyUID[2] && rfid.uid.uidByte[3] == managerKeyUID[3] ) { Serial.println("The access is granted to manager"); digitalWrite(RELAY_PIN, LOW); // unlock the door for 2 seconds delay(2000); digitalWrite(RELAY_PIN, HIGH); // lock the door } else if (rfid.uid.uidByte[0] == secretaryKeyUID[0] && rfid.uid.uidByte[1] == secretaryKeyUID[1] && rfid.uid.uidByte[2] == secretaryKeyUID[2] && rfid.uid.uidByte[3] == secretaryKeyUID[3] ) { Serial.println("The access is granted to secretary"); digitalWrite(RELAY_PIN, LOW); // unlock the door for 2 seconds delay(2000); digitalWrite(RELAY_PIN, HIGH); // lock the door } else { Serial.print("Access denied, UID:"); for (int i = 0; i < rfid.uid.size; i++) { Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " "); Serial.print(rfid.uid.uidByte[i], HEX); } Serial.println(); } rfid.PICC_HaltA(); // halt PICC rfid.PCD_StopCrypto1(); // stop encryption on PCD } } }

Repeat the same steps as before, and then tap each tag on the RFID-RC522 module. The output on the Serial Monitor should appear as follows:

COM6
Send
Tap RFID/NFC tag on reader Access is granted for secretary Access is granted for manager
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

You can expand the code written above to include three, four, or more tags.

Adding LCD Display to the RFID Door Lock

We can optionally add a LCD display to show the access status (e.g. GRANTED/DENIED) to users. You can learn more about LCD in ESP8266 - LCD tutorial

Wiring diagram - Door lock system using RFID, solenoid lock or electromagnetic lock, and LCD display

The wiring diagram between ESP8266 NodeMCU and RFID RC522 door lock LCD

This image is created using Fritzing. Click to enlarge image

Please note that in the wiring diagram above, 5V power is added because the 5V pin of the ESP8266 cannot supply enough power for both the relay and LCD simultaneously.

ESP8266 Code - Door lock system with password using RFID RC522 module, solenoid lock or electromagnetic lock, and LCD display

/* * This ESP8266 NodeMCU code was developed by newbiely.com * * This ESP8266 NodeMCU code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp8266/esp8266-rfid-door-lock */ #include <SPI.h> #include <MFRC522.h> #include <LiquidCrystal_I2C.h> #define SS_PIN D8 // The ESP8266 pin D8 #define RST_PIN D4 // The ESP8266 pin D4 #define RELAY_PIN D3 // The ESP8266 pin connects to relay MFRC522 rfid(SS_PIN, RST_PIN); LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C address 0x27 (from DIYables LCD), 16 column and 2 rows byte managerKeyUID[4] = {0x3A, 0xC9, 0x6A, 0xCB}; byte secretaryKeyUID[4] = {0x30, 0x01, 0x8B, 0x15}; void setup() { Serial.begin(9600); SPI.begin(); // init SPI bus rfid.PCD_Init(); // init MFRC522 pinMode(RELAY_PIN, OUTPUT); // initialize pin as an output. digitalWrite(RELAY_PIN, HIGH); // lock the door lcd.init(); // Initialize the LCD I2C display lcd.backlight(); Serial.println("Tap RFID/NFC Tag on reader"); } void loop() { if (rfid.PICC_IsNewCardPresent()) { // new tag is available if (rfid.PICC_ReadCardSerial()) { // NUID has been readed MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak); if (rfid.uid.uidByte[0] == managerKeyUID[0] && rfid.uid.uidByte[1] == managerKeyUID[1] && rfid.uid.uidByte[2] == managerKeyUID[2] && rfid.uid.uidByte[3] == managerKeyUID[3] ) { Serial.println("Access is granted for manager"); digitalWrite(RELAY_PIN, LOW); // unlock the door for 2 seconds lcd.clear(); lcd.setCursor(0, 0); lcd.print("CORRECT!"); lcd.setCursor(0, 1); lcd.print("DOOR UNLOCKED!"); delay(2000); digitalWrite(RELAY_PIN, HIGH); // lock the door lcd.clear(); } else if (rfid.uid.uidByte[0] == secretaryKeyUID[0] && rfid.uid.uidByte[1] == secretaryKeyUID[1] && rfid.uid.uidByte[2] == secretaryKeyUID[2] && rfid.uid.uidByte[3] == secretaryKeyUID[3] ) { Serial.println("Access is granted for secretary"); digitalWrite(RELAY_PIN, LOW); // unlock the door for 2 seconds lcd.clear(); lcd.setCursor(0, 0); lcd.print("CORRECT!"); lcd.setCursor(0, 1); lcd.print("DOOR UNLOCKED!"); delay(2000); digitalWrite(RELAY_PIN, HIGH); // lock the door lcd.clear(); } else { Serial.print("Access denied for user with UID:"); lcd.clear(); lcd.setCursor(0, 0); lcd.print("INCORRECT!"); lcd.setCursor(0, 1); lcd.print("ACCESS DENIED!"); for (int i = 0; i < rfid.uid.size; i++) { Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " "); Serial.print(rfid.uid.uidByte[i], HEX); } Serial.println(); } rfid.PICC_HaltA(); // halt PICC rfid.PCD_StopCrypto1(); // stop encryption on PCD } } }

※ NOTE THAT:

The address of the LCD can differ depending on the manufacturer. We used 0x27 in our code, as specified by DIYables.

Adding a door sensor to the RFID door lock

In the previously mentioned code, the ESP8266 locks the door after a timeout since unlocking. However, in practical applications, a door sensor is usually added to the system. If the ESP8266 detects that the door is closed, it locks the door immediately instead of waiting for the timeout.

To avoid overwhelming you, we didn't include the door sensor in the wiring diagram and code. Instead, we're leaving this part up to your creativity. You can check out the ESP8266 - Door Sensor and ESP8266 - Door Sensor control Relay tutorials for more guidance.

Managing and storing the valid RFID keys to EEPROM

The above code has valid RFID keys (UID) that are hardcoded into the ESP8266 code. This means that if you want to add or remove keys, you have to make changes to the code and upload it to the ESP8266 again, which is inconvenient.

In real-life applications, it's necessary to manage RFID keys without having to modify and upload the code every time. To achieve this, the RFID keys can be stored in EEPROM instead of being hardcoded. Consequently, a method is needed to easily manage the RFID keys from the EEPROM.

Two methods are available for managing RFID keys in EEPROM:

  • RFID keys as master keys
    • By utilizing a RFID key as an ADD master key, new keys can be added to the system. Once the ESP8266 detects the ADD master key, it switches between the ADD mode and OPERATION mode.
    • During the ADD mode, the ESP8266 adds any new keys it detects to the EEPROM.
    • A similar approach is used for DELETE master key and DELETE mode.
  • Use a ADD/DELETE commands via Serial/Bluetooth/IR
    • Commands are transmitted via Serial/Bluetooth/IR, utilizing tools such as the Serial Monitor, Bluetooth app, or IR controller.
    • The commands consist of a directive (ADD/DELETE) and the UID of the RFID key.
    • In order to improve security, a password should also be included with the command. The ESP8266 verifies the password to determine if the command is valid or not.

    In order to utilize any of two above methods, a considerable amount of ESP8266 code must be added. For individuals who are new to programming, this can be a challenging task. As a result, this tutorial aims to provide a basic understanding of the door lock system without overwhelming beginners with complex code. If you wish to implement this system for practical purposes, please contact us through our paid programming service

Storing the access history to SD Card

To keep track of access history, it might be necessary to save the UID of the RFID key, access status (GRANTED/DENIED), and date and time. Since EEPROM has insufficient capacity to store the entire history, an SD card can be used instead. You can find guidance on this ESP8266 - Log Data with Timestamp to SD Card tutorial.

Video Tutorial