Raspberry Pi RFID + Keypad
Smart Door Lock System
Two-factor access control — scan your RFID card, then enter your password. Motorized lock control with L298N, real-time 16×2 LCD feedback, and SPI communication.
What This System Does
This project implements a dual-factor smart access control system on Raspberry Pi. A user must first present an authorized RFID card (primary factor) and then enter the correct password on the 4×4 matrix keypad (secondary factor). Only when both checks pass does the L298N motor driver activate the DC motor to unlock the door.
All system status messages are displayed in real time on a 16×2 LCD screen, making it suitable for real-world deployment in offices, hostels, or smart homes.
Components Required
System Working Principle
RFID Authentication — Primary Verification
The RC522 RFID module communicates via SPI protocol (pins SCK, MOSI, MISO, SDA, RST). When a user presents a card or tag, the system reads the unique UID and compares it against a pre-stored list of authorized IDs in the program.
Keypad Password — Secondary Security Layer
After RFID validation, the LCD prompts "Enter Password". The user types a PIN on the 4×4 matrix keypad. This second factor substantially increases security over single-layer RFID systems and mitigates lost/stolen card risks.
Real-Time LCD Feedback
The 16×2 LCD display (I2C, address 0x27) shows live status messages at every stage so the user always knows what the system expects.
Motorized Lock Control via L298N
On successful authentication, GPIO pins IN1, IN2, and ENA drive the L298N H-Bridge, which spins the DC motor to simulate door unlocking. The motor runs for 5 seconds then reverses to re-lock. On failed authentication the motor remains inactive.
Dual Power Management
The Raspberry Pi powers all logic components (RFID, keypad, LCD). A separate 9V battery supplies the L298N motor driver, preventing motor current spikes from disrupting the Pi's stable 3.3V/5V power rails.
GPIO Pin Connections
Wiring diagram: Raspberry Pi ↔ RC522 RFID (SPI) · 4×4 Keypad (GPIO) · 16×2 LCD (I2C) · L298N + DC Motor
| Component | Signal | Raspberry Pi GPIO | Notes |
|---|---|---|---|
| RC522 RFID Module (SPI) | |||
| RC522 SDA/CS | Chip Select | GP17 | SPI CE |
| RC522 SCK | SPI Clock | GP27 | SPI CLK |
| RC522 MOSI | Master Out | GP9 | SPI MOSI |
| RC522 MISO | Master In | GP10 | SPI MISO |
| RC522 RST | Reset | GP7 | Digital output |
| L298N Motor Driver | |||
| L298N IN1 | Direction A | GP23 | Motor forward/reverse |
| L298N IN2 | Direction B | GP24 | Motor forward/reverse |
| L298N ENA | Enable | GP22 | PWM speed control |
| 4×4 Matrix Keypad | |||
| Keypad Row 1–4 | R1,R2,R3,R4 | GP5, GP6, GP13, GP19 | Row scanning |
| Keypad Col 1–4 | C1,C2,C3,C4 | GP12, GP16, GP20, GP21 | Column scanning |
| 16×2 LCD Display (I2C) | |||
| LCD SDA | I2C Data | GP2 (SDA) | Address 0x27 |
| LCD SCL | I2C Clock | GP3 (SCL) | Address 0x27 |
| Power | |||
| L298N VCC | Motor Power | 9V Battery (+) | Isolated from Pi rail |
| L298N GND | Common GND | GND (shared) | Pi GND + Battery (−) |
Step-by-Step Instructions
Enable SPI on Raspberry Pi
Open a terminal and run sudo raspi-config → Interface Options → SPI → Enable. This activates the SPI bus required by the RC522 RFID module.
Install Required Libraries
Run in terminal: pip install mfrc522 RPLCD smbus2 keypad. These provide the RFID, LCD I2C, and keypad driver libraries needed for the project.
Wire the RC522 RFID Module
Connect RC522 to Raspberry Pi SPI pins as per the table above. Use 3.3V for power (not 5V — the RC522 is a 3.3V device). Double-check SDA/CS, SCK, MOSI, MISO, and RST connections.
Wire the 4×4 Keypad
Connect the 8 keypad pins (4 rows + 4 columns) to GPIO pins GP5, GP6, GP13, GP19 (rows) and GP12, GP16, GP20, GP21 (columns). No resistors needed — the Keypad library uses internal pull-ups.
Wire the 16×2 LCD (I2C)
Connect LCD SDA to GPIO2 (Pin 3) and SCL to GPIO3 (Pin 5). Power from 5V and GND. Verify I2C address with i2cdetect -y 1 — should show 0x27.
Wire the L298N and DC Motor
Connect IN1→GP23, IN2→GP24, ENA→GP22. Connect the 9V battery to L298N VCC. Connect the DC motor to the L298N motor output terminals. Share GND between Pi and L298N.
Register Your RFID Card UID
Run a test script to scan your RFID card and read its UID. Copy the UID into the AUTHORIZED_UIDS list in the main code. Each card has a unique UID printed in hex.
Upload & Run the Code
Save the code as doorlock.py and run with python3 doorlock.py. The LCD will display "Door Lock System". Present your RFID card, then enter your password on the keypad.
Complete Program Code
This Arduino-style C++ implementation (compatible with Raspberry Pi via the Arduino-Pi bridge or direct C++ GPIO) handles the full authentication and motor control logic:
/* * Raspberry Pi RFID and Keypad Based Smart Door Lock System * MakeMindz.com | makemindz.com/raspberry-pi-rfid-door-lock * * Two-factor authentication: * 1. RFID card UID verification (RC522 via SPI) * 2. Keypad password entry (4x4 matrix) * On success: L298N motor driver unlocks DC motor for 5 seconds. * LCD shows real-time status at every stage. */ #include <Wire.h> #include <LiquidCrystal_I2C.h> #include <MFRC522.h> #include <Keypad.h> // ── RFID Pin Definitions (SPI) ──────────────────── #define SDA_PIN 17 // GP17 — Chip Select #define SCK_PIN 27 // GP27 — SPI Clock #define MOSI_PIN 9 // GP9 — SPI MOSI #define MISO_PIN 10 // GP10 — SPI MISO #define RST_PIN 7 // GP7 — Reset // ── L298N Motor Driver Pins ─────────────────────── #define IN1_PIN 23 // GP23 — Motor direction A #define IN2_PIN 24 // GP24 — Motor direction B #define ENA_PIN 22 // GP22 — Motor enable (HIGH = enabled) // ── LCD (I2C, address 0x27, 16 columns x 2 rows) ─ LiquidCrystal_I2C lcd(0x27, 16, 2); // ── RFID Module ─────────────────────────────────── MFRC522 rfid(SDA_PIN, RST_PIN); // ── Authorized RFID UIDs ────────────────────────── // Add your card UID bytes here (scan card to get UID) byte authorizedUID[][4] = { {0xDE, 0xAD, 0xBE, 0xEF}, // Replace with your card UID {0x12, 0x34, 0x56, 0x78} // Add more UIDs as needed }; const int NUM_UIDS = sizeof(authorizedUID) / sizeof(authorizedUID[0]); // ── Secret Keypad Password ──────────────────────── const String CORRECT_PASSWORD = "1234"; // Change this! // ── 4x4 Keypad Setup ───────────────────────────── const byte ROWS = 4; const byte COLS = 4; char keys[ROWS][COLS] = { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; byte rowPins[ROWS] = {5, 6, 13, 19}; // Row GPIO pins byte colPins[COLS] = {12, 16, 20, 21}; // Column GPIO pins Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS); // ── State Variables ─────────────────────────────── bool rfidVerified = false; String enteredPIN = ""; // ───────────────────────────────────────────────── void setup() { Serial.begin(9600); // Initialise LCD lcd.begin(); lcd.backlight(); lcd.print("Door Lock System"); lcd.setCursor(0, 1); lcd.print(" Initialising.."); delay(1500); // Initialise RFID reader SPI.begin(); rfid.PCD_Init(); // Initialise motor driver pins pinMode(IN1_PIN, OUTPUT); pinMode(IN2_PIN, OUTPUT); pinMode(ENA_PIN, OUTPUT); digitalWrite(ENA_PIN, HIGH); // Enable motor driver lockDoor(); // Ensure locked at startup promptScan(); } // ───────────────────────────────────────────────── void loop() { if (!rfidVerified) { // ── Stage 1: Wait for RFID card ────────────── if (rfid.PICC_IsNewCardPresent() && rfid.PICC_ReadCardSerial()) { Serial.println("Card scanned."); if (isAuthorized(rfid.uid.uidByte, rfid.uid.size)) { rfidVerified = true; enteredPIN = ""; lcd.clear(); lcd.print("Card: OK!"); lcd.setCursor(0, 1); lcd.print("Enter Password:"); Serial.println("RFID OK. Enter PIN."); } else { lcd.clear(); lcd.print("Unknown Card!"); lcd.setCursor(0, 1); lcd.print("Access Denied"); Serial.println("Unauthorized UID."); delay(2000); promptScan(); } rfid.PICC_HaltA(); } } else { // ── Stage 2: Read PIN from keypad ───────────── char key = keypad.getKey(); if (key) { if (key == '#') { // '#' confirms the PIN entry if (enteredPIN == CORRECT_PASSWORD) { grantAccess(); } else { denyAccess(); } rfidVerified = false; enteredPIN = ""; promptScan(); } else if (key == '*') { // '*' clears the current entry enteredPIN = ""; lcd.setCursor(0, 1); lcd.print("Cleared. "); delay(500); lcd.setCursor(0, 1); lcd.print("Enter Password: "); } else { // Append digit, show '*' mask enteredPIN += key; lcd.setCursor(enteredPIN.length() - 1, 1); lcd.print('*'); } } } } // ───────────────────────────────────────────────── // Check if scanned UID matches any authorized UID bool isAuthorized(byte *uid, byte size) { for (int i = 0; i < NUM_UIDS; i++) { bool match = true; for (int j = 0; j < 4; j++) { if (uid[j] != authorizedUID[i][j]) { match = false; break; } } if (match) return true; } return false; } void grantAccess() { Serial.println("ACCESS GRANTED"); lcd.clear(); lcd.print("Access Granted!"); lcd.setCursor(0, 1); lcd.print("Door Unlocked "); unlockDoor(); } void denyAccess() { Serial.println("ACCESS DENIED - Wrong PIN"); lcd.clear(); lcd.print("Wrong Password!"); lcd.setCursor(0, 1); lcd.print("Access Denied "); delay(2000); } void unlockDoor() { digitalWrite(IN1_PIN, HIGH); // Motor forward — unlock digitalWrite(IN2_PIN, LOW); delay(5000); // Keep unlocked 5 seconds lockDoor(); lcd.clear(); lcd.print("Door Locked"); delay(1000); } void lockDoor() { digitalWrite(IN1_PIN, LOW); // Motor stop digitalWrite(IN2_PIN, LOW); } void promptScan() { lcd.clear(); lcd.print("Scan Your Card"); lcd.setCursor(0, 1); lcd.print("to continue..."); }
Serial.println(rfid.uid.uidByte[i], HEX) in a loop to print your card's UID to Serial Monitor. Copy those hex values into authorizedUID.
Comments
Post a Comment