Editorial Solution

From the task, we can understand that we have to make the PIN-enabled locker system. There will be a user pin and master pin and the locker can be accessed by entering the correct user pin.

  • We can store the master pin in the code which won’t change but will be used to reset the user pin.
  • We can prompt the user with multiple options such as Accessing the locker, updating the user PIN, or resetting the user PIN.
    • When accessing the locker we can ask for the user PIN and compare it with the already stored user PIN in the EERPOM and if matches then access is granted else not granted.
    • When updating the user pin, we will ask for the current user pin and match and if the pin is matched, the new pin will be asked from the user and stored in the EEPROM location.
    • When the reset pin option is selected, the user will be prompted to enter the master pin. If the master pin matches with the stored master pin the new pin will be requested for the user pin and stored in the EERPOM location.

Code

#include <EEPROM.h>

#define EEPROM_USER_PIN_ADDR 0  // Starting address for user PIN in EEPROM
#define MASTER_PIN "1234"       // Master PIN for reset (stored as a string)

void setup() {
  Serial.begin(9600);
  Serial.println("Password-Protected Locker System Started!");

  // Check if a user PIN is already set
  if (EEPROM.read(EEPROM_USER_PIN_ADDR) == 255) {  // Uninitialized EEPROM value
    setInitialPIN();                               // Prompt user to set initial PIN
  } else {
    Serial.println("User PIN is already set. Enter your PIN to access.");
  }
}


void loop() {
  Serial.println("\nMain Menu:");
  Serial.println("1. Enter PIN to Unlock");
  Serial.println("2. Update User PIN");
  Serial.println("3. Reset PIN with Master PIN");
  Serial.print("Choose an option (1-3): ");
  while (Serial.available() == 0)
    ;  // Wait for user input
  int option = Serial.parseInt();
  Serial.println(option);

  switch (option) {
    case 1:
      verifyPIN();
      break;
    case 2:
      updateUserPIN();
      break;
    case 3:
      resetPINWithMaster();
      break;
    default:
      Serial.println("Invalid option. Please try again.");
  }
}


void setInitialPIN() {
  Serial.println("No PIN found. Set a new 4-digit PIN:");
  String newPIN = getValidatedPIN();
  for (int i = 0; i < 4; i++) {
    EEPROM.write(EEPROM_USER_PIN_ADDR + i, newPIN[i]);
  }
  Serial.println("User PIN set successfully!");
}


void verifyPIN() {
  Serial.println("Enter your 4-digit PIN to unlock:");
  String enteredPIN = getValidatedPIN();
  String storedPIN = readStoredPIN();

  if (enteredPIN == storedPIN) {
    Serial.println("Access Granted!");
  } else {
    Serial.println("Incorrect PIN. Access Denied.");
  }
}


void updateUserPIN() {
  Serial.println("Enter your current 4-digit PIN:");
  String currentPIN = getValidatedPIN();
  String storedPIN = readStoredPIN();

  if (currentPIN == storedPIN) {
    Serial.println("Enter your new 4-digit PIN:");
    String newPIN = getValidatedPIN();
    for (int i = 0; i < 4; i++) {
      EEPROM.write(EEPROM_USER_PIN_ADDR + i, newPIN[i]);
    }
    Serial.println("User PIN updated successfully!");
  } else {
    Serial.println("Incorrect current PIN. Update failed.");
  }
}

void resetPINWithMaster() {
  Serial.println("Enter the Master PIN to reset user PIN:");
  String enteredMasterPIN = getValidatedPIN();

  if (enteredMasterPIN == MASTER_PIN) {
    Serial.println("Enter a new 4-digit User PIN:");
    String newPIN = getValidatedPIN();
    for (int i = 0; i < 4; i++) {
      EEPROM.write(EEPROM_USER_PIN_ADDR + i, newPIN[i]);
    }
    Serial.println("User PIN reset successfully!");
  } else {
    Serial.println("Incorrect Master PIN. Reset failed.");
  }
}


String getValidatedPIN() {
  while (true) {
    while (Serial.available() == 0)
      ;                                          // Wait for user input
    String recv = Serial.readStringUntil('\n');  // Read input until newline
    recv.trim();                                 // Remove leading/trailing whitespace and CR/LF


    // Check if input is exactly 4 digits
    if (recv.length() == 4 && isDigits(recv)) {
      return recv;  // Return valid 4-digit PIN
    }

    if (recv.length() > 1)
      Serial.println("Invalid input. Please enter a 4-digit PIN:");
  }
}


bool isDigits(String str) {
  for (int i = 0; i < str.length(); i++) {
    if (!isDigit(str[i])) {
      return false;  // Return false if any character is not a digit
    }
  }
  return true;
}


String readStoredPIN() {
  char pin[5];  // Buffer for 4 digits + null terminator
  for (int i = 0; i < 4; i++) {
    pin[i] = EEPROM.read(EEPROM_USER_PIN_ADDR + i);
  }
  pin[4] = '\0';  // Null-terminate the string
  return String(pin);
}


Code Explanation

Recursive Input Validation

  • The function waits for user input and reads it as a string using Serial.readString().
  • If the input is a 4-digit number, it is returned as valid.
  • If the input is zero or any other character, a recursive call is made to prompt the user again for correct input to handle non-integer values or here in this case handling carriage return or newline characters.
  • Any other integer value will be handled as invalid input.
while (true) {
  while (Serial.available() == 0); // Wait for user input
  String recv = Serial.readStringUntil('\n'); // Read input until newline
  recv.trim(); // Remove leading/trailing whitespace and CR/LF

  // Check if input is exactly 4 digits
  if (recv.length() == 4 && isDigits(recv)) {
    return recv; // Return valid 4-digit PIN
  }
  
 if(recv.length() > 1)
  Serial.println("Invalid input. Please enter a 4-digit PIN:");
}

 

Output

 

Output Video

 

Submit Your Solution