Door Lock Security System Using RFID, KEYPAD, I2c LCD 16x2

help me make an arduino uno based door lock which can store multiple rfid card in eeprom memory and a pin which can also be stored in the eeprom memory the pin and card should be changeable and should automatically stored in eeprom so that the uno can be restarted. for input we are using 4x4 keypad for display using i2c 16x2 display for rfic mcr522 sensor. Also the first time the code run it will ask to set a master pin which will than get stored in the eeprom than after storing it will change a variable in the eeprom which will help later letting the program know that a pin is set already and will not display the pin setting program again on startup to change the pin there will be options on the display to choose and after confirming the pin than only the pin can be changed.

I have Made Some Progress will share the code till now.

Be sure to format the code by clicking the < CODE > button and pasting your code where you see '''type or paste code here'''

#include <Keypad.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include <MFRC522.h>
#include <SPI.h>

#define MASTER_PIN_ADDRESS 0 // EEPROM address to store master pin
#define CARD_COUNT_ADDRESS 1 // EEPROM address to store card count
#define MAX_CARDS 10
#define MAX_PIN_LENGTH 4
#define RST_PIN         11          // Reset pin
#define SS_PIN          10   

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] = {A1, 8, 7, 6}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {5, 4, 3, 2}; //connect to the column pinouts of the keypad
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);

LiquidCrystal_I2C lcd(0x27, 16, 2); // Set the LCD address to 0x27 for a 16 chars and 2 line display

MFRC522 mfrc522(SS_PIN, RST_PIN); // Create MFRC522 instance

char masterPin[MAX_PIN_LENGTH + 1]; // Variable to store master pin
bool masterPinSet = false; // Flag to check if master pin is set
byte cardCount = 0; // Number of cards stored

void setup() {
  Serial.begin(9600);
  SPI.begin(); // Init SPI bus
  mfrc522.PCD_Init(); // Init MFRC522
  lcd.begin(); // Initialize the lcd
  lcd.backlight();
  
  // Check if master pin is set
  masterPinSet = EEPROM.read(MASTER_PIN_ADDRESS);
  if (masterPinSet==0) {
    setMasterPin();
  }

  // Retrieve card count from EEPROM
  cardCount = EEPROM.read(CARD_COUNT_ADDRESS);
}

void setMasterPin() {
  lcd.clear();
  lcd.print("Set Master PIN:");
  char tempPin[MAX_PIN_LENGTH + 1];
  int index = 0;
  
  while (true) {
    char key = keypad.getKey();
    if (key != NO_KEY) {
      if (key == '#') {
        if (index > 0) {
          tempPin[index] = '\0';
          strcpy(masterPin, tempPin);
          EEPROM.put(MASTER_PIN_ADDRESS, masterPin);
          masterPinSet = true;
          EEPROM.write(MASTER_PIN_ADDRESS, 1); // Set flag to indicate master pin is set
          lcd.clear();
          lcd.print("Master PIN Set");
          delay(1000);
          return;
        }
      } else if (index < MAX_PIN_LENGTH && isDigit(key)) {
        tempPin[index++] = key;
        lcd.setCursor(index - 1, 1);
        lcd.print('*');
      }
    }
  }
}

bool addCardToMemory() {
  if (cardCount >= MAX_CARDS) {
    lcd.clear();
    lcd.print("Max cards reached");
    delay(1000);
    return false;
  }
  
  lcd.clear();
  lcd.print("Present a card");
  
  // Wait for card
  if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
    return false;
  }
  
  // Read UID
  String cardUID = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    cardUID.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));
    cardUID.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  
  // Check if card already exists
  for (int i = 0; i < cardCount; i++) {
    String storedUID = "";
    for (int j = 0; j < 4; j++) {
      storedUID.concat(String(EEPROM.read(MASTER_PIN_ADDRESS + 1 + i * 4 + j), HEX));
    }
    if (cardUID == storedUID) {
      lcd.clear();
      lcd.print("Card already exists");
      delay(1000);
      return false;
    }
  }
  
  // Store card in EEPROM
  for (int i = 0; i < 4; i++) {
    EEPROM.write(MASTER_PIN_ADDRESS + 1 + cardCount * 4 + i, strtoul(cardUID.substring(i * 2, i * 2 + 2).c_str(), NULL, 16));
  }
  cardCount++;
  EEPROM.write(CARD_COUNT_ADDRESS, cardCount);
  
  lcd.clear();
  lcd.print("Card added");
  delay(1000);
  return true;
}

void removeCardFromMemory() {
  lcd.clear();
  lcd.print("Present card");
  
  // Wait for card
  if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
    return;
  }
  
  // Read UID
  String cardUID = "";
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    cardUID.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));
    cardUID.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  
  // Check if card exists and remove it
  for (int i = 0; i < cardCount; i++) {
    String storedUID = "";
    for (int j = 0; j < 4; j++) {
      storedUID.concat(String(EEPROM.read(MASTER_PIN_ADDRESS + 1 + i * 4 + j), HEX));
    }
    if (cardUID == storedUID) {
      // Shift remaining cards to fill the gap
      for (int k = i; k < cardCount - 1; k++) {
        for (int j = 0; j < 4; j++) {
          EEPROM.write(MASTER_PIN_ADDRESS + 1 + k * 4 + j, EEPROM.read(MASTER_PIN_ADDRESS + 1 + (k + 1) * 4 + j));
        }
      }
      cardCount--;
      EEPROM.write(CARD_COUNT_ADDRESS, cardCount);
      
      lcd.clear();
      lcd.print("Card removed");
      delay(1000);
      return;
    }
  }
  
  lcd.clear();
  lcd.print("Card not found");
  delay(1000);
}

