📅 Duration: 2 hours
🎯 Objective:
Build an RFID access control system using Arduino and the MFRC522 RFID module to grant or deny access based on authorized card UIDs.
Introduction
This Arduino program reads an RFID tag using the MFRC522 module and determines whether access is granted or denied based on a list of pre-authorized UIDs. We'll examine the code structure, understand how it works, and implement a complete access control system.
Circuit Diagram

Circuit diagram showing the connections between Arduino and MFRC522 RFID reader.
Understanding the RFID Access Control System
1. Libraries and Setup
- We need two essential libraries:
- SPI.h - Allows communication between Arduino and RFID module using SPI protocol
- MFRC522.h - Provides functions to interact with the MFRC522 RFID reader
- Define the RFID module pins:
- SS_PIN (Slave Select) connected to pin 10
- RST_PIN (Reset) connected to pin 9
- Create an instance of MFRC522 class
#include
#include
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
2. Storing Authorized UIDs
- Create an array to store pre-approved RFID card UIDs
- Calculate the number of authorized UIDs automatically
const String authorizedUIDs[] = { "BD31152B", "A1B2C3D4" };
const int numAuthorized = sizeof(authorizedUIDs) / sizeof(authorizedUIDs[0]);
3. The setup() Function
- Initialize serial communication for debugging
- Initialize SPI bus for RFID communication
- Initialize the MFRC522 RFID reader
- Print initialization message to serial monitor
void setup() {
Serial.begin(9600); // Start serial communication
SPI.begin(); // Initialize SPI bus
mfrc522.PCD_Init(); // Initialize the MFRC522 RFID reader
Serial.println("RFID Access Control System Initialized");
Serial.println("Please scan your card...");
}
4. The loop() Function
- Check if a new RFID card is present
- Read the card's UID if present
- Check if the card is authorized
- Wait before scanning again
void loop() {
// Check if a new RFID card is present
if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
return; // Exit loop if no card is detected
}
// Read the UID of the card
String scannedUID = getCardUID();
Serial.print("Scanned UID: ");
Serial.println(scannedUID);
// Check if UID is authorized
if (isAuthorized(scannedUID)) {
Serial.println("Access Granted ✅");
} else {
Serial.println("Access Denied ❌");
}
delay(3000); // Wait 3 seconds before scanning again
}
5. The getCardUID() Function
This function reads the RFID card's UID and converts it to a readable string format.
String getCardUID() {
String uid = ""; // Create an empty string to store the UID
// Loop through all bytes of the UID
for (byte i = 0; i < mfrc522.uid.size; i++) {
uid += String(mfrc522.uid.uidByte[i], HEX); // Convert byte to HEX and append
}
uid.toUpperCase(); // Convert to uppercase for consistency
return uid; // Return the UID string
}
6. The isAuthorized() Function
This function checks if the scanned UID matches any of the pre-authorized UIDs.
bool isAuthorized(String uid) {
for (int i = 0; i < numAuthorized; i++) {
if (uid.equalsIgnoreCase(authorizedUIDs[i])) {
return true; // Authorized UID found
}
}
return false; // Not authorized
}
Deep Dive: Understanding getCardUID() Function
What is a UID in RFID?
- Every RFID card has a Unique Identifier (UID)
- The UID is a series of bytes (typically 4, 7, or 10 bytes)
- The UID is stored in hexadecimal (HEX) format
- Example of a 4-byte UID: BD 31 15 2B
Why Convert the UID to a String?
- The RFID reader reads the UID as raw bytes
- To compare it with predefined UIDs, we need to convert it to a readable format
- Example:
- Raw bytes: [0xBD, 0x31, 0x15, 0x2B]
- Converted string: "BD31152B"
Breaking Down getCardUID() Step by Step
- Step 1: Create an empty string
String uid = "";
- Step 2: Loop through each byte
for (byte i = 0; i < mfrc522.uid.size; i++) {
- Step 3: Convert each byte to HEX
uid += String(mfrc522.uid.uidByte[i], HEX);
- Step 4: Convert to uppercase
uid.toUpperCase();
- Step 5: Return the final UID string
return uid;
Example in Action
Let's say we scanned a card with UID = BD 31 15 2B
Raw Data from RFID Reader:
mfrc522.uid.uidByte[0] = 0xBD
mfrc522.uid.uidByte[1] = 0x31
mfrc522.uid.uidByte[2] = 0x15
mfrc522.uid.uidByte[3] = 0x2B
Processing in getCardUID():
- First loop iteration (i = 0): uid = "BD"
- Second loop iteration (i = 1): uid = "BD31"
- Third loop iteration (i = 2): uid = "BD3115"
- Fourth loop iteration (i = 3): uid = "BD31152B"
Final Output:
Scanned UID: BD31152B
Why This Conversion Is Important
❌ Incorrect Comparison (Raw Bytes):
if (mfrc522.uid.uidByte == {0xBD, 0x31, 0x15, 0x2B}) { // Won't work
✅ Correct Comparison (String):
if (scannedUID.equalsIgnoreCase("BD31152B")) {
Complete RFID Access Control System Code
#include
#include
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance
const String authorizedUIDs[] = { "BD31152B", "A1B2C3D4" };
const int numAuthorized = sizeof(authorizedUIDs) / sizeof(authorizedUIDs[0]);
void setup() {
Serial.begin(9600); // Start serial communication
SPI.begin(); // Initialize SPI bus
mfrc522.PCD_Init(); // Initialize the MFRC522 RFID reader
Serial.println("RFID Access Control System Initialized");
Serial.println("Please scan your card...");
}
void loop() {
// Check if a new RFID card is present
if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
return; // Exit loop if no card is detected
}
// Read the UID of the card
String scannedUID = getCardUID();
Serial.print("Scanned UID: ");
Serial.println(scannedUID);
// Check if UID is authorized
if (isAuthorized(scannedUID)) {
Serial.println("Access Granted ✅");
} else {
Serial.println("Access Denied ❌");
}
delay(3000); // Wait 3 seconds before scanning again
}
// Function to read RFID UID and return it as a string
String getCardUID() {
String uid = ""; // Create an empty string to store the UID
// Loop through all bytes of the UID
for (byte i = 0; i < mfrc522.uid.size; i++) {
uid += String(mfrc522.uid.uidByte[i], HEX); // Convert byte to HEX and append
}
uid.toUpperCase(); // Convert to uppercase for consistency
return uid; // Return the UID string
}
// Function to check if the UID is in the authorized list
bool isAuthorized(String uid) {
for (int i = 0; i < numAuthorized; i++) {
if (uid.equalsIgnoreCase(authorizedUIDs[i])) {
return true; // Authorized UID found
}
}
return false; // Not authorized
}
Example Output on the Serial Monitor
Authorized Card
RFID Access Control System Initialized
Please scan your card...
Scanned UID: BD31152B
Access Granted ✅
Unauthorized Card
Scanned UID: 5A7C3D1E
Access Denied ❌
Lab Exercise: Enhancing the RFID System
Task 1: Add Visual Indicators
- Add a Green LED to indicate access granted
- Add a Red LED to indicate access denied
- Pin suggestions:
- Green LED: Pin 7
- Red LED: Pin 6
Task 2: Add Sound Notification
- Add a buzzer that beeps:
- One short beep for access granted
- Three short beeps for access denied
- Suggested pin: Buzzer on Pin 8
Task 3: Implement a Door Lock Simulation
- Use a servo motor to simulate a door lock
- When access is granted:
- Rotate servo to "unlock" position
- Wait 5 seconds
- Rotate servo back to "lock" position
- Suggested pin: Servo on Pin 5
Task 4: Dynamic Card Management
- Allow adding new authorized cards through serial commands
- Create a "master card" that when scanned, puts the system in "enrollment mode"
- The next card scanned is added to the authorized list
- Use EEPROM to store the list of authorized cards
Submission Requirements
- Complete Arduino code with comments explaining each section
- Circuit diagram showing all connections
- Video demonstration of your working system
- Brief report explaining:
- How your implemented features work
- Challenges faced and how you solved them
- Potential real-world applications
Grading Criteria
- Functionality (40%)
- All features working as specified
- Proper integration of components
- Code Quality (30%)
- Well-structured and commented code
- Efficient implementation
- Documentation (20%)
- Clear circuit diagram
- Complete submission requirements
- Creativity (10%)
- Additional features or improvements
- Innovative solutions