#include <Keypad.h>
#include <avr/sleep.h>
#include <Wire.h>
const byte ROWS = 4;
const byte COLS = 4;
const byte rowPins[ROWS] = {22, 23, 24, 25};
const byte colPins[COLS] = {26, 27, 28, 29};
const char validChar[75] = "0123456789.!*#><§_DISCOURSE_HOISTED_CODE_0_§-_/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\0";
char keys[ROWS][COLS] = {
{ 1, 2, 3, 4 },
{ 5, 6, 7, 8 },
{ 9, 10, 11, 12 },
{ 13, 14, 15, 16 }
};
const char* keyStringArray[17] = {
".*&!", "abc", "def", "caps",
"ghi", "jkl", "mno", "delete",
"pqrs", "tuv", "wxyz", "save",
" ", "-_/", "#><$", "cancel"
};
const char* keyStringArrayUpper[17] = {
".*&!", "ABC", "DEF", "caps",
"GHI", "JKL", "MNO", "delete",
"PQRS", "TUV", "WXYZ", "save",
" ", "-_/", "#><$", "cancel"
};
const char* keyStringArrayNo[17] = {
"1", "2", "3", "caps",
"4", "5", "6", "delete",
"7", "8", "9", "save",
"", "0", "", "cancel"
};
const char* longPressKeyStringArray[17] = {
"1", "2", "3", "no-",
"4", "5", "6", "",
"7", "8", "9", "",
"", "0", "", "menu"
};
char singlePressKeyButtons[] = {1, 2, 3, 5, 6, 7, 9, 10, 11, 13, 14, 15, '\0'};
char singlePressCmdButtons[] = {4, 8, 12, 16, '\0'};
char longPressCmdButtons[] = {1, 2, 3, 4, 5, 6, 7, 9, 10, 11, 14, 16, '\0'};
static byte kpadState;
char textMode[5] = "no";
byte keyState = 0;
char valueToSend[8] = {};
char keyCounterArray = 0;
char keySaved = -1;
Keypad customKeypad = Keypad( makeKeymap(keys), rowPins, colPins, 4, 4);
unsigned long TimeInMillis;
int customKey;
#define interruptPin 2
const long sleepAfterMs = 10000;
typedef char (* genericFP)();
void printText(const String& text, const char x0, const char y0, const char h) {
}
void clearText() {
}
void setup() {
Serial.begin(9600);
Serial.println("Enter Setup");
pinMode(interruptPin, INPUT_PULLUP); //< Exit sleep mode
customKeypad.begin(makeKeymap(keys));
customKeypad.addEventListener(keypadEvent);
customKeypad.setDebounceTime(20);
customKeypad.setHoldTime(500);
TimeInMillis = millis();
valueToSend[0] = 0;
}
void loop() {
const String mainMenu[1] = { "M1" };
const genericFP mainMenuFunctions[1] = { menu1};
char returnValue = -1;
if ((returnValue = passwordProtect()) == 1) {
if (millis() - TimeInMillis > sleepAfterMs)
goSleep();
valueToSend[0] = 0;
while (browseMenu(3, mainMenu, mainMenuFunctions) >= 0);
goSleep();
}
else if (returnValue == -1) {
goSleep();
}
}
char browseMenu(int menuSize, String menuItem[], genericFP menuFunctions[])
{
unsigned char menuIndex = 0;
char returnChar = -1;
valueToSend[0] = 0;
while (true) {
valueToSend[0] = 0;
customKey = customKeypad.getKey();
if (valueToSend[0] != 0) {
if (strcmp(valueToSend, "save") == 0) {
Serial.println("enter menu item");
valueToSend[0] = 0;
returnChar = menuFunctions[menuIndex]();
if (returnChar == -1) {
return (-1);
}
else if (returnChar == 0) {
return (0);
}
}
else if (isValueInArray(valueToSend[0], "abcABC2")) { //< 'UP' is pressed
Serial.println("menuUP");
if (menuIndex == 0) {
menuIndex = menuSize - 1;
}
else {
--menuIndex;
}
}
else if (isValueInArray(valueToSend[0], "tuvTUV8")) { //< 'DOWN" is pressed
Serial.println("menuDOWN");
++menuIndex;
if (menuIndex > menuSize - 1) {
menuIndex = 0;
}
}
else if (strcmp(valueToSend, "cancel") == 0) {
Serial.println("menuBACK");
clearText();
return (1);
}
else if (strcmp(valueToSend, "menu") == 0) {
Serial.println("menuMENU");
clearText();
return (0);
}
valueToSend[0] = 0;
}
else {
if (millis() - TimeInMillis > sleepAfterMs) {
return -1;
}
}
}
}
char inputString(char* _input, char _inputSize, bool _hidden) {
customKey = -1;
char i = 0;
while (customKey != 12 && i < _inputSize - 1) {
customKey = customKeypad.getKey();
if (valueToSend[0] != 0) {
if (strcmp(valueToSend, "delete") == 0)
{
if (i > 0) {
--i;
_input[i] = 0;
}
}
else if (strcmp(valueToSend, "cancel") == 0) {
clearText();
valueToSend[0] = 0;
return (0);
}
else if (strcmp(valueToSend, "menu") == 0) {
clearText();
valueToSend[0] = 0;
return (-1);
}
else if (strlen(valueToSend) == 1) {
_input[i] = valueToSend[0];
++i;
}
valueToSend[0] = 0;
}
else {
if (millis() - TimeInMillis > sleepAfterMs) {
return -1;
}
}
}
return (1);
}
char passwordProtect() {
char input_pwd[15] = "00000000000000";
char inputReturn = -1;
//EEPROM.get(eep_address, pwd_read);
char pwd[15] = "12000000000000";
while (true)
{
strcpy(input_pwd, "00000000000000");
inputReturn = inputString(input_pwd, 15, true);
if (inputReturn <= 0) {
return (inputReturn);
}
Serial.println("Check password\npwd:");
Serial.println(input_pwd);
if (strcmp(input_pwd, pwd) == 0) {
delay(1500);
return (1);
}
else {
delay(1500);
return (0);
}
}
}
char menu1() {
printText("Should not access here", 0, 0, 8);
}
void goSleep() {
//sleep
}
void wakeUp() {}
int TimeDiffBtwnKeyPress = 2000;
void getKeyFromKeyPress(const char keyVal, const char** charArray) {
if ((millis() - TimeInMillis) < TimeDiffBtwnKeyPress && strstr(charArray[keyVal], valueToSend) != NULL)
keyCounterArray++;
else {
keyCounterArray = 0;
}
TimeInMillis = millis();
if (keyCounterArray >= strlen(charArray[keyVal]))
keyCounterArray = 0;
valueToSend[0] = charArray[keyVal][keyCounterArray];
valueToSend[1] = '\0';
Serial.print("Keypad key :");
Serial.println(valueToSend);
}
//following function is used to cycle through strings
void getCommandFromKeyPress(const char keyVal, const char** charArray) {
TimeInMillis = millis();
if (charArray[keyVal] != "") {
strcpy(valueToSend, charArray[keyVal]);
Serial.print("Keypad Command :");
Serial.println(valueToSend);
}
}
//following function is used for long press functionality
void getCommandFormLongKeyPress(char keyVal) {
TimeInMillis = millis();
if (longPressKeyStringArray[keyVal] != "") {
strcpy(valueToSend, longPressKeyStringArray[keyVal]);
Serial.print("Keypad LongCommand :");
Serial.println(valueToSend);
}
}
void keypadEvent(KeypadEvent key) {
kpadState = customKeypad.getState();
char keyVal = key;
switch (kpadState) {
case PRESSED:
break;
case HOLD:
if (isValueInArray(keyVal, longPressCmdButtons)) {
keyState = 1;
getCommandFormLongKeyPress(keyVal);
}
break;
case RELEASED:
if (keyState == 1)
keyState = 0;
else if (isValueInArray(keyVal, singlePressCmdButtons))
getCommandFromKeyPress(keyVal - 1, keyStringArray);
else if (isValueInArray(keyVal, singlePressKeyButtons)) {
if (strcmp(textMode, "caps") == 0) {
getKeyFromKeyPress(keyVal - 1, keyStringArrayUpper);
}
else if (strcmp(textMode, "no") == 0) {
getKeyFromKeyPress(keyVal - 1, keyStringArrayNo);
}
else {
getKeyFromKeyPress(keyVal - 1, keyStringArray);
}
}
else
getKeyFromKeyPress(keyVal - 1, keyStringArray);
break;
}
if (strcmp(valueToSend, "caps") == 0) {
if (strcmp(textMode, "caps") == 0) {
strcpy(textMode, "small");
}
else {
strcpy(textMode, "caps");
}
}
else if (strcmp(valueToSend, "no") == 0) {
strcpy(textMode, "no");
}
keySaved = keyVal;
}
bool isValueInArray(char val, char *arr) {
for (char i = 0; arr[i] != '\0'; ++i)
{
if (arr[i] == val)
return true;
}
return false;
}