An RFID access control system is one of the most practical security projects you can build with Arduino. From small offices to server rooms, RFID-based entry systems provide a keyless, auditable access solution at a fraction of the cost of commercial systems. This guide shows you how to build a multi-door RFID access control system with Arduino, complete with card management, audit logging, solenoid lock integration, and optional WiFi connectivity via ESP32.
Table of Contents
- System Design and Architecture
- Hardware Components
- RFID Technology Basics: RC522 Module
- Single Door Setup with Arduino
- Multi-Door System with ESP32
- Card Management and Enrolment
- Audit Logging and Monitoring
- Frequently Asked Questions
- Conclusion
System Design and Architecture
A multi-door RFID access control system consists of:
- RFID readers (RC522): One at each door, reading 13.56 MHz MIFARE cards/tags
- Controller (Arduino/ESP32): Validates card UID against authorised list, controls lock
- Electric lock: Solenoid lock, electromagnetic lock, or electric strike
- Feedback: LED indicators (green/red) and buzzer for access granted/denied
- Logging: SD card or WiFi-based audit trail
- Central management: Web interface for adding/removing cards (ESP32 version)
Hardware Components
Per Door
- RFID-RC522 module: 13.56 MHz reader with SPI interface. ₹100-200.
- Arduino Nano or ESP32: Controller per door. ₹200-400.
- 12V solenoid lock: Fail-secure type (locked when power off). ₹200-500.
- Relay module: To switch solenoid from Arduino logic level. ₹40-80.
- 12V power supply: For solenoid lock. ₹100-200.
- Buzzer and LEDs: Red/green indicators. ₹20-40.
- MIFARE cards/keyfobs: ₹10-30 each in bulk.
RFID Technology Basics: RC522 Module
The MFRC522 (RC522) module reads 13.56 MHz MIFARE Classic and MIFARE Ultralight cards. Each card has a unique 4-byte UID (Unique Identifier) that serves as the “key” for access control.
Wiring RC522 to Arduino
RC522 Pin Arduino Uno Arduino Nano ESP32
SDA (SS) Pin 10 Pin 10 GPIO 5
SCK Pin 13 Pin 13 GPIO 18
MOSI Pin 11 Pin 11 GPIO 23
MISO Pin 12 Pin 12 GPIO 19
IRQ Not connected Not connected Not connected
GND GND GND GND
RST Pin 9 Pin 9 GPIO 22
3.3V 3.3V 3.3V 3.3V
Important: The RC522 operates at 3.3V. Connecting to 5V will damage it. Arduino Uno’s SPI pins are 5V but most RC522 modules include voltage regulation. ESP32 is natively 3.3V, so no issues there.
Single Door Setup with Arduino
// RFID Access Control - Single Door
#include
#include
#define SS_PIN 10
#define RST_PIN 9
#define RELAY_PIN 7
#define GREEN_LED 5
#define RED_LED 6
#define BUZZER 4
MFRC522 rfid(SS_PIN, RST_PIN);
// Authorised card UIDs (add your cards here)
byte authorisedCards[][4] = {
{0xA1, 0xB2, 0xC3, 0xD4}, // Card 1 - Jayesh
{0xE5, 0xF6, 0x07, 0x18}, // Card 2 - Security
{0x29, 0x3A, 0x4B, 0x5C}, // Card 3 - Office
};
const int numCards = sizeof(authorisedCards) / sizeof(authorisedCards[0]);
void setup() {
Serial.begin(9600);
SPI.begin();
rfid.PCD_Init();
pinMode(RELAY_PIN, OUTPUT);
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(BUZZER, OUTPUT);
digitalWrite(RELAY_PIN, LOW); // Lock secured
digitalWrite(RED_LED, HIGH); // Default: red (locked)
digitalWrite(GREEN_LED, LOW);
Serial.println("RFID Access Control Ready");
Serial.println("Scan your card...");
}
void loop() {
if (!rfid.PICC_IsNewCardPresent() || !rfid.PICC_ReadCardSerial()) {
return;
}
// Print card UID
Serial.print("Card UID: ");
for (byte i = 0; i < rfid.uid.size; i++) {
Serial.print(rfid.uid.uidByte[i], HEX);
Serial.print(" ");
}
Serial.println();
// Check if card is authorised
if (isAuthorised(rfid.uid.uidByte)) {
grantAccess();
} else {
denyAccess();
}
rfid.PICC_HaltA();
rfid.PCD_StopCrypto1();
}
bool isAuthorised(byte *uid) {
for (int i = 0; i < numCards; i++) {
bool match = true;
for (int j = 0; j < 4; j++) {
if (uid[j] != authorisedCards[i][j]) {
match = false;
break;
}
}
if (match) return true;
}
return false;
}
void grantAccess() {
Serial.println("ACCESS GRANTED");
digitalWrite(GREEN_LED, HIGH);
digitalWrite(RED_LED, LOW);
tone(BUZZER, 2000, 200);
// Unlock door for 5 seconds
digitalWrite(RELAY_PIN, HIGH);
delay(5000);
digitalWrite(RELAY_PIN, LOW);
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, HIGH);
}
void denyAccess() {
Serial.println("ACCESS DENIED");
// Rapid red LED flash + buzzer
for (int i = 0; i < 3; i++) {
digitalWrite(RED_LED, LOW);
tone(BUZZER, 500, 100);
delay(200);
digitalWrite(RED_LED, HIGH);
delay(200);
}
}
Multi-Door System with ESP32
For multiple doors, use ESP32 controllers that communicate with a central web server for card management:
// ESP32 RFID Access Control with Web Server
#include
#include
#include
#include
#include
#define SS_PIN 5
#define RST_PIN 22
#define RELAY_PIN 26
#define DOOR_NAME "Main Entrance"
#define MAX_CARDS 50
MFRC522 rfid(SS_PIN, RST_PIN);
WebServer server(80);
struct CardEntry {
byte uid[4];
char name[20];
bool active;
};
CardEntry cards[MAX_CARDS];
int cardCount = 0;
// Log entry structure
struct LogEntry {
byte uid[4];
unsigned long timestamp;
bool granted;
};
void setup() {
Serial.begin(115200);
SPI.begin();
rfid.PCD_Init();
EEPROM.begin(sizeof(cards) + sizeof(int));
loadCardsFromEEPROM();
WiFi.begin("ssid", "password");
while (WiFi.status() != WL_CONNECTED) delay(500);
// Web server routes
server.on("/", handleDashboard);
server.on("/add", HTTP_POST, handleAddCard);
server.on("/remove", HTTP_POST, handleRemoveCard);
server.on("/log", handleViewLog);
server.begin();
Serial.printf("Access Control [%s] ready at http://%sn",
DOOR_NAME, WiFi.localIP().toString().c_str());
}
void loop() {
server.handleClient();
if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) {
processCard();
rfid.PICC_HaltA();
}
}
void processCard() {
bool authorised = false;
String cardName = "Unknown";
for (int i = 0; i < cardCount; i++) {
if (cards[i].active && memcmp(rfid.uid.uidByte, cards[i].uid, 4) == 0) {
authorised = true;
cardName = String(cards[i].name);
break;
}
}
logAccess(rfid.uid.uidByte, authorised);
if (authorised) {
Serial.printf("GRANTED: %sn", cardName.c_str());
unlockDoor(5000);
} else {
Serial.println("DENIED: Unknown card");
denyAccess();
}
}
Card Management and Enrolment
The ESP32 web interface allows adding and removing cards without reprogramming. The enrolment process:
- Access the web dashboard at the ESP32’s IP address
- Click “Add New Card” and enter the person’s name
- Scan the new RFID card on the reader
- System captures the UID and saves it with the name to EEPROM
- Card is immediately active across all doors (if using centralised database)
Master Card System
For systems without WiFi, use a “master card” approach: scanning the master card puts the system into enrolment mode. The next card scanned is added to the authorised list. Scan the master card again to exit enrolment mode.
Audit Logging and Monitoring
Every access attempt (granted and denied) should be logged with timestamp, card UID, door name, and result. Options for logging:
- SD Card: Simple CSV file with Arduino. Good for offline systems.
- EEPROM: Limited space but requires no additional hardware.
- WiFi + Database: ESP32 sends log entries to a MySQL/InfluxDB database on a Raspberry Pi.
- MQTT: Publish access events to an MQTT broker for real-time monitoring dashboards.
Frequently Asked Questions
Can RFID cards be cloned?
Basic MIFARE Classic cards can be cloned using cheap readers and software. For higher security, use MIFARE DESFire EV2 or DESFire EV3 cards which have AES encryption. For most small office applications, MIFARE Classic with UID-based authentication is sufficient — the threat model should match the security requirement.
What type of lock should I use?
Solenoid locks (₹200-500) are cheapest and work for lightweight doors. Electromagnetic locks (₹800-2,000) are stronger and suitable for heavier doors. Electric strikes (₹1,500-3,000) are the most professional option. Always use fail-secure locks (locked when power off) for security-critical doors.
Can I add fingerprint along with RFID?
Yes. Add an R307 or R503 fingerprint sensor and require both RFID card + fingerprint for dual-factor authentication. This significantly increases security for sensitive areas like server rooms.
How many cards can the system store?
Arduino EEPROM (1 KB): approximately 50 cards. ESP32 EEPROM (4 KB): approximately 200 cards. Using an SD card or external database: practically unlimited. For most small offices, 50-100 cards is more than sufficient.
What happens during a power failure?
Fail-secure locks remain locked during power outages (safe for security). Add a battery backup (UPS) for critical doors. The Arduino/ESP32 can include a supercapacitor to save the last log entry during power loss.
Conclusion
An RFID access control system built with Arduino or ESP32 provides a surprisingly capable and affordable security solution. From a simple single-door setup costing under ₹1,000 to a multi-door networked system with web management and audit logging, the technology scales well for small to medium installations.
Start with a single door, get familiar with the RC522 module and solenoid lock, then expand to multiple doors with ESP32 and centralised management. The resulting system is fully customisable, upgradeable, and costs a fraction of commercial access control systems.
Find RFID modules, development boards, and security components at Zbotic’s online store.
Add comment