Access Control System with RFID and Keypad - RobotDynOfficial/Documentation GitHub Wiki

Access Control System with RFID and Keypad

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.

RFID MFRC522 Specifications

  • 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.

RFID PN532 Specifications

  • 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.

Example of a finished project:

We will need:

  1. LCD1602 screen
  2. RFID- MFRC522 or PN532
  3. 4x4 keyboard
  4. Arduino UNO
  5. Buzzer
  6. Electromagnetic lock
  7. 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

Connection diagram

For the correct inclusion of e.m. lock in the circuit, you need to connect a protective diode in parallel with the lock.

Libraries:

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

Arduino IDE Settings for Arduino UNO Board

Programming a new access card and code

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.

The 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);}

Results

Invalid code:

Invalid card:

Valid code:

Valid card:

⚠️ **GitHub.com Fallback** ⚠️