Arduino RFID and Password Gate Lock Project
Hi in this project we will make Arduino RFID and Password Gate Lock project which can serve 2 purposes.
You can make password protected gate lock project and a student/employee attendance system with the same circuit.
You have already seen rfid based gate lock project, there is one issue with this project related to security.
If anybody takes away your RFID tag they can easily unlock the gate, Hence here is the solution.
Adding a password lock ensures double safety to this system also you can call this as 2 factor authentication.
After you tap the RFID tag you need to enter the password to open the gate, this makes the gate/door secure.
Also check my arduino car parking system here
How Arduino RFID and Password Gate Lock Works
The logic behind working on this project is simple.
The Arduino Program is written in such a way that when you tap on that RFID reader the first time you tap it is considered a master tag.
Now you can set a password and then tap on the tags that you want to store in EEPROM.
You can register more than 40 tags in my case I did only 2.
Follow the instructions on LCD screen and then type the password you like.
Tap on the master tag to exit the program and then tap on the other tag with a password for servo movement.
I will use this mechanism to open the gate, you can add a servo to a door and make a doorway.
This can be used to allow vehicles and to monitor students or employees.
List of materials to build this project
- Arduino Uno
- LCD module with I2c
- RFID module with tags
- Red and Green Led
- Keypad matrix
- Micro servo
- Jumper wires
- Cardboard
- Hot glue
- Arduino IDE and programming cable
RFID and Keypad based Lock System Circuit Diagram
Follow this circuit diagram to connect the components together for this project.
The connections are easy if you split the connections component wise, RFID reader, Servo, LCD and matrix membrane module.
RFID Module (RC522) Connections
- SDA to Pin 10 on Arduino
- SCK to Pin 13 on Arduino
- MOSI to Pin 11
- MISO to Pin 12
- IRQ is Not connected
- GND to GND on Arduino
- RST to Pin 9 on Arduino
- 3.3V to 3.3v
Servo Motor
- VCC to 5V on Arduino
- GND to GND on Arduino
- Signal to Pin 8 on Arduino
16×2 LCD (with I2C)
- VSS to GND on Arduino
- VDD to 5V
- V0 to GND for contrast control
- D4 to Pin 5 on Arduino
- D5 to Pin 4 on Arduino
- D6 to Pin 3
- D7 to Pin 2 on Arduino
4×4 Keypad Membrane
- R1 to Pin A0
- R2 to Pin A1 on Arduino
- R3 to Pin A2
- R4 to Pin A3 on Arduino
- C1 to Pin A4
- C2 to Pin A5 on Arduino
- C3 to Pin A6 on Arduino
- C4 to Pin A7
Codes for Arduino RFID and Password Gate Lock
Open your Arduino IDE and paste this below arduino program, Select proper board type and port name.
Click on upload, if you have any issues make sure to check the library.
If you don’t have liquid crystal library get it here
#include <EEPROM.h> // We are going to read and write Tag's UIDs from/to EEPROM
#include <MFRC522.h>
#include <LiquidCrystal_I2C.h>
#include <Keypad.h>
#include <Servo.h>
#include <SPI.h>
#include <Wire.h>
// Create instances
MFRC522 mfrc522(10, 9); // MFRC522 mfrc522(SS_PIN, RST_PIN)
LiquidCrystal_I2C lcd(0x27, 16, 2);
Servo myServo; // create servo object to control a servo
// Set Pins for LEDs, servo, buzzer, and wipe button
constexpr uint8_t greenLed = 7;
constexpr uint8_t blueLed = 6;
constexpr uint8_t redLed = 5;
constexpr uint8_t ServoPin = 8;
constexpr uint8_t BuzzerPin = 4;
constexpr uint8_t wipeB = 3; // Button pin for WipeMode
boolean match = false; // Initialize card match to false
boolean programMode = false; // Initialize programming mode to false
boolean replaceMaster = false;
uint8_t successRead; // Variable integer to keep if we have Successful Read from Reader
byte storedCard[4]; // Stores an ID read from EEPROM
byte readCard[4]; // Stores scanned ID read from RFID Module
byte masterCard[4]; // Stores master card's ID read from EEPROM
char storedPass[5]; // Variable to get password from EEPROM (4 chars + null terminator)
char password[5]; // Variable to store user's password (4 chars + null terminator)
char masterPass[5]; // Variable to store master password (4 chars + null terminator)
boolean RFIDMode = true; // Boolean to change modes
boolean NormalMode = true; // Boolean to change modes
char key_pressed = 0; // Variable to store incoming keys
uint8_t i = 0; // Variable used for counter
// Defining how many rows and columns our keypad has
const byte rows = 4;
const byte columns = 4;
// Keypad pin map
char hexaKeys[rows][columns] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
// Initializing pins for keypad
byte row_pins[rows] = {A0, A1, A2, A3};
byte column_pins[columns] = {2, 1, 0, A4}; // Updated to have 4 columns
// Create instance for keypad
Keypad newKey = Keypad(makeKeymap(hexaKeys), row_pins, column_pins, rows, columns);
///////////////////////////////////////// Setup ///////////////////////////////////
void setup() {
// Arduino Pin Configuration
pinMode(redLed, OUTPUT);
pinMode(greenLed, OUTPUT);
pinMode(blueLed, OUTPUT);
pinMode(BuzzerPin, OUTPUT);
pinMode(wipeB, INPUT_PULLUP); // Enable pin's pull-up resistor
// Make sure LEDs are off
digitalWrite(redLed, LOW);
digitalWrite(greenLed, LOW);
digitalWrite(blueLed, LOW);
// Protocol Configuration
lcd.init(); // Initialize the LCD
lcd.backlight();
SPI.begin(); // MFRC522 Hardware uses SPI protocol
mfrc522.PCD_Init(); // Initialize MFRC522 Hardware
myServo.attach(ServoPin); // Attaches the servo on pin 8 to the servo object
myServo.write(10); // Initial Position
// If you set Antenna Gain to Max it will increase reading distance
// mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);
ShowReaderDetails(); // Show details of PCD - MFRC522 Card Reader details
// Wipe Code - If the Button (wipeB) Pressed while setup runs (powered on) it wipes EEPROM
if (digitalRead(wipeB) == LOW) { // When button pressed pin should get low, button connected to ground
digitalWrite(redLed, HIGH); // Red LED stays on to inform user we are going to wipe
lcd.setCursor(0, 0);
lcd.print("Button Pressed");
digitalWrite(BuzzerPin, HIGH);
delay(1000);
digitalWrite(BuzzerPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("This will remove");
lcd.setCursor(0, 1);
lcd.print("all records");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("You have 10 ");
lcd.setCursor(0, 1);
lcd.print("secs to Cancel");
delay(2000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Unpress to cancel");
lcd.setCursor(0, 1);
lcd.print("Counting: ");
bool buttonState = monitorWipeButton(10000); // Give user enough time to cancel operation
if (buttonState == true && digitalRead(wipeB) == LOW) { // If button still pressed, wipe EEPROM
lcd.clear();
lcd.print("Wiping EEPROM...");
for (uint16_t x = 0; x < EEPROM.length(); x++) { // Loop end of EEPROM address
if (EEPROM.read(x) != 0) {
EEPROM.write(x, 0); // If not zero, write 0 to clear
}
}
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Wiping Done");
// Visualize a successful wipe
cycleLeds();
}
else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Wiping Cancelled"); // Show feedback that the wipe was cancelled
digitalWrite(redLed, LOW);
}
}
// Check if master card is defined; if not, let user choose a master card
if (EEPROM.read(1) != 143) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("No Master Card ");
lcd.setCursor(0, 1);
lcd.print("Defined");
delay(2000);
lcd.setCursor(0, 0);
lcd.print("Scan A Tag to ");
lcd.setCursor(0, 1);
lcd.print("Define as Master");
do {
successRead = getID(); // Sets successRead to 1 when we get a read from the reader
// Visualize that Master Card needs to be defined
digitalWrite(blueLed, HIGH);
digitalWrite(BuzzerPin, HIGH);
delay(200);
digitalWrite(BuzzerPin, LOW);
digitalWrite(blueLed, LOW);
delay(200);
}
while (!successRead); // Program will not proceed until a successful read
for (uint8_t j = 0; j < 4; j++) { // Loop 4 times
EEPROM.write(2 + j, readCard[j]); // Write scanned Tag's UID to EEPROM, starting from address 2
}
EEPROM.write(1, 143); // Write to EEPROM that we defined Master Card.
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Master Defined");
delay(2000);
storePassword(6); // Store password for master tag. 6 is the position in the EEPROM
}
// Read Master Card's UID and master password from EEPROM
for (uint8_t i = 0; i < 4; i++) {
masterCard[i] = EEPROM.read(2 + i); // Write it to masterCard
masterPass[i] = EEPROM.read(6 + i); // Write it to masterPass
}
masterPass[4] = '\0'; // Null-terminate the master password string
ShowOnLCD(); // Print on the LCD
cycleLeds(); // Everything ready; give user some feedback by cycling LEDs
}
///////////////////////////////////////// Main Loop ///////////////////////////////////
void loop() {
// System will first look for mode. If RFID mode is true, then it will get the tags; otherwise, it will get keys
if (RFIDMode == true) {
do {
successRead = getID(); // Sets successRead to 1 when we get a read from the reader
if (programMode) {
cycleLeds(); // Program Mode cycles through Red, Green, Blue waiting to read a new card
}
else {
normalModeOn(); // Normal mode, blue Power LED is on, all others are off
}
}
while (!successRead); // The program will not proceed until a successful read
if (programMode) {
if (isMaster(readCard)) { // When in program mode, check first if master card scanned again to exit program mode
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Exiting Program Mode");
digitalWrite(BuzzerPin, HIGH);
delay(1000);
digitalWrite(BuzzerPin, LOW);
ShowOnLCD();
programMode = false;
return;
}
else {
if (findID(readCard)) { // If scanned card is known, delete it
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Already there");
deleteID(readCard);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Tag to ADD/REM");
lcd.setCursor(0, 1);
lcd.print("Master to Exit");
}
else { // If scanned card is not known, add it
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("New Tag, adding...");
writeID(readCard);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Scan to ADD/REM");
lcd.setCursor(0, 1);
lcd.print("Master to Exit");
}
}
}
else {
if (isMaster(readCard)) { // If scanned card's ID matches Master Card's ID - enter program mode
programMode = true;
matchpass();
if (programMode == true) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Program Mode");
uint8_t count = EEPROM.read(0); // Read the first Byte of EEPROM that stores the number of IDs
lcd.setCursor(0, 1);
lcd.print("I have ");
lcd.print(count);
lcd.print(" records");
digitalWrite(BuzzerPin, HIGH);
delay(2000);
digitalWrite(BuzzerPin, LOW);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Scan a Tag to ");
lcd.setCursor(0, 1);
lcd.print("ADD/REMOVE");
}
}
else {
if (findID(readCard)) { // If not, see if the card is in the EEPROM
granted();
RFIDMode = false; // Make RFID mode false
ShowOnLCD();
}
else { // If not, show that the Access is denied
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Access Denied");
denied();
ShowOnLCD();
}
}
}
}
// If RFID mode is false, get keys
else if (RFIDMode == false) {
key_pressed = newKey.getKey(); // Store new key
if (key_pressed) {
password[i++] = key_pressed; // Storing in password variable
lcd.print("*");
}
if (i == 4) { // If 4 keys are completed
password[4] = '\0'; // Null-terminate the password string
delay(200);
if (strncmp(password, storedPass, 4) == 0) { // If password is matched
lcd.clear();
lcd.print("Pass Accepted");
lcd.setCursor(0, 1);
lcd.print("Door Opened");
granted();
RFIDMode = true; // Make RFID mode true
ShowOnLCD();
i = 0;
}
else { // If password is not matched
lcd.clear();
lcd.print("Wrong Password");
denied();
RFIDMode = true; // Make RFID mode true
ShowOnLCD();
i = 0;
}
}
}
}
///////////////////////////////////////// Access Granted ///////////////////////////////////
void granted() {
digitalWrite(blueLed, LOW); // Turn off blue LED
digitalWrite(redLed, LOW); // Turn off red LED
digitalWrite(greenLed, HIGH); // Turn on green LED
if (RFIDMode == false) {
myServo.write(90);
delay(3000);
myServo.write(10);
}
delay(1000);
digitalWrite(blueLed, HIGH);
digitalWrite(greenLed, LOW);
}
///////////////////////////////////////// Access Denied ///////////////////////////////////
void denied() {
digitalWrite(greenLed, LOW); // Make sure green LED is off
digitalWrite(blueLed, LOW); // Make sure blue LED is off
digitalWrite(redLed, HIGH); // Turn on red LED
digitalWrite(BuzzerPin, HIGH);
delay(1000);
digitalWrite(BuzzerPin, LOW);
digitalWrite(blueLed, HIGH);
digitalWrite(redLed, LOW);
}
///////////////////////////////////////// Get Tag's UID ///////////////////////////////////
uint8_t getID() {
// Getting ready for Reading Tags
if (!mfrc522.PICC_IsNewCardPresent()) { // If a new Tag placed to RFID reader continue
return 0;
}
if (!mfrc522.PICC_ReadCardSerial()) { // Since a Tag placed get Serial and continue
return 0;
}
// There are Mifare Tags which have 4 byte or 7 byte UID; care if you use 7 byte Tag
// Until we support 7 byte Tags, assume every Tag has 4 byte UID
for (uint8_t i = 0; i < 4; i++) {
readCard[i] = mfrc522.uid.uidByte[i];
}
mfrc522.PICC_HaltA(); // Stop reading
return 1;
}
/////////////////////// Check if RFID Reader is correctly initialized or not /////////////////////
void ShowReaderDetails() {
// Get the MFRC522 software version
byte v = mfrc522.PCD_ReadRegister(mfrc522.VersionReg);
// When 0x00 or 0xFF is returned, communication probably failed
if ((v == 0x00) || (v == 0xFF)) {
lcd.setCursor(0, 0);
lcd.print("Communication Failure");
lcd.setCursor(0, 1);
lcd.print("Check Connections");
digitalWrite(BuzzerPin, HIGH);
delay(2000);
// Visualize system is halted
digitalWrite(greenLed, LOW); // Make sure green LED is off
digitalWrite(blueLed, LOW); // Make sure blue LED is off
digitalWrite(redLed, HIGH); // Turn on red LED
digitalWrite(BuzzerPin, LOW);
while (true); // Do not proceed further
}
}
///////////////////////////////////////// Cycle LEDs (Program Mode) ///////////////////////////////////
void cycleLeds() {
digitalWrite(redLed, LOW); // Make sure red LED is off
digitalWrite(greenLed, HIGH); // Make sure green LED is on
digitalWrite(blueLed, LOW); // Make sure blue LED is off
delay(200);
digitalWrite(redLed, LOW);
digitalWrite(greenLed, LOW);
digitalWrite(blueLed, HIGH);
delay(200);
digitalWrite(redLed, HIGH);
digitalWrite(greenLed, LOW);
digitalWrite(blueLed, LOW);
delay(200);
digitalWrite(redLed, LOW);
digitalWrite(greenLed, LOW);
digitalWrite(blueLed, HIGH);
}
///////////////////////////////////////// Normal Mode LED ///////////////////////////////////
void normalModeOn() {
digitalWrite(blueLed, HIGH); // Blue LED ON and ready to read card
digitalWrite(redLed, LOW); // Make sure Red LED is off
digitalWrite(greenLed, LOW); // Make sure Green LED is off
}
///////////////////////////////////////// Read an ID from EEPROM //////////////////////////////
void readID(uint8_t number) {
uint8_t start = (number * 8) + 2; // Figure out starting position
for (uint8_t i = 0; i < 4; i++) { // Loop 4 times to get the 4 Bytes
storedCard[i] = EEPROM.read(start + i); // Assign values read from EEPROM to array
storedPass[i] = EEPROM.read(start + i + 4);
}
storedPass[4] = '\0'; // Null-terminate the stored password
}
///////////////////////////////////////// Add ID to EEPROM ///////////////////////////////////
void writeID(byte a[]) {
if (!findID(a)) { // Before we write to the EEPROM, check to see if we have seen this card before!
uint8_t num = EEPROM.read(0); // Get the number of used spaces, position 0 stores the number of ID cards
uint8_t start = (num * 8) + 10; // Figure out where the next slot starts
num++; // Increment the counter by one
EEPROM.write(0, num); // Write the new count to the counter
for (uint8_t j = 0; j < 4; j++) { // Loop 4 times
EEPROM.write(start + j, a[j]); // Write the array values to EEPROM in the right position
}
storePassword(start + 4);
BlinkLEDS(greenLed);
lcd.setCursor(0, 1);
lcd.print("Added");
delay(1000);
}
else {
BlinkLEDS(redLed);
lcd.setCursor(0, 0);
lcd.print("Failed!");
lcd.setCursor(0, 1);
lcd.print("ID already exists");
delay(2000);
}
}
///////////////////////////////////////// Remove ID from EEPROM ///////////////////////////////////
void deleteID(byte a[]) {
if (!findID(a)) { // Before we delete from the EEPROM, check to see if we have this card!
BlinkLEDS(redLed); // If not
lcd.setCursor(0, 0);
lcd.print("Failed!");
lcd.setCursor(0, 1);
lcd.print("ID not found");
delay(2000);
}
else {
uint8_t num = EEPROM.read(0); // Get the number of used spaces, position 0 stores the number of ID cards
uint8_t slot; // Slot number of the card
uint8_t start; // Starting position in EEPROM
uint8_t looping; // The number of times the loop repeats
uint8_t j;
uint8_t count = EEPROM.read(0); // Read the first Byte of EEPROM that stores number of cards
slot = findIDSLOT(a); // Figure out the slot number of the card to delete
start = (slot * 8) + 10;
looping = ((num - slot)) * 8;
num--; // Decrement the counter by one
EEPROM.write(0, num); // Write the new count to the counter
for (j = 0; j < looping; j++) { // Loop the card shift times
EEPROM.write(start + j, EEPROM.read(start + 8 + j)); // Shift the array values to 8 places earlier in the EEPROM
}
for (uint8_t k = 0; k < 8; k++) { // Clear the remaining space
EEPROM.write(start + j + k, 0);
}
BlinkLEDS(blueLed);
lcd.setCursor(0, 1);
lcd.print("Removed");
delay(1000);
}
}
///////////////////////////////////////// Check Bytes ///////////////////////////////////
boolean checkTwo(byte a[], byte b[]) {
match = true; // Assume they match at first
for (uint8_t k = 0; k < 4; k++) { // Loop 4 times
if (a[k] != b[k]) { // If a != b then set match = false
match = false;
break;
}
}
return match;
}
///////////////////////////////////////// Find Slot ///////////////////////////////////
uint8_t findIDSLOT(byte find[]) {
uint8_t count = EEPROM.read(0); // Read the first Byte of EEPROM
for (uint8_t i = 1; i <= count; i++) { // Loop once for each EEPROM entry
readID(i); // Read an ID from EEPROM, stored in storedCard[4]
if (checkTwo(find, storedCard)) { // Check if the storedCard read from EEPROM matches
return i; // Return the slot number of the card
}
}
return 255; // Return an invalid slot if not found
}
///////////////////////////////////////// Find ID From EEPROM ///////////////////////////////////
boolean findID(byte find[]) {
uint8_t count = EEPROM.read(0); // Read the first Byte of EEPROM
for (uint8_t i = 1; i <= count; i++) { // Loop once for each EEPROM entry
readID(i); // Read an ID from EEPROM, stored in storedCard[4]
if (checkTwo(find, storedCard)) { // Check if the storedCard read from EEPROM matches
return true;
}
}
return false;
}
///////////////////////////////////////// Blink LEDs For Indication ///////////////////////////////////
void BlinkLEDS(int led) {
digitalWrite(blueLed, LOW); // Make sure blue LED is off
digitalWrite(redLed, LOW); // Make sure red LED is off
digitalWrite(greenLed, LOW); // Make sure green LED is off
for (int i = 0; i < 3; i++) {
digitalWrite(BuzzerPin, HIGH);
digitalWrite(led, HIGH);
delay(200);
digitalWrite(led, LOW);
digitalWrite(BuzzerPin, LOW);
delay(200);
}
}
////////////////////// Check if readCard is masterCard ///////////////////////////////////
boolean isMaster(byte test[]) {
return checkTwo(test, masterCard);
}
/////////////////// Counter to check if reset/wipe button is pressed or not /////////////////////
bool monitorWipeButton(uint32_t interval) {
unsigned long currentMillis = millis(); // Grab current time
while (millis() - currentMillis < interval) {
int timeSpent = (millis() - currentMillis) / 1000;
lcd.setCursor(10, 1);
lcd.print(timeSpent);
// Check every half a second
if (((uint32_t)millis() % 500) == 0) {
if (digitalRead(wipeB) != LOW) {
return false;
}
}
}
return true;
}
////////////////////// Print Info on LCD ///////////////////////////////////
void ShowOnLCD() {
lcd.clear();
if (RFIDMode == false) {
lcd.setCursor(0, 0);
lcd.print("Enter Password");
lcd.setCursor(0, 1);
}
else if (RFIDMode == true) {
lcd.setCursor(0, 0);
lcd.print(" Access Control");
lcd.setCursor(0, 1);
lcd.print(" Scan a Tag");
}
}
////////////////////// Store Passwords in EEPROM ///////////////////////////////////
void storePassword(int j) {
int k = j + 4;
BlinkLEDS(blueLed);
lcd.clear();
lcd.print("New Password:");
lcd.setCursor(0, 1);
while (j < k) {
char key = newKey.getKey();
if (key) {
lcd.print("*");
EEPROM.write(j, key);
j++;
}
}
}
////////////////////// Match Passwords ///////////////////////////////////
void matchpass() {
RFIDMode = false;
ShowOnLCD();
i = 0;
while (i < 4) { // Wait until we get 4 keys
key_pressed = newKey.getKey(); // Store new key
if (key_pressed) {
password[i++] = key_pressed; // Storing in password variable
lcd.print("*");
}
}
password[4] = '\0'; // Null-terminate the password string
delay(200);
if (strncmp(password, masterPass, 4) == 0) { // If password is matched
RFIDMode = true;
programMode = true;
i = 0;
}
else { // If password is not matched
lcd.clear();
lcd.print("Wrong Password");
digitalWrite(BuzzerPin, HIGH);
delay(1000);
digitalWrite(BuzzerPin, LOW);
programMode = false;
RFIDMode = true;
ShowOnLCD();
i = 0;
}
}
After you upload the code to uno, Test the circuit.
You can use an external power supply or the USB power supply from a cable.
To register the tag follow the instructions given above, I will put this circuit on a piece of cardboard.
This mere electronics setup can be made more interesting to look like a gate system.
In my case i will use hot glue and double sided tape, You can follow my placements.
There is no rule to follow this exact setup, feel free to customize this model.
Using this project is very simple, Just power on the board and you can see the message on LCD module.
Tap on the RFID board and then your tag, Then enter the password, i had 2222 and 3333 as default.
Now the servo/gate opens only when the password is correct if it is not it will show error message.
This is all about this project, Dont miss to check the working video here.
Have a great build and if you have any questions ask in the comments, Thanks and have a great day.