I have this one project witch is too long to explain so in the most simple way possible:
this project uses a LCD and a LED (also a EEPROM but later after I figure out what's wrong)
When I turn on the arduino:
(LCD)
Enter Passcode:
**
if passcode incorrect go back and try again, if passcode correct:
Press A to start (LED is a replacement for a relay cause I dont have a transistor and a relay laying around plus its just a demo)
When A is pressed:
LED Turn on and LCD says "Press B to stop"
Only after passcode is entered and on the press A to start screen (this is where EEPROM comes in later)
If i press * it will bring me into passcode reset screen and confirm passcode screen which explanation is in the code.
Here is my code:
#include <Keypad.h>
#include <LiquidCrystal.h>
bool passcodeEntered = false;
bool asteriskPressed = false;
const int LED = 2;
const int rs = A0, en = A1, d4 = A2, d5 = A3, d6 = A4, d7 = A5;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const byte ROWS = 4;
const byte COLS = 4;
char hexaKeys[ROWS][COLS] = {
{ '1', '2', '3', 'A' },
{ '4', '5', '6', 'B' },
{ '7', '8', '9', 'C' },
{ '*', '0', '#', 'D' }
};
byte rowPins[ROWS] = { 8, 7, 6, 5 };
byte colPins[COLS] = { 12, 11, 10, 9 };
Keypad keypad = Keypad(makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);
const unsigned long PASSCODE_TIMEOUT = 15000; // 15 seconds
const String DEFAULT_PASSCODE = "1501";
String passcode = "";
enum State {
ENTER_PASSCODE,
PRESS_A_TO_START,
LED_ON,
PASSCODE_CHANGE,
ENTER_NEW_PASSCODE,
CONFIRM_NEW_PASSCODE
};
State currentState = ENTER_PASSCODE;
unsigned long passcodeTimer;
bool passcodeChangeRequested = false;
int passcodeLength = 0; // Variable to keep track of the number of characters entered during passcode reset
void setup() {
pinMode(LED, OUTPUT);
lcd.begin(16, 2);
lcd.print("Enter Passcode:");
Serial.begin(9600);
}
void loop() {
char key = keypad.getKey();
if (key != NO_KEY) {
Serial.print("Key pressed: ");
Serial.println(key);
switch (currentState) {
case ENTER_PASSCODE:
handlePasscodeInput(key);
break;
case PRESS_A_TO_START:
if (key == 'A') {
lcd.clear();
lcd.print("Press B to Stop");
digitalWrite(LED, HIGH); // Turn on the LED
} else if (key == 'B') {
currentState = ENTER_PASSCODE;
passcodeEntered = false;
lcd.clear();
lcd.print("Enter Passcode:");
lcd.setCursor(0, 1);
passcode = "";
digitalWrite(LED, LOW); // Turn off the LED
}
break;
case ENTER_NEW_PASSCODE:
if (key == '#') {
currentState = CONFIRM_NEW_PASSCODE;
passcodeTimer = millis();
lcd.clear();
lcd.print("Confirm Pass:");
} else if (key == 'B') {
currentState = ENTER_PASSCODE;
passcode = "";
passcodeChangeRequested = false;
passcodeLength = 0; // Reset the passcode length
lcd.clear();
lcd.print("Enter Passcode:");
}
break;
case CONFIRM_NEW_PASSCODE:
if (passcodeLength == passcode.length()) { // Check if the passcode length is the same
if (passcode.equals(DEFAULT_PASSCODE)) {
currentState = ENTER_PASSCODE;
lcd.clear();
lcd.print("Passcode set");
delay(2000);
lcd.clear();
lcd.print("Enter Passcode:");
passcode = "";
passcodeLength = 0; // Reset the passcode length
} else {
lcd.clear();
lcd.print("Passcodes don't");
lcd.setCursor(0, 1);
lcd.print("match. Try again.");
delay(2000);
lcd.clear();
lcd.print("Enter New Pass:");
passcode = "";
passcodeLength = 0; // Reset the passcode length
}
} else if (millis() - passcodeTimer >= PASSCODE_TIMEOUT) {
currentState = ENTER_PASSCODE;
lcd.clear();
lcd.print("Timeout");
delay(2000);
lcd.clear();
lcd.print("Enter Passcode:");
passcode = "";
passcodeLength = 0; // Reset the passcode length
}
break;
}
}
}
void handlePasscodeInput(char key) {
if (key == '#') {
if (passcode.equals(DEFAULT_PASSCODE) && !passcodeChangeRequested) {
currentState = PRESS_A_TO_START;
lcd.clear();
lcd.print("Press A to start");
passcodeEntered = true; // Set passcodeEntered to true when the correct passcode is entered
lcd.setCursor(0, 1);
lcd.print("PE"); // Display "PE" on the LCD
} else {
lcd.clear();
lcd.print("Incorrect Password");
lcd.setCursor(0, 1);
lcd.print("Please Try again");
delay(2000);
lcd.clear();
lcd.print("Enter Passcode:");
lcd.setCursor(0, 1);
passcode = "";
passcodeEntered = false; // Set passcodeEntered to false when an incorrect passcode is entered
}
} else if (key == 'A') {
if (currentState == PRESS_A_TO_START && passcodeEntered) {
// Proceed to the passcode reset screen
currentState = PASSCODE_CHANGE;
lcd.clear();
lcd.print("Reset Passcode");
delay(2000);
lcd.clear();
lcd.print("Enter New Pass:");
passcode = "";
passcodeLength = 0; // Reset the passcode length
} else {
lcd.clear();
lcd.print("Invalid Key");
}
} else if (key == 'B') {
currentState = ENTER_PASSCODE;
passcodeEntered = false;
lcd.clear();
lcd.print("Enter Passcode:");
lcd.setCursor(0, 1);
passcode = "";
digitalWrite(LED, LOW); // Turn off the LED
} else if (key != NO_KEY) {
lcd.setCursor(0, 1);
lcd.print(key); // Display the pressed key on the LCD
if (passcode.length() < DEFAULT_PASSCODE.length()) {
passcode += key;
lcd.setCursor(passcode.length() - 1, 1);
lcd.print("*");
}
}
}
Note: asteriskPressed is because when I was focusing on setting up the part of the code where I wanted to make it so when I hold the * key for 5 seconds it should display a asterisks on the lcd for 5 seconds indicating that asterisks pressed is true and I press # to get into the passcode reset screen so just ignore it cause I aint using it right now.
Now for some context, I have a Geni lift and it doesn't have security at all like I undo the emergency button and press the power on button and the thing just turns on. If you dont know a Geni lift can move around so a thief can just drive away. I have everything built Infront of me (so no simulation) and there will be things changing like pressing the * button to change the passcode and adding EEPROM and I will do those later. For now I want to debug why I cant seem to get into the passcode changed menu and I want to test it. The main issue: My keypad works until I get into the Press A to start state. It seems to me that the only 2 keys that do work is A and B nothing else. The keypad does work at the beginning of the whole thing when it asks for a passcode. I removed it but the way I found out was Serial.println(key); and i did that on my lcd too in the handlePasscodeInput function.
Thanks a lot for reading this.