Access Control System with RFID and Keypad - RobotDynOfficial/Documentation GitHub Wiki
This scheme implements access to the premises by code or cards. In the normal state, the lock is closed and it is written on the screen. If the correct card is attached to the card reader or the correct code is entered, a beep sounds and the lock opens. New cards or a new code can be registered through a computer.
- Supply voltage: 3.3V;
- Current consumption: 13-26mA;
- Operating frequency: 13.56MHz;
- Reading range: 0 - 60 mm;
- Interface: SPI, I2C;
- Transmission rate: maximum 10MBit / s;
- Size: 30mm x 30mm.
- Microchip: PN532;
- Logic: CMOS, 3.3V;
- Supply voltage: 3.3-5V;
- Maximum current consumption: 150 mA;
- Current consumption in standby mode: 100 mA;
- Current consumption in read mode: 120 mA;
- Current consumption in recording mode: 120 mA;
- Reading range: 5 - 7 cm;
- Antenna: built-in, on the board;
- Dimensions: 42.7 x 40.4 mm.
- LCD1602 screen
- RFID- MFRC522 or PN532
- 4x4 keyboard
- Arduino UNO
- Buzzer
- Electromagnetic lock
- Connecting wires
Let's assemble the circuit using this table:
Arduino | LCD1602 | Buzzer | keypad | Relay | PN532 | MFRC522 | lock |
---|---|---|---|---|---|---|---|
5V | 5V | VCC | VCC | VCC | 5V | 5V | |
vin | + | ||||||
GND | GND | GND | GND | GND | GND | GND | |
3 | in | ||||||
5 | S | ||||||
A4 | SCL | SCL | MISO | ||||
A5 | SDA | SDA | SDA | ||||
A0 | Out | ||||||
(-) to relay in OUT |
For the correct inclusion of e.m. lock in the circuit, you need to connect a protective diode in parallel with the lock.
Depending on the RFID readers used, install the appropriate libraries:
- PN532_I2C.h RFID library for PN532 I2C
- NfcAdapter.h RFID Library
- LiquidCrystal_I2C.h display library for 16x2 LCD
- EEPROM.h EEPROM memory library
- Wire.h I2C Bus Library
- MFRC522_I2C.h RFID Library for MFRC522
The library "MFRC522_I2C.h" can be downloaded from the link: https://github.com/arozcan/MFRC522-I2C-Library
Connect the Arduino to the computer, open the port monitor at 115200 Baud, enter the word 'card', attach a new card to the reader and write the symbol 's' in the port monitor, if you need to delete this card from memory, write the character 'd'.
To program a new access code, enter "code 1234" in the port monitor, where 1234 is the new code.
#include <PN532_I2C.h> // RFID library PN532 I2C
#include <NfcAdapter.h> // RFID library
#include <LiquidCrystal_I2C.h> // display library 1602
#include <EEPROM.h> // EEPROM memory library
#include <Wire.h> // I2C bus library
#include "MFRC522_I2C.h" // RFID library MFRC522
#define useMFRC522
// # define usePN532
#define keybPin A0
#define beepPin 5
#define relayPin 3
#define timeOpen 6 // how many seconds the lock is open
#define relayLogic 1 // pin state when the lock is open
#define beepLogic 1 // state of the pin when the squeaker sounds
#define lcdAddr 0x38 // I2C display address
#define mfrcAddr 0x2A // I2C address of the reader MFRC522
int keybVals [16] = {325,1020,926,850,674,632,595,504,480,459,784,562,439,235,403,269}; // average signal values for the keyboard
int nowCard;
int degKV;
byte cardSaved [10] [4];
byte uid [4]; byte uidLength;
byte codeT [4];
byte codeE [4];
unsigned long timeRst;
char key;
char keyOld;
byte entCode;
byte cLen;
LiquidCrystal_I2C lcd (lcdAddr, 16.2);
#ifdef usePN532
PN532_I2C pn532i2c (Wire);
PN532 nfc (pn532i2c);
#endif
#ifdef useMFRC522
MFRC522 mfrc522 (mfrcAddr, 2);
#endif
void setup () {
Serial.begin (115200);
Wire.begin ();
lcd.init (); lcd.noBacklight ();
pinMode (relayPin, OUTPUT); digitalWrite (relayPin,! relayLogic);
pinMode (beepPin, OUTPUT); digitalWrite (beepPin,! beepLogic);
pinMode (keybPin, INPUT);
#ifdef usePN532
// Check RFID connection and initialize it
Wire.beginTransmission (0x24);
if (! Wire.endTransmission ()) {
nfc.begin ();
nfc.setPassiveActivationRetries (0x04);
nfc.SAMConfig ();
} else {
Serial.println ("RFID error");
while (1) {}
}
#endif
#ifdef useMFRC522
// Check RFID connection and initialize it
Wire.beginTransmission (mfrcAddr);
if (! Wire.endTransmission ()) {
mfrc522.PCD_Init ();
} else {
Serial.println ("RFID error");
while (1) {}
}
#endif
for (int n = 0; n <10; n ++) {for (int k = 0; k <4; k ++) {cardSaved [n] [k] = EEPROM.read (k + 4 * n);}}
for (int n = 0; n <4; n ++) {codeT [n] = EEPROM.read (n + 50);}
degKV = 1024;
for (int n = 0; n <16; n ++) {
for (int i = 0; i <16; i ++) {
if (i! = n) {
if (abs (keybVals [n] - keybVals [i]) <degKV) {degKV = abs (keybVals [n] - keybVals [i]);}
}
}
}
degKV--;
entCode = 0;
lcdClear ();
lcd.backlight ();
Serial.println ("Std");
}
void loop () {
nowCard = isCard ();
if (nowCard> = 0) {
Serial.println ("Open by card");
beep (700);
lcd.clear (); lcd.setCursor (0,0); lcd.print ("OPEN");
digitalWrite (relayPin, relayLogic);
delay (1000 * timeOpen);
digitalWrite (relayPin,! relayLogic);
lcdClear ();
} else if (nowCard == -2) {
Serial.println ("Wrong card");
beep (200); delay (300); beep (200);
while (isCard ()! = -1) {delay (500);}
delay (500);
}
key = getKey ();
if (key) {
timeRst = millis () + 4000;
beep (70);
if (! entCode) {
lcd.print ("code:");
cLen = 0;
}
lcd.print (key);
codeE [cLen] = key;
cLen ++;
entCode = 1;
if (cLen> = 4) {
if (codeE [0] == codeT [0] && codeE [1] == codeT [1] && codeE [2] == codeT [2] && codeE [3] == codeT [3]) {
Serial.println ("Open by code");
beep (700);
lcd.clear (); lcd.setCursor (0,0); lcd.print ("OPEN");
digitalWrite (relayPin, relayLogic);
delay (1000 * timeOpen);
digitalWrite (relayPin,! relayLogic);
lcdClear ();
} else {
lcd.setCursor (6,1); lcd.print ("Error");
beep (200); delay (300); beep (200);
delay (1500);
timeRst = 0;
}
}
}
if (entCode == 1 && millis ()> timeRst) {
entCode = 0;
lcdClear ();
}
if (Serial.available ()> 0) {
if (Serial.read () == 'c') {
delay (20);
byte sRead = Serial.read ();
if (sRead == 'a') {
if (Serial.read () == 'r' && Serial.read () == 'd') {
Serial.print ("attach card:");
nowCard = isCard ();
while (nowCard! = -1) {nowCard = isCard ();}
#ifdef usePN532
while (! nfc.readPassiveTargetID (PN532_MIFARE_ISO14443A, & uid [0], & uidLength)) {}
#endif
#ifdef useMFRC522
while (! (mfrc522.PICC_IsNewCardPresent () && mfrc522.PICC_ReadCardSerial ())) {}
for (int i = 0; i <4; i ++) {uid [i] = mfrc522.uid.uidByte [i];}
#endif
beep (500);
for (int n = 0; n <4; n ++) {Serial.print (uid [n]); Serial.print ("");} Serial.println ("");
while (Serial.available ()> 0) {Serial.read ();}
Serial.println ("d - delete");
Serial.println ("s - save");
while (Serial.available () <= 0) {}
sRead = Serial.read ();
if (sRead == 's') {
Serial.println ("Saved");
if (EEPROM.read (100)> 9) {EEPROM.write (100, 0);}
for (int k = 0; k <4; k ++) {cardSaved [EEPROM.read (100)] [k] = uid [k]; EEPROM.write (k + 4 * EEPROM.read (100), uid [k ]);}
EEPROM.write (100, EEPROM.read (100) +1);
}
if (sRead == 'd') {
Serial.println ("Deleted");
for (int n = 0; n <10; n ++) {
if (cardSaved [n] [0] == uid [0] && cardSaved [n] [1] == uid [1] && cardSaved [n] [2] == uid [2] && cardSaved [n] [3 ] == uid [3]) {
for (int k = 0; k <4; k ++) {cardSaved [n] [k] = 0; EEPROM.write (k + 4 * n, 0);}
}
}
}
}
} else if (sRead == 'o') {
if (Serial.read () == 'd' && Serial.read () == 'e' && Serial.read () == '') {
byte codeN [4]; byte res = 1;
for (int n = 0; n <4; n ++) {codeN [n] = Serial.read (); if ((codeN [n] <'0' || codeN [n]> '9') && (codeN [n] <'A' || codeN [n]> 'D') && codeN [n]! = '*' && codeN [n]! = '#') {res = 0;}}
if (res) {
Serial.println ("Saved");
for (int n = 0; n <4; n ++) {codeT [n] = codeN [n]; EEPROM.write (n + 50, codeN [n]);}
} else {
Serial.println ("Error");
}
}
}
}
}
}
void lcdClear () {
lcd.clear ();
lcd.setCursor (0,0); lcd.print ("CLOSED");
lcd.setCursor (0,1);
}
int isCard () {
#ifdef usePN532
if (nfc.readPassiveTargetID (PN532_MIFARE_ISO14443A, & uid [0], & uidLength)) {
for (int n = 0; n <10; n ++) {
if (uid [0] == cardSaved [n] [0]) {
if (uid [1] == cardSaved [n] [1]) {
if (uid [2] == cardSaved [n] [2]) {
if (uid [3] == cardSaved [n] [3]) {return n;}
}
}
}
}
return -2;
}
#endif
#ifdef useMFRC522
if (mfrc522.PICC_IsNewCardPresent () && mfrc522.PICC_ReadCardSerial ()) {
for (int i = 0; i <4; i ++) {uid [i] = mfrc522.uid.uidByte [i];}
for (int n = 0; n <10; n ++) {
if (uid [0] == cardSaved [n] [0]) {
if (uid [1] == cardSaved [n] [1]) {
if (uid [2] == cardSaved [n] [2]) {
if (uid [3] == cardSaved [n] [3]) {return n;}
}
}
}
}
return -2;
}
#endif
return -1;
}
char getKey () {
int aReadK = analogRead (keybPin);
if (aReadK <100) {keyOld = 0; return 0;}
if (keyOld> 0) {return 0;}
for (int i = 0; i <16; i ++) {
if (aReadK> keybVals [i] -degKV / 2 && aReadK <keybVals [i] + degKV / 2) {
if (i <10) {if (i + 48! = keyOld) {keyOld = i + 48; return i + 48;} else {return 0;}} else {
if (i == 10 && keyOld! = 10) {keyOld = 10; return 'A';}
if (i == 11 && keyOld! = 11) {keyOld = 11; return 'B';}
if (i == 12 && keyOld! = 12) {keyOld = 12; return 'C';}
if (i == 13 && keyOld! = 13) {keyOld = 13; return 'D';}
if (i == 14 && keyOld! = 14) {keyOld = 14; return '*';}
if (i == 15 && keyOld! = 15) {keyOld = 15; return '#';}
}
}
}
return 0;
}
void beep (int del) {tone (beepPin, 230, del);}
Invalid code:
Invalid card:
Valid code:
Valid card: