#include <Keypad.h>
#include <LiquidCrystal.h>
#include "icons.h"
extern "C" {
bool checkPassword(uint16_t pwd);
}
const int ROW_NUM = 4;
const int COLUMN_NUM = 4;
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
char keys[ROW_NUM][COLUMN_NUM] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte pin_rows[ROW_NUM] = {5, 4, 3, 2};
byte pin_column[COLUMN_NUM] = {A3, A2, A1, A0};
Keypad keypad = Keypad( makeKeymap(keys), pin_rows, pin_column, ROW_NUM, COLUMN_NUM );
int maxAttempts = 3;
int attempts = 0;
bool locked = false;
unsigned long lockStartTime = 0;
unsigned long lockDuration = 10000;
void showStartupMessage() {
lcd.setCursor(4, 0);
lcd.print("Welcome!");
delay(1000);
lcd.setCursor(0, 2);
String message = "HardwareBased v1";
for (byte i = 0; i < message.length(); i++) {
lcd.print(message[i]);
delay(100);
}
delay(500);
}
void showWaitScreen(int delayMillis) {
lcd.setCursor(2, 1);
lcd.print("[..........]");
lcd.setCursor(3, 1);
for (byte i = 0; i < 10; i++) {
delay(delayMillis / 10);
lcd.print("=");
}
}
int inputSecretCode() {
lcd.setCursor(5, 1);
lcd.print("[____]");
lcd.setCursor(6, 1);
int result = 0;
int digitCount = 0;
while (attempts < maxAttempts) {
char key = keypad.getKey();
if (key >= '0' && key <= '9' && digitCount < 4) {
lcd.print('*');
result = result * 10 + (key - '0');
digitCount++;
} else if (key == '*' && digitCount > 0) {
result = 0;
digitCount = 0;
lcd.setCursor(5, 1);
lcd.print("[____]");
lcd.setCursor(6, 1);
} else if (key == '#') {
bool isSame = checkPassword(result);
Serial.println(isSame);
if (isSame == 0) {
attempts++;
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Access denied!");
delay(1000);
lcd.setCursor(0, 0);
Serial.println("Attempt failed, " + String(maxAttempts - attempts) + " attempts left till lockout.");
lcd.print("Attempts left: " + String(maxAttempts - attempts));
showWaitScreen(2000);
showLockedMessage();
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.write(ICON_CHECK);
lcd.setCursor(15, 0);
lcd.write(ICON_CHECK);
lcd.setCursor(1, 1);
Serial.println("Password was correct, access granted.");
lcd.print("Access granted!");
delay(2000);
}
return result;
}
}
return -1;
}
void showInitializeMessage(){
lcd.clear();
lcd.setCursor(1, 0);
lcd.print("Initializing...");
showWaitScreen(1200);
}
void showLockedMessage() {
lcd.clear();
lcd.setCursor(1, 0);
lcd.write(ICON_LOCKED_CHAR);
lcd.print(" Enter pwd: ");
lcd.write(ICON_LOCKED_CHAR);
int userCode = inputSecretCode();
if (userCode == -1){
locked = true;
lockStartTime = millis();
lcd.clear();
lcd.setCursor(0, 0);
lcd.write(ICON_LOCKED_CHAR);
Serial.println("Lockout initiated.");
lcd.print(" System locked!");
lcd.write(ICON_LOCKED_CHAR);
delay(2000);
}
}
void restartSystem() {
lcd.clear();
Serial.println("D button pressed, restarting the whole process...");
attempts = 0;
locked = false;
}
void setup() {
lcd.begin(16, 2);
init_icons(lcd);
Serial.begin(9600);
Serial.println("Welcome to the Serial Monitor!");
Serial.println("---------------------------------");
showStartupMessage();
showInitializeMessage();
showLockedMessage();
}
void loop() {
char key = keypad.getKey();
if (key == 'D') {
restartSystem();
showStartupMessage();
showInitializeMessage();
showLockedMessage();
}
if (locked) {
unsigned long elapsedTime = millis() - lockStartTime;
if (elapsedTime < lockDuration) {
showWaitScreen(lockDuration - elapsedTime);
} else {
locked = false;
attempts = 0;
}
}
}