/*
Forum: https://forum.arduino.cc/t/the-lcd-screen-doesnt-show-the-input-from-the-keypad/1232826
Wokwi: https://wokwi.com/projects/391797529307245569
*/
#include <LiquidCrystal.h>
#include <Keypad.h>
// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(8, 9, 10, 11, 12, 13);
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
int button = A5;
int board = A3;
//define the symbols on the buttons of the keypads
char timeobj;
char keys[ROWS][COLS] = {
{'1', '2', '3', 'A'},
{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {7, 6, 5, 4}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {3, 2, 1, 0}; //connect to the column pinouts of the keypad
enum StatusType { INPUTCODE, INPUTTEMPO, GUESSCODE, SOLVED, HACKED, FAILED, WAIT};
StatusType status;
unsigned long codiceSegreto = 0;
String inputString;
int tempoTimer = 0;
int countDown = 0;
bool codiceInserito = false;
unsigned long startTime;
unsigned long countDownTime;
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
char key;
void setup() {
lcd.begin(16, 2);
pinMode(board, INPUT);
pinMode(button, INPUT_PULLUP);
setNewStatus(INPUTCODE);
}
void loop() {
handleKeypad();
handleTimer();
handleHacking();
StateMachine();
}
void handleKeypad() {
key = keypad.getKey();
}
void StateMachine() {
switch (status) {
case INPUTCODE:
handleCodeInput();
break;
case INPUTTEMPO:
handleTempoInput();
break;
case GUESSCODE:
guessCode();
break;
case SOLVED:
solved();
break;
case HACKED:
handleHacked();
break;
case FAILED:
failed();
break;
case WAIT:
handleWait();
break;
}
}
void handleWait() {
if (key == 'A') {
setNewStatus(GUESSCODE);
}
if (key == 'D') {
setNewStatus(INPUTCODE);
}
}
void setNewStatus(StatusType newStatus) {
inputString = "";
switch (newStatus) {
case INPUTCODE:
clearLCD("Inserisci codice:");
break;
case SOLVED:
codiceInserito = false;
break;
case FAILED:
codiceInserito = false;
startTime = millis();
break;
case GUESSCODE:
lcd.clear();
codiceInserito = true;
countDownTime = millis();
countDown = tempoTimer + 1;
break;
case WAIT:
clearLCD("Again with 'A'", "New with 'D'");
break;
}
status = newStatus;
}
void clearLCD(String line) {
lcd.clear();
lcd.print(line);
}
void clearLCD(String line0, String line1) {
clearLCD(line0);
lcd.setCursor(0, 1);
lcd.print(line1);
}
boolean keyIsNumber() {
return (key >= '0' && key <= '9');
}
void addNumberToInputString(int maxLen) {
if (keyIsNumber() && inputString.length() < maxLen) {
inputString += key;
lcd.setCursor(0, 1);
lcd.print(inputString);
}
}
void handleCodeInput() {
addNumberToInputString(8);
if (key == '#' && inputString.length() >= 3) { // Use in minimum three numbers
codiceSegreto = inputString.toInt();
clearLCD("Inserisci tempo:");
setNewStatus(INPUTTEMPO);
}
}
void handleTempoInput() {
addNumberToInputString(2);
if (key == '*' && inputString.toInt() >= 5) { // Give in minimum five seconds
tempoTimer = inputString.toInt();
clearLCD("Codice e tempo", "inseriti!");
delay(2000);
setNewStatus(GUESSCODE);
}
}
void guessCode() {
addNumberToInputString(8);
if (key == 'C') {
unsigned long guess = inputString.toInt();
codiceInserito = false;
if (guess == codiceSegreto) {
setNewStatus(SOLVED);
} else {
setNewStatus(FAILED);
}
}
}
void failed() {
lcd.clear();
lcd.print("Ordigno detonato");
if (millis() - startTime > 3000 ) {
clearLCD("Out of business ...");
delay(10000);
setNewStatus(WAIT);
}
}
void solved() {
clearLCD("ordigno","disinnescato");
delay(3000);
setNewStatus(WAIT);
}
void handleHacked() {
clearLCD("Hacking ....");
delay(1000);
setNewStatus(SOLVED);
}
void handleTimer() {
static unsigned long lastCountDown = 0;
if (codiceInserito && countDown > 0) {
if (lastCountDown == 0) {
lastCountDown = millis();
}
if (millis() - lastCountDown > 1000) {
lastCountDown = millis();
countDown--;
lcd.setCursor(0, 0);
lcd.print("Count Down: ");
lcd.setCursor(12, 0);
lcd.print(countDown);
}
if (countDown == 0) {
setNewStatus(FAILED);
}
} else {
lastCountDown = 0;
}
}
void handleHacking() {
if (!codiceInserito) {
return;
}
if (digitalRead(button) == LOW ||
digitalRead(board) == HIGH) {
setNewStatus(HACKED);
}
}