#include <Keypad.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>
#include <string.h>
/* ================= LCD ================= */
LiquidCrystal_I2C lcd(0x27, 16, 2); // change to 0x3F if needed
/* ================= PASSWORD ================= */
char password[5];
char entered[5];
int pos = 0;
int attempts = 0;
bool locked = false;
bool changeMode = false;
unsigned long lastFailTime = 0;
/* ================= KEYPAD ================= */
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] = {PA0, PA1, PA2, PA3};
byte colPins[COLS] = {PA4, PA5, PA6, PA7};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
/* ================= OUTPUT PINS ================= */
#define GREEN_LED PB0
#define RED_LED PB1
#define BUZZER PB2
#define RESET_BTN PB3
/* ================= SETUP ================= */
void setup() {
Serial.begin(115200);
Serial.println("Hello, STM32!");
Serial.println("Multi-Level Security System");
pinMode(GREEN_LED, OUTPUT);
pinMode(RED_LED, OUTPUT);
pinMode(BUZZER, OUTPUT);
pinMode(RESET_BTN, INPUT_PULLUP);
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, LOW);
digitalWrite(BUZZER, LOW);
lcd.init();
lcd.backlight();
// Load password from EEPROM (default 1234)
for (int i = 0; i < 4; i++) {
char v = EEPROM.read(i);
if (v < '0' || v > '9')
password[i] = '2' + i;
else
password[i] = v;
}
password[4] = '\0';
lcd.clear();
lcd.print("Enter Password");
}
/* ================= LOOP ================= */
void loop() {
/* -------- ADMIN RESET -------- */
if (digitalRead(RESET_BTN) == LOW) {
locked = false;
attempts = 0;
changeMode = false;
lastFailTime = 0;
digitalWrite(BUZZER, LOW);
digitalWrite(RED_LED, LOW);
lcd.clear();
lcd.print("System Reset");
delay(1500);
lcd.clear();
lcd.print("Enter Password");
}
/* -------- LOCK STATE -------- */
if (locked) {
digitalWrite(RED_LED, HIGH);
digitalWrite(BUZZER, HIGH);
lcd.setCursor(0, 1);
lcd.print("SYSTEM LOCKED ");
delay(500);
return;
}
/* -------- TIMEOUT AFTER FAIL -------- */
if (lastFailTime != 0 && millis() - lastFailTime < 5000) {
lcd.setCursor(0, 1);
lcd.print("Wait 5 seconds ");
return;
}
char key = keypad.getKey();
if (key) {
Serial.print("Key Pressed: ");
Serial.println(key);
// Enter password change mode
if (key == '#' && pos == 0) {
changeMode = true;
lcd.clear();
lcd.print("New Password:");
return;
}
entered[pos] = key;
lcd.setCursor(pos, 1);
lcd.print("*");
pos++;
if (pos == 4) {
entered[4] = '\0';
// Change password
if (changeMode) {
for (int i = 0; i < 4; i++) {
password[i] = entered[i];
EEPROM.write(i, entered[i]);
}
changeMode = false;
lcd.clear();
lcd.print("Pwd Changed!");
Serial.println("Password Updated");
delay(1500);
}
// Correct password
else if (strcmp(entered, password) == 0) {
lcd.clear();
lcd.print("Access Granted");
digitalWrite(GREEN_LED, HIGH);
attempts = 0;
lastFailTime = 0;
Serial.println("ACCESS GRANTED");
}
// Wrong password
else {
lcd.clear();
lcd.print("Access Denied");
digitalWrite(RED_LED, HIGH);
digitalWrite(BUZZER, HIGH);
delay(300);
digitalWrite(BUZZER, LOW);
attempts++;
lastFailTime = millis();
Serial.print("Wrong Attempt: ");
Serial.println(attempts);
}
// Lock system
if (attempts >= 3) {
locked = true;
lcd.clear();
lcd.print("LOCKED!");
Serial.println("SYSTEM LOCKED");
}
pos = 0;
delay(1500);
digitalWrite(GREEN_LED, LOW);
digitalWrite(RED_LED, LOW);
lcd.clear();
lcd.print("Enter Password");
}
}
}