Article
RFID door lock with Arduino and RC522: unlock only for the right card
🔐
An RFID door lock is a great entry point into hardware security projects: cheap, easy to understand, and satisfying fast — one evening in, you’ll be tapping a card to open a cabinet, a storage box, or a small room door.
How it works
- The RC522 module broadcasts a 13.56MHz RFID field and reads the UID (a unique identifier) of any card or keyfob held near it.
- The Arduino receives the UID over SPI and compares it against an allow-list stored in code.
- On a match, the Arduino turns a servo to release the lock for a few seconds and then re-locks, while lighting a green LED / buzzer for “accepted”.
- On a mismatch, a red LED flashes for “denied”.
Parts list
- Arduino Uno (or Nano)
- RC522 RFID reader module (SPI interface)
- 13.56MHz RFID card/keyfob (Mifare Classic is the most common type)
- SG90 servo attached to a mechanical latch (or a 12V solenoid lock driven through a relay if you need more holding force)
- 2 LEDs (green, red) + a small buzzer for feedback
- The
MFRC522library (install via the Arduino IDE Library Manager)
Sample code
Step 1: read a card’s UID so you know what value to add to the allow-list.
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 rfid(SS_PIN, RST_PIN);
void setup() {
Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
Serial.println("Hold a card near the reader to read its UID...");
}
void loop() {
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;
Serial.print("UID: ");
for (byte 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();
}
Step 2: the actual door lock with an allow-list of UIDs.
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
#define SS_PIN 10
#define RST_PIN 9
#define GREEN_LED 6
#define RED_LED 5
#define BUZZER 4
#define SERVO_PIN 3
MFRC522 rfid(SS_PIN, RST_PIN);
Servo lockServo;
// Allow-list of UIDs (uppercase, no spaces)
String allowedUids[] = {
"A1B2C3D4",
"1A2B3C4D"
};
const int NUM_CARDS = 2;
void unlockDoor() {
digitalWrite(GREEN_LED, HIGH);
tone(BUZZER, 1000, 200);
lockServo.write(90); // unlocked position
delay(4000);
lockServo.write(0); // locked position
digitalWrite(GREEN_LED, LOW);
}
void denyAccess() {
for (int i = 0; i < 3; i++) {
digitalWrite(RED_LED, HIGH);
tone(BUZZER, 300, 100);
delay(150);
digitalWrite(RED_LED, LOW);
delay(150);
}
}
void setup() {
Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
lockServo.attach(SERVO_PIN);
lockServo.write(0);
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(BUZZER, OUTPUT);
}
void loop() {
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) return;
String uid = "";
for (byte i = 0; i < rfid.uid.size; i++) {
if (rfid.uid.uidByte[i] < 0x10) uid += "0";
uid += String(rfid.uid.uidByte[i], HEX);
}
uid.toUpperCase();
bool allowed = false;
for (int i = 0; i < NUM_CARDS; i++) {
if (uid == allowedUids[i]) { allowed = true; break; }
}
if (allowed) {
Serial.println("Valid card -> unlocking");
unlockDoor();
} else {
Serial.println("Invalid card -> denied");
denyAccess();
}
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
}
Common pitfalls
- Feeding 5V into the RC522: the module only tolerates 3.3V logic, and connecting VCC to 5V can fry the chip within seconds.
- Servo too weak to hold the latch: the SG90 is fairly weak — if your latch is heavy, switch to a 12V solenoid lock driven through a relay instead of pulling it directly with a servo.
- Mismatched UID formatting: a UID byte can print with or without a leading zero — normalize it consistently (e.g. always pad with “0” when the byte is below 0x10) both when recording the allow-list and when comparing, or valid cards will get rejected.
- No protection against UID cloning: acceptable for a small DIY project, but don’t rely on this for anything that actually matters — RFID UIDs can be copied with dedicated hardware.
Where to go from here
Store the UID allow-list in EEPROM so you can add or remove cards without reflashing, or log unlock events with timestamps to an SD card or Google Sheets via an ESP8266 so you know who opened the door and when.
Tags:#arduino#rfid#security
Comments