void handlePinInput(char key) {
  static char enteredPin[MAX_PIN_LENGTH + 1];
  static int index = 0;
  
  if (key == '*') {
    // Asterisk (*) entered, clear entered PIN
    memset(enteredPin, 0, sizeof(enteredPin));
    index = 0;
    lcd.clear();
    lcd.print("Enter PIN:");
    return;
  }
  
  if (key == '#') {
    // Pound (#) entered, verify PIN
    if (index == MAX_PIN_LENGTH) {
      enteredPin[index] = '\0';
      if (strcmp(enteredPin, masterPin) == 0) {
        unlockDoor(); // Correct PIN entered, unlock door
      } else {
        lcd.clear();
        lcd.print("Invalid PIN");
        delay(1000);
        lcd.clear();
        lcd.print("Standby Mode");
      }
    } else {
      lcd.clear();
      lcd.print("Invalid PIN");
      delay(1000);
      lcd.clear();
      lcd.print("Standby Mode");
    }
    return;
  }
  
  // Append digit to entered PIN
  if (index < MAX_PIN_LENGTH && isDigit(key)) {
    enteredPin[index++] = key;
    lcd.setCursor(index - 1, 1);
    lcd.print('*');
  }
}

void masterMode() {
  lcd.clear();
  lcd.print("Master Mode");
  lcd.setCursor(0, 1);
  lcd.print("1: Change PIN");
  lcd.setCursor(0, 2);
  lcd.print("2: Add Card");
  lcd.setCursor(0, 3);
  lcd.print("3: Remove Card");
  
  while (true) {
    char key = keypad.getKey();
    if (key == '1') {
      changeMasterPin();
      return;
    } else if (key == '2') {
      addCardToMemory();
      return;
    } else if (key == '3') {
      removeCardFromMemory();
      return;
    }
    delay(1000);
  }
}

void changeMasterPin() {
  lcd.clear();
  lcd.print("Enter new PIN:");
  char newPin[MAX_PIN_LENGTH + 1];
  int index = 0;
  
  while (true) {
    char key = keypad.getKey();
    if (key == '#') {
      if (index == MAX_PIN_LENGTH) {
        newPin[index] = '\0';
        strcpy(masterPin, newPin);
        EEPROM.put(MASTER_PIN_ADDRESS, masterPin);
        lcd.clear();
        lcd.print("PIN changed");
        delay(1000);
        lcd.clear();
        lcd.print("Standby Mode");
        return;
      }
    } else if (index < MAX_PIN_LENGTH && isDigit(key)) {
      newPin[index++] = key;
      lcd.setCursor(index - 1, 1);
      lcd.print('*');
    }
    delay(100);
  }
}

void unlockDoor() {
  // Implement your door unlocking mechanism here.
  // For example, you can activate a relay connected to the door lock.
}

void handleCardDetection() {
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    String cardUID = "";
    for (byte i = 0; i < mfrc522.uid.size; i++) {
      cardUID.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));
      cardUID.concat(String(mfrc522.uid.uidByte[i], HEX));
    }
    
    // Check if card exists in memory
    for (int i = 0; i < cardCount; i++) {
      String storedUID = "";
      for (int j = 0; j < 4; j++) {
        storedUID.concat(String(EEPROM.read(MASTER_PIN_ADDRESS + 1 + i * 4 + j), HEX));
      }
      if (cardUID == storedUID) {
        unlockDoor(); // Card matched, unlock door
        return;
      }
    }
    
    lcd.clear();
    lcd.print("Unknown Card");
    delay(1000);
    lcd.clear();
    lcd.print("Standby Mode");
  }
}

void standbyMode() {
  lcd.clear();
  lcd.print("Standby Mode");
  while (true) {
    char key = keypad.getKey();
    if (key == '*') {
      lcd.clear();
      lcd.print("Enter PIN:");
      handlePinInput('*');
      return;
    }
    delay(100);
  }
}

void loop() {
 char key = keypad.getKey();
  if (masterPinSet==1) {
    standbyMode();
  }

  if (key == '#') {
    masterMode(); // Enter master mode
    return;
  }
  
  if (key != NO_KEY && key != '*' && key != '#') {
    handlePinInput(key);
  }

  handleCardDetection();
}

Ask ChatGPT if the code it gave to you works.

1 Like

I do not see how this relates to "Interfacing w/ Software on the Computer". Hence your topic had been moved to a more suitable location on the forum.

Thank You

The code is created by me only I took some reference but gpt isn't following what I want so I did it myself my problem is it gets stuck on standby after setting up the pin I don't know why🥲

Your command of the English language really shows in the program comments only.
You even refer to yourself in the second person?

  // Implement your door unlocking mechanism here.
  // For example, you can activate a relay connected to the door lock.

Where did you copy this? What does it say?

As I told earlier I tried using the code from chatgpt only however the code was not what I wanted so I changed alot in it. And the code is this after changing

I asked gpt to fix the problems many times but found no success in that infact I had to go through the code line by line to understand what was happening and how it was working and tried fixing it my self. The code is compiling perfectly but still I don't know wheather there is a mistake that I made in the standby mode or void loop which is causing it to get stuck on stand by mode after setting up the pin. On first boot. I'm asking for help please help. And sorry for the inconvenience I may have caused.

Here, I will help:

  1. Discard GPT code until you understand how programming works.
  2. Write a sketch for each device until you understand how to use each device and each sketch.
  3. Use your learned skills to create sketches integrating devices.

Why would you want someone else to write code? It won't be your code and you will never know how it works. Enjoy learning and applying your knowledge.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.