Watson221:
Still pretty darn cool 8)
This may be a better version and allows for a PASSWORD_ENTRY_MODE by pressing the # key to enter your password.
You can add in the LCD stuff..
#define DEBUG_KEYPAD // comment this out to mask the password entry with an asterisk
#include <Keypad.h>
constexpr size_t MAX_PASSWORD_LENGTH = 4;
constexpr uint32_t SECONDS_TO_MILLIS(uint32_t seconds) {
return 1000 * seconds;
};
// function declaration
void onKeyPressed(const char key, size_t position);
enum {
COOP_MODE,
PASSWORD_ENTRY_MODE,
SECURITY_MODE,
UNKNOWN_MODE,
} mode = UNKNOWN_MODE;
char storedPassword[MAX_PASSWORD_LENGTH + 1] = "1234";
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{'1', '2', '3'},
{'4', '5', '6'},
{'7', '8', '9'},
{'*', '0', '#'}
};
byte rowPins[ROWS] = {3, 5, 6, 7};
byte colPins[COLS] = {8, 9, 10};
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
void setup() {
Serial.begin(9600);
pinMode(13, OUTPUT);
}
void loop() {
static uint32_t lastModeChangeMillis = 0;
switch (mode) {
case COOP_MODE:
doCoopModeStuff();
if (char keyEntered = keypad.getKey() == '#') {
mode = PASSWORD_ENTRY_MODE;
Serial.println(keyEntered);
Serial.println(F("Entered Pssword Entry Mode"));
// set up your password entry LCD screen here
}
break;
case PASSWORD_ENTRY_MODE:
if (char* enteredPassword = lookForPassword(keypad, '#', onKeyPressed)) {
Serial.println(enteredPassword);
if (strcmp(enteredPassword, storedPassword) == 0) {
Serial.println(F("SUCCESS: CHANGED TO SECURITY MODE"));
// do something on mode change to SECURITY_MODE
mode = SECURITY_MODE;
digitalWrite(13, HIGH);
lastModeChangeMillis = millis();
} else {
Serial.println(F("EPIC FAIL!"));
}
}
// timeout on password entry
if (millis() - lastModeChangeMillis > SECONDS_TO_MILLIS(30)) {
mode = COOP_MODE;
}
break;
case SECURITY_MODE:
doSecurityModeStuff();
// timer to return to COOP_MODE
if (millis() - lastModeChangeMillis > SECONDS_TO_MILLIS(120)) {
mode = COOP_MODE;
digitalWrite(13, LOW);
}
break;
case UNKNOWN_MODE:
// do you need to programmatically figure out what mode device is in at startup?
// default for now...
mode = COOP_MODE;
break;
}
}
void doCoopModeStuff() {
}
void doSecurityModeStuff() {
}
void onKeyPressed(const char key, size_t position) {
// you can print key entered by using <position> to your lcd
Serial.print(key);
}
char* lookForPassword(Keypad& kpd, const char enterChar, void (*keyPressCallback)(const char key, const size_t position))
{
static char password[MAX_PASSWORD_LENGTH + 1];
static uint8_t idx = 0;
if (char key = kpd.getKey()) {
if (key == enterChar) {
idx = 0;
return password;
} else {
password[idx++] = key;
password[idx] = '\0';
if (idx > MAX_PASSWORD_LENGTH) {
idx = 0;
return password;
}
#ifdef DEBUG_KEYPAD
keyPressCallback(key, idx); // for debug
#else
keyPressCallback('*', idx); // for actual program
#endif
}
}
return nullptr;
}