Build an Arduino RFID Door Lock System ๐(RC522 + Solenoid Lock)
Security systems are becoming an essential part of modern homes and offices. Instead of traditional keys, RFID technology offers a simple and secure way to control access.
So letโs build a complete RFID door lock system using Arduino, an RC522 RFID reader, and a solenoid door lock. This system allows access only to authorized RFID cards and provides visual and audio feedback using LEDs, a buzzer, and an LCD.
๐งฐ Components Youโll Need
I highly recommend getting aย complete starter kitย that includes everything you need to create a wide range of projects.

| Component | Quantity |
|---|---|
| Arduino Uno/Nano | 1 |
| RC522 RFID Module | 1 |
| 13.56MHz RFID Tags/Cards | 1+ |
| Solenoid Lock (12V) | 1 |
| Relay Module (5V or 12V) | 1 |
| 16ร2 LCD with I2C backpack | 1 |
| Red LED | 1 |
| Green LED | 1 |
| Buzzer (5V) | 1 |
| 220ฮฉ resistors | 2 |
| 12V power supply (for solenoid) | 1 |
| Jumper wires & breadboard | as needed |
Note: The solenoid lock draws more current than an Arduino pin can supply. Always use aย relay moduleย to control it safely.
๐ Wiring Diagrams (Pin Connections)
RC522 โ Arduino

| RC522 Pin | Arduino Pin |
|---|---|
| SDA (SS) | 10 |
| SCK | 13 |
| MOSI | 11 |
| MISO | 12 |
| RST | 9 |
| 3.3V | 3.3V |
| GND | GND |
LCD (I2C)โ Arduino

Other Components

All LEDs and buzzer negatives go toย GND.
๐ป The Complete Arduino Code
This is the exact code Iโm running on my system, which includes:
- RFID authentication
- Solenoid control
- LCD messages
- LED + buzzer feedback
//Arduino Door Lock Access Control Project
//Library: MFRC522, https://github.com/miguelbalboa/rfid
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>
#define SS_PIN 10
#define RST_PIN 9
// Instance of the class MFRC522
MFRC522 rfid(SS_PIN, RST_PIN);
// Create LCD object : Use 0x27 If 0x3F Doesn't work
LiquidCrystal_I2C lcd(0x3F, 16, 2);
// Init array that will store new NUID
byte nuidPICC[4];
// Put Your access NUID Here
byte master[4] = {0x49, 0xA1, 0xDE, 0x6E};
// Pin connected to lock relay signal
int lockOutput = 2;
int greenLED = 3;
int redLED = 4;
int buzzerPin = 5;
void setup() {
SPI.begin(); // Init SPI bus
rfid.PCD_Init(); // Init MFRC522
// Setup LCD with backlight and initialize
lcd.init();
lcd.backlight();
printWelcomeMessage();
// Set OUTPUT pins
pinMode(lockOutput, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(buzzerPin, OUTPUT);
}
void loop() {
// Reset the loop if no new card present on the sensor/reader
if ( ! rfid.PICC_IsNewCardPresent())
return;
// Verify if the NUID has been readed
if ( ! rfid.PICC_ReadCardSerial())
return;
// Store NUID into nuidPICC array
for (byte i = 0; i < 4; i++) {
nuidPICC[i] = rfid.uid.uidByte[i];
}
// Checks whether the scanned tag is authorized
if (getAccessState(master, nuidPICC) == true) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Access Granted!");
// Turn on relay & green LED for 5 seconds
digitalWrite(lockOutput, HIGH);
digitalWrite(greenLED, HIGH);
delay(4000);
digitalWrite(lockOutput, LOW);
digitalWrite(greenLED, LOW);
delay(25); //To fix (LCD, Solenoid) issue
printWelcomeMessage();
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" Access Denied!");
digitalWrite(redLED, HIGH);
digitalWrite(buzzerPin, HIGH);
delay(1000);
digitalWrite(redLED, LOW);
digitalWrite(buzzerPin, LOW);
printWelcomeMessage();
}
// Halt PICC
rfid.PICC_HaltA();
// Stop encryption on PCD
rfid.PCD_StopCrypto1();
}
bool getAccessState(byte accessCode[], byte newCode[]) {
for (byte i = 0; i < 4; i++) {
if (newCode[i] != accessCode[i]) {
return false;
}
}
return true;
}
void printWelcomeMessage() {
lcd.clear();
lcd.print("<Access Control>");
lcd.setCursor(0, 1);
lcd.print(" Scan Your Tag!");
}
๐ Step 1: Install Required Libraries
First, make sure to install these 2 libraries from the Arduino Library Manager:
- MFRC522 by Github Comunityโ To read and write RFID cards/tags
- LiquidCrystal_I2C Library โ controls the LCD through the I2C interface.
๐ Step 2: Get Your RFID Tag UID
Next, you need to get your tagโs unique UID using the RFID reader. By opening an example sketch using the installed library:
Head over to File > Examples > MFRC522 > DumpInfo

Or copy this sketch to your Arduino IDE. It will read any tag you scan and show you its unique ID.
#include <SPI.h>
#include <MFRC522.h>
#define RST_PIN 9
#define SS_PIN 10
MFRC522 mfrc522(SS_PIN, RST_PIN);
void setup() {
Serial.begin(9600);
while (!Serial);
SPI.begin();
mfrc522.PCD_Init();
delay(4);
mfrc522.PCD_DumpVersionToSerial();
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}
void loop() {
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
if ( ! mfrc522.PICC_ReadCardSerial()) {
return;
}
mfrc522.PICC_DumpToSerial(&(mfrc522.uid));
} - Uploadย the Dump Info sketch to your Arduino
- Openย the Serial Monitor (Tools โ Serial Monitor orย
Ctrl+Shift+M) - Setย the baud rate toย 9600
- Scanย your RFID tag/card on the RC522 reader
- Copyย the UID that appears โ it will look something like:

โ๏ธ Step 3: Update Your Main Door Lock Code
Now take that UID and replace theย masterย array in your original door lock code:
// Put Your access NUID Here
byte master[4] = {0x49, 0xA1, 0xDE, 0x6E}; Once updated, you can upload the sketch to the Arduino board and start testing:



๐งช Testing & Troubleshooting
LCD shows nothing?
- Try changing the I2C address fromย
0x3Fย toย0x27ย in this line: LiquidCrystal_I2C lcd(0x3F, 16, 2); - Or run an I2C scanner sketch to find your LCDโs real address.
Solenoid not moving?
- The solenoid lock needs enough current (often 1โ2A).
- Check your relay wiring โ common mistake.
- Make sure the relayโsย VCCย is connected to an external 12V supply, not the Arduinoโs 5V.
๐ง Complete Code Explanation:
In this section, weโll break down how the Arduino code works to control the RFID door lock system.
๐น 1. Including Required Libraries
#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>
- SPI.h โ Enables communication between Arduino and the RFID module
- MFRC522.h โ Controls the RFID reader
- LiquidCrystal_I2C.h โ Manages the LCD using I2C
๐น 2. Defining Pins and Initializing Modules
#define SS_PIN 10
#define RST_PIN 9MFRC522 rfid(SS_PIN, RST_PIN);
LiquidCrystal_I2C lcd(0x3F, 16, 2);
SS_PINandRST_PINare used for RFID communicationrfidThe object initializes the RFID readerlcdThe object initializes the 16ร2 LCD
๐น 3. Storing Authorized RFID Card UID
// Put Your access NUID Here
byte master[4] = {0x49, 0xA1, 0xDE, 0x6E};
- This array stores the UID of the authorized card
- Only this card can unlock the door
- You can replace it with your own cardโs UID
๐ก You can also extend the code to storeย multiple authorized tagsย using an array of arrays.
๐น 4. Defining Output Components
// Pin connected to lock relay signal
int lockOutput = 2;
int greenLED = 3;
int redLED = 4;
int buzzerPin = 5;
These pins control:
- Relay (door lock)
- Status LEDs
- Buzzer for alerts
๐น 5. Setup Function
void setup() {
SPI.begin();
rfid.PCD_Init(); lcd.init();
lcd.backlight();
printWelcomeMessage(); pinMode(lockOutput, OUTPUT);
pinMode(greenLED, OUTPUT);
pinMode(redLED, OUTPUT);
pinMode(buzzerPin, OUTPUT);
} - Initializes RFID and SPI communication
- Starts the LCD and turns on the backlight
- Displays a welcome message
- And sets all output pins
๐น 6. Main Loop โ Detecting RFID Cards
// Reset the loop if no new card present on the sensor/reader
if ( ! rfid.PICC_IsNewCardPresent())
return;
// Verify if the NUID has been readed
if ( ! rfid.PICC_ReadCardSerial())
return;
This waits until a card is placed near the reader.
๐น 7. Storing the Scanned UID
// Store NUID into nuidPICC array
for (byte i = 0; i < 4; i++) {
nuidPICC[i] = rfid.uid.uidByte[i];
}
- Copies the scanned UID into an array
- This will be compared with the authorized UID
๐น 8. Checking Access Permission
if (getAccessState(master, nuidPICC))
- This calls a function to compare both UIDs
- And returns
trueIf they match
๐น 9. Access Granted Logic
// Turn on relay & green LED for 5 seconds
digitalWrite(lockOutput, HIGH);
digitalWrite(greenLED, HIGH);
delay(4000);
digitalWrite(lockOutput, LOW);
digitalWrite(greenLED, LOW);
When access is granted:
- Relay activates โ door unlocks
- Green LED turns ON
- The door stays open for 4 seconds
- Then everything turns OFF
๐น 10. Access Denied Logic
digitalWrite(redLED, HIGH);
digitalWrite(buzzerPin, HIGH);
delay(1000);
digitalWrite(redLED, LOW);
digitalWrite(buzzerPin, LOW);
If access is denied:
- Red LED turns ON
- The buzzer sounds an alarm
- Lasts for 1 second
๐น 11. UID Comparison Function
bool getAccessState(byte accessCode[], byte newCode[]) {
for (byte i = 0; i < 4; i++) {
if (newCode[i] != accessCode[i]) {
return false;
}
}
return true;
} Here we compare each byte of the UID; if all match โ access is granted, otherwise โ access is denied.
๐น 12. LCD Welcome Message Function
void printWelcomeMessage() {
lcd.clear();
lcd.print("<Access Control>");
lcd.setCursor(0, 1);
lcd.print(" Scan Your Tag!");
} This function displays the default message on the LCD, which guides the user to scan their card.
