// MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START * MACRO-START *
#define dbg(myFixedText, variableName) \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName);
#define dbgi(myFixedText, variableName,timeInterval) \
{ \
static unsigned long intervalStartTime; \
if ( millis() - intervalStartTime >= timeInterval ){ \
intervalStartTime = millis(); \
Serial.print( F(#myFixedText " " #variableName"=") ); \
Serial.println(variableName); \
} \
}
#define dbgc(myFixedText, variableName) \
{ \
static long lastState; \
if ( lastState != variableName ){ \
Serial.print( F(#myFixedText " " #variableName" changed from ") ); \
Serial.print(lastState); \
Serial.print( F(" to ") ); \
Serial.println(variableName); \
lastState = variableName; \
} \
}
#define dbgcf(myFixedText, variableName) \
{ \
static float lastState; \
if ( lastState != variableName ){ \
Serial.print( F(#myFixedText " " #variableName" changed from ") ); \
Serial.print(lastState); \
Serial.print( F(" to ") ); \
Serial.println(variableName); \
lastState = variableName; \
} \
}
// MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END * MACRO-END *
/**
derived from the Arduino Calculator
Copyright (C) 2020, Uri Shaked.
Released under the MIT License.
*/
#include <LiquidCrystal.h>
#include <Keypad.h>
/* Display */
LiquidCrystal lcd(12, 11, 10, 9, 8, 7);
/* original
const int rs = A0, en = A1, d4 = A2, d5 = A3, d6 = A4, d7 = A5;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
*/
bool passcodeEntered = false;
bool asteriskPressed = false;
const int LED = 13; // original 2
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] = {5, 4, 3, 2};
byte colPins[COLS] = {A3, A2, A1, A0};
/* original
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() {
Serial.begin(115200);
Serial.println("Setup-Start");
pinMode(LED, OUTPUT);
lcd.begin(16, 2);
lcd.print("Enter Passcode:");
}
void loop() {
char key = keypad.getKey();
dbgc("ToL",key);
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("*");
}
}
}