#include <Keypad.h>
#include <LiquidCrystal.h>
// Keypad setup
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
char keys[ROWS][COLS] ={
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowPins[ROWS] = {14, 15, 18, 13}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {10, 19, 8, 7}; //connect to the column pinouts of the keypad
//Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const int rs = 12, en = 11, d4 = 5, d5 = 4, d6 = 3, d7 = 2;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
// LED setup
const int ledPin = A2;
// Codes
const char codeA[] = "12345678"; // Countdown
const char codeB[] = "87654321"; // Lock
const char codeC[] = "11223344"; // Unlock
// Variables
char enteredCode[9];
int codeIndex = 0;
enum States { ATTESA, COUNTDOWN, LOCKED, BOOM };
States currentState = ATTESA;
unsigned long countdownStartTime;
unsigned long countdownDuration = 1800000UL; // 30 minutes in milliseconds
void setup() {
Serial.begin(9600);
lcd.begin(16, 2);
pinMode(ledPin, OUTPUT);
digitalWrite(ledPin, LOW);
displayState();
Serial.println("board resettata");
Serial.println(countdownDuration);
keypad.setDebounceTime(10);
}
void loop() {
char key = keypad.getKey();
if (key) {
if (key == '#') {
checkCode();
} else if (key == '*') {
clearCode();
displayState();
} else {
enteredCode[codeIndex++] = key;
displayEnteredCode();
}
}
if (currentState == COUNTDOWN) {
updateCountdown();
}
}
void checkCode() {
if (currentState == LOCKED) {
if (strcmp(enteredCode, codeC) == 0) {
currentState = ATTESA;
displayMessage("Unlocked");
delay(1000);
clearCode();
displayState();
} else {
displayMessage("Locked");
delay(1000);
clearCode();
displayState();
}
return;
}
if (strcmp(enteredCode, codeA) == 0 && currentState == IDLE) {
startCountdown();
} else if (strcmp(enteredCode, codeB) == 0) {
currentState = LOCKED;
countdownStartTime = 0; //reset countdown
displayMessage("Locked");
delay(1000);
clearCode();
displayState();
} else if (currentState == COUNTDOWN && strcmp(enteredCode, codeB) == 0) {
currentState = LOCKED;
displayMessage("Locked");
delay(1000);
clearCode();
displayState();
} else {
displayMessage("Invalid Code");
delay(1000);
clearCode();
displayState();
}
}
void startCountdown() {
// metto in countdownStartTime il momento in millisecondi in cui e' stato avviato il timer
countdownStartTime = millis();
currentState = COUNTDOWN;
displayState();
clearCode();
}
void updateCountdown() {
//Serial.print(countdownDuration);
//Serial.println();
//Serial.print(countdownStartTime);
//Serial.println();
//long remainingMillis = countdownDuration - (millis() - countdownStartTime);
unsigned long remainingMillis = countdownDuration - (millis() - countdownStartTime);
Serial.print(remainingMillis);
Serial.println();
//if (remainingMillis <= 0) {
if (remainingMillis >= countdownDuration) {
digitalWrite(ledPin, HIGH);
displayMessage(">> IGNITION <<");
currentState = BOOM;
delay(5000);
digitalWrite(ledPin, LOW);
displayState();
} else {
unsigned long remainingSeconds = remainingMillis / 1000;
unsigned long minutes = remainingSeconds / 60;
unsigned long seconds = remainingSeconds % 60;
lcd.setCursor(16 - 5, 0); // Right-aligned
if (minutes < 10) lcd.print("0");
lcd.print(minutes);
lcd.print(":");
if (seconds < 10) lcd.print("0");
lcd.print(seconds);
lcd.print(" ");
}
}
void clearCode() {
codeIndex = 0;
memset(enteredCode, 0, sizeof(enteredCode));
}
void displayEnteredCode() {
//lcd.clear();
lcd.setCursor(0,1);
for (int i = 0; i < 15; i++) {
lcd.print("");
}
lcd.setCursor(0,1);
lcd.print("Code: ");
for (int i = 0; i < codeIndex; i++) {
lcd.print(enteredCode[i]);
}
}
void displayMessage(const char* message) {
lcd.clear();
lcd.print(message);
}
void displayState() {
lcd.clear();
switch (currentState) {
case IDLE:
lcd.print("ENTER CODE:");
break;
case COUNTDOWN:
lcd.print("COUNTDOWN:");
break;
case LOCKED:
lcd.print("SYSTEM LOCKED");
break;
case BOOM:
lcd.print("LANCIO ESEGUITO");
break;
}
}