Let's get started with this innovative Arduino tutorial in which you will learn to create your own RFID-based solenoid door lock system using Arduino. You will learn to interface and control the solenoid lock with Arduino and RFID MF-RC522 module. Here, In this project Arduino is used to trigger electromagnetic solenoid lock and RFID is used to authenticate, RFID tags are used as key. Similar systems you must have seen in hotels, metro, gym lockers and other places.
Components Required:
- Arduino Board
- 16x2 LCD
- RC522 RFID Module with Tag and Card
- Buzzer
- 10k Potentiometer
- 560 ohm resistor
- Electromagnetic Lock
- Connecting wires
- Power supply
- BC547 Transistor
- 1N4007 Diode
- Bread Board
What is RC522 RFID Module?
The RC522 is a 13.56MHz RFID module built on the NXP semiconductor's MFRC522 controller. A 4-pin Serial Peripheral Interface (SPI) allows the reader to communicate with a microcontroller at a maximum data rate of 10Mbps.. The module also supports I2C and UART communication. It comes with an RFID card and a key tag having 1KB memory.
A scanning antenna, a transceiver, and a transponder are the three components of every RFID device. An RFID reader is created when the scanning antenna and transceiver are combined. The RFID reader is a network-connected device that can be either portable or fixed. It transmits signals that trigger the tag using radio waves. When the tag is turned on, it sends a wave back to the antenna, which is converted into data.
RFID tags are divided into two categories: passive RFID tags & active RFID tags.
- Active RFID: An active RFID tag has its own source of power, which is usually a battery.
- Passive RFID: The reading antenna, whose electromagnetic wave generates a current in the RFID tag's antenna, provides power to a passive RFID tag.
How to Interface 16x2 LCD with Arduino Uno ?
LCD modules are a critical component in many Arduino-based embedded systems. As a result, understanding how to attach an LCD module to an Arduino is crucial when designing embedded systems. Here you will learn how to connect an Arduino to a 16x2 LCD display.
The JHD162A is a 16x2 LCD module based on Hitachi's HD44780 driver. The JHD162A has 16 pins and can be used in 4-bit or 8-bit mode (using only four data lines) or (using all 8 data lines) respectively. In this case, the LCD module is set to 4-bit mode.
Before going into the details of the project, let’s have a look at the JHD162A LCD module. The schematic of a JHD162A LCD pin diagram is given below.
Pinout:
- Pin1(Vss): Ground pin of the LCD module.
- Pin2(Vcc): Power to LCD module (+5V supply is given to this pin)
- Pin3(VEE): Contrast adjustment pin. This is done by connecting the ends of a 10K potentiometer to +5V and ground and then connecting the slider pin to the VEE pin. The voltage at the VEE pin defines the contrast. The normal setting is between 0.4 and 0.9V.
- Pin4(RS): Register select pin. The JHD162A has two registers namely the command register and data register. Logic HIGH at RS pin selects data register and logic LOW at RS pin selects command register. If we make the RS pin HIGH and feed input to the data lines (DB0 to DB7), this input will be treated as data to display on the LCD screen. If we make the RS pin LOW and feed input to the data lines, then this will be treated as a command ( a command to be written to LCD controller – like positioning cursor or clear screen or scroll).
- Pin5(R/W): Read/Write modes. This pin is used for selecting between reading and write modes. Logic HIGH at this pin activates read mode and logic LOW at this pin activates write mode.
- Pin6(E): This pin is meant for enabling the LCD module. A HIGH to LOW signal at this pin will enable the module.
- Pin7(DB0) to Pin14(DB7): These are data pins. The commands and data are fed to the LCD module through these pins.
- Pin15(Backlight +): Anode of the backlight LED. When operated on 5V, a 560-ohm resistor should be connected in series to this pin. In Arduino-based projects, the backlight LED can be powered from the 3.3V source on the Arduino board.
- Pin16(Backlight -): Cathode of the backlight LED.
How does a Solenoid Lock Work?
A solenoid is a small electromagnet that moves or pulls a plunger to perform a task. In this situation, it either keeps the strike opening closed or allows it to swing open, allowing the door's lock latch to open without having to retrace it. Although the mechanical door lock latch is still engaged when a door strike is released, it is possible to force the door open from the outside (locked). The strike opening simply swings forward, and the latch in the frame's latch pocket is no longer held in place.
Working
In this project MF-RC522 RFID module is used to authenticate, Initially you need to setup a master card. This master card is used for adding new cards or removing existing cards and tags from the memory. If any known card is swiped over the RFID reader door unlocks and if any unknown card is placed over the RFID reader it will show access denied message on LCD screen and buzzer generates a long beep.
Circuit Diagram:
Arduino Code:
#include <EEPROM.h> //Library To read and write RFID Tag's UIDs from/to EEPROM#include <SPI.h> //Library RC522 Module uses SPI protocol
#include <MFRC522.h> //Library RC522 Module
#include <LiquidCrystal.h> //Library for LCD Display
int Relay=A5;
boolean match = false; // initialize card match to false
boolean programMode = false; // initialize programming mode to false
int 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
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance.
LiquidCrystal lcd(7, 6, 5, 4, 3, 2); //Initializing LCD PINS as (RS,EN,D4,D5,D6,D7)
void setup() {
// put your setup code here, to run once:
Serial.begin(9600); // Initialize serial communications with PC
lcd.begin(16, 2); //Initializing LCD 16x2
pinMode(8, OUTPUT); //LED and Buzzer PIN OUT
pinMode(Relay, OUTPUT);
SPI.begin(); // MFRC522 Hardware uses SPI protocol
mfrc522.PCD_Init(); // Initialize MFRC522 Hardware
mfrc522.PCD_SetAntennaGain(mfrc522.RxGain_max);
if (EEPROM.read(1) != 1) { // Look EEPROM if Master Card defined, EEPROM address 1 holds if defined
Serial.println("No Master Card Defined"); //When no Master Card in Your EEROM (Serial Display)
Serial.println("Scan A PICC to Define as Master Card");
lcd.clear();
lcd.setCursor(0, 0);
lcd.println("SET MASTERCARD "); //When no Master Card in Your EEROM (LCD Display)
lcd.setCursor(0, 1);
lcd.println("SCAN A PICC....."); //Scan any RFID CARD to set Your Master Card in Your EEROM (LCD Display)
delay(1500);
do {
successRead = getID(); // sets successRead to 1 when we get read from reader otherwise 0
}
while (!successRead); //the program will not go further while you not get a successful read
for ( int j = 0; j < 4; j++ ) { // Loop 4 times
EEPROM.write( 2 + j, readCard[j] ); // Write scanned PICC's UID to EEPROM, start from address 3
}
EEPROM.write(1, 1); //Write to EEPROM we defined Master Card.
Serial.println("Master Card Defined");
}
Serial.println("Master Card's UID");
for ( int i = 0; i < 4; i++ ) { // Read Master Card's UID from EEPROM
masterCard[i] = EEPROM.read(2 + i); // Write it to masterCard
Serial.print(masterCard[i], HEX); //Master Card only view in serial
Serial.println("Waiting PICCs to bo scanned :)");
}
//WAITING TO SCAN THE RFID CARDS:
Serial.println("");
Serial.println("Waiting PICCs to bo scanned :)");
lcd.clear();
lcd.setCursor(0, 0);
lcd.println("WAITING ");
lcd.setCursor(0, 1);
lcd.println("FOR PICC.... ");
delay(1500);
}
void loop() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" SWIPE");
lcd.setCursor(0, 1);
lcd.print(" YOUR CARD");
/*
if (digitalRead(BUTTON) == HIGH); //To Delete the EEROM USE the below command just run it
{
// for (int i = 0 ; i < EEPROM.length() ; i++) {
// EEPROM.write(i, 0);
// }
// } */
do {
successRead = getID(); // sets successRead to 1 when we get read from reader otherwise 0
if (programMode) {
// Program Mode cycles through RGB waiting to read a new card
}
else {
}}
while (!successRead); //the program will not go further while you not get a successful read
if (programMode) {
if ( isMaster(readCard) ) { //If master card scanned again exit program mode
Serial.println("This is Master Card");
Serial.println("Exiting Program Mode");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("EXITING FROM");
lcd.setCursor(0, 1);
lcd.print("MASTERCARD MODE");
delay(2000);
programMode = false;
return;
}
else {
if ( findID(readCard) ) { //If scanned card is known delete it
Serial.println("I know this PICC, so removing");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("AVAILABLE!");
lcd.setCursor(0, 1);
lcd.print("SO DELETING.....");
delay(5000);
deleteID(readCard);
Serial.println("-----------------------------");
}
else { // If scanned card is not known add it
Serial.println("I do not know this PICC, adding...");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Card no:");
lcd.setCursor(0, 1);
lcd.print(readCard[0], HEX);
lcd.print(readCard[1], HEX);
lcd.print(readCard[2], HEX);
lcd.print(readCard[3], HEX);
lcd.print(readCard[4], HEX);
delay(4000);
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("NOT AVAILABLE");
lcd.setCursor(0, 1);
lcd.print("SO ADDING.......");
delay(5000);
writeID(readCard);
Serial.println("-----------------------------");
}} }
else {
if ( isMaster(readCard) ) { // If scanned card's ID matches Master Card's ID enter program mode
programMode = true;
Serial.println("Welcome to Mastercard Mode");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WELCOME TO");
lcd.setCursor(0, 1);
lcd.print("MASTERCARD MODE");
delay(3000);
int count = EEPROM.read(0); // Read the first Byte of EEPROM that
Serial.print("I have "); // stores the number of ID's in EEPROM
Serial.print(count);
Serial.print(" record(s) on EEPROM");
Serial.println("");
Serial.println("Scan a PICC to ADD or REMOVE");
Serial.println("-----------------------------");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SCAN PICC TO");
lcd.setCursor(0, 1);
lcd.print("ADD OR REMOVE...");
delay(2500);
}
else {
if ( findID(readCard) ) { // If not, see if the card is in the EEPROM
Serial.println("Acces Granted");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" CONGRATULATION");
lcd.setCursor(0, 1);
lcd.print(" ACCESS GRANTED");
digitalWrite(8, HIGH);
digitalWrite(Relay, HIGH);
delay(1500);
digitalWrite(8, LOW);
digitalWrite(Relay, LOW);
lcd.clear();
}
else { // If not, show that the ID was not valid
Serial.println("Access Denied");
for (int abcd = 0; abcd < 6; abcd++)
{
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(" SORRY");
lcd.setCursor(0, 1);
lcd.print(" ACCESS DENIED");
digitalWrite(8, HIGH);
delay(700);
digitalWrite(8, LOW);
lcd.clear();
lcd.print(" YOU'RE NOT ");
lcd.setCursor(0, 1);
lcd.print(" AUTHORIZED ");
delay(700);
}
lcd.clear();
}}}}
int getID() {
// Getting ready for Reading PICCs
if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
return 0;
}
if ( ! mfrc522.PICC_ReadCardSerial()) { //Since a PICC placed get Serial and continue
return 0;
}
// There are Mifare PICCs which have 4 byte or 7 byte UID care if you use 7 byte PICC
// I think we should assume every PICC as they have 4 byte UID
// Until we support 7 byte PICCs
Serial.println("Scanning PICC's UID.........");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SCANNING");
lcd.setCursor(0, 1);
lcd.print("PICC's UID.....");
delay(2000);
for (int i = 0; i < 4; i++) { //
readCard[i] = mfrc522.uid.uidByte[i];
Serial.print(readCard[i], HEX);
}
Serial.println("");
mfrc522.PICC_HaltA(); // Stop reading
return 1;
}
boolean isMaster( byte test[] ) {
if ( checkTwo( test, masterCard ) )
return true;
else
return false;
}
boolean checkTwo ( byte a[], byte b[] ) {
if ( a[0] != NULL ) // Make sure there is something in the array first
match = true; // Assume they match at first
for ( int k = 0; k < 4; k++ ) { // Loop 4 times
if ( a[k] != b[k] ) // IF a != b then set match = false, one fails, all fail
match = false;
}
if ( match ) { // Check to see if if match is still true
return true; // Return true
}
else {
return false; // Return false
}}
boolean findID( byte find[] ) {
int count = EEPROM.read(0); // Read the first Byte of EEPROM that
for ( int i = 1; i <= count; i++ ) { // Loop once for each EEPROM entry
readID(i); // Read an ID from EEPROM, it is stored in storedCard[4]
if ( checkTwo( find, storedCard ) ) { // Check to see if the storedCard read from EEPROM
return true;
break; // Stop looking we found it
}
else { // If not, return false
}}
return false;
}
void readID( int number ) {
int start = (number * 4 ) + 2; // Figure out starting position
for ( int 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
}
}
void deleteID( byte a[] ) {
if ( !findID( a ) ) { // Before we delete from the EEPROM, check to see if we have this card!
failedWrite(); // If not
}
else {
int num = EEPROM.read(0); // Get the numer of used spaces, position 0 stores the number of ID cards
int slot; // Figure out the slot number of the card
int start;// = ( num * 4 ) + 6; // Figure out where the next slot starts
int looping; // The number of times the loop repeats
int j;
int 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 * 4) + 2;
looping = ((num - slot) * 4);
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 + 4 + j)); // Shift the array values to 4 places earlier in the EEPROM
}
for ( int k = 0; k < 4; k++ ) { //Shifting loop
EEPROM.write( start + j + k, 0);
}
successDelete();
}}
//For Failed to add the card:
void failedWrite() {
Serial.println("something wrong with Card");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SOMETHING WRONG");
lcd.setCursor(0, 1);
lcd.print("WITH CARD");
delay(2000);
}
//For Sucessfully Deleted:
void successDelete() {
Serial.println("Succesfully removed");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SUCCESFULLY");
lcd.setCursor(0, 1);
lcd.print("REMOVED");
delay(2000);
}
int findIDSLOT( byte find[] ) {
int count = EEPROM.read(0); // Read the first Byte of EEPROM that
for ( int i = 1; i <= count; i++ ) { // Loop once for each EEPROM entry
readID(i); // Read an ID from EEPROM, it is stored in storedCard[4]
if ( checkTwo( find, storedCard ) ) { // Check to see if the storedCard read from EEPROM
// is the same as the find[] ID card passed
return i; // The slot number of the card
break; // Stop looking we found it
}
}
}
//For Sucessfully Added:
void successWrite() {
Serial.println("Succesfully added");
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("SUCCESFULLY");
lcd.setCursor(0, 1);
lcd.print("ADDED");
delay(2000);
}
//For Adding card to EEROM:
void writeID( byte a[] ) {
if ( !findID( a ) ) { // Before we write to the EEPROM, check to see if we have seen this card before!
int num = EEPROM.read(0); // Get the numer of used spaces, position 0 stores the number of ID cards
int start = ( num * 4 ) + 6; // 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 ( int j = 0; j < 4; j++ ) { // Loop 4 times
EEPROM.write( start + j, a[j] ); // Write the array values to EEPROM in the right position
}
successWrite();
}
else {
failedWrite();
}
}
2 comments
Kapil Kumar
@Taukeer,
https://www.hnhcart.com/ , here is the link from where you can buy all of these components.
Taukeer
I will try to make it. Please provide me with all the components.