#include #include #include #include "config.h" #include "HostCommunication.h" char keys[KP_ROWS][KP_COLS] = { {'1','2','3','A'}, {'4','5','6','B'}, {'7','8','9','C'}, {'*','0','#','.'} }; byte rowPins[KP_ROWS] = {A3, A2, A0, A1}; byte colPins[KP_COLS] = {8, 9, 10, 11}; Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KP_ROWS, KP_COLS); LiquidCrystal lcd(2, 3, 4, 5, 6, 7); String uid; String password; enum Status { Uid, Password, SelfTest, LoginInProgress, LoginFailed, LoginSuccess }; Status status = Uid; unsigned long lastActivity = 0; unsigned long lastSelfTest = 0; int lastSelfTestResult = ERROR_NONE; HostCommunication hostCommunication; void setup() { hostCommunication.init(); lcd.begin(LCD_COLS, LCD_ROWS); lcd.blink(); lcd.noAutoscroll(); selfTest(); } String makeChars(char c, int count) { char str[count + 1]; memset(str, c, count); str[count] = 0; return String(str); } bool handleUidPassword(String& str, int maxLength, char key) { int len = str.length(); if (key >= '0' && key <= '9') { if (len < maxLength) { str += key; return true; } } else if (key == 'C' || key == '*') { if (len > 0) { str = str.substring(0, len - 1); return true; } else if (status == Password) { status = Uid; return true; } } return false; } void loop() { unsigned long secs = millis() / 1000; if (handleKeyPad()) { lastActivity = secs; updateLcd(); } if ((uid.length() != 0 || password.length() != 0) && secs - lastActivity >= MAX_IDLE_TIME) { askUidPassword(); } if (uid.length() == 0 && password.length() == 0 && secs - lastSelfTest >= SELF_TEST_INTERVAL) { selfTest(); } } bool handleKeyPad() { char key = keypad.getKey(); if (key != NO_KEY) { if (status == Uid) { if (key == '#') { if (uid.length() != 0) { status = Password; return true; } } else { return handleUidPassword(uid, UID_MAX_LEN, key); } } else if (status == Password) { if (key == '#') { if (password.length() != 0) { login(uid, password); return true; } } else { return handleUidPassword(password, PWD_MAX_LEN, key); } } } return false; } void updateLcd() { hostCommunication.debug("Update LCD"); lcd.clear(); if (status == Uid || status == Password) { lcd.setCursor(0, 0); lcd.print(UID_LABEL); lcd.print(uid); lcd.setCursor(0, 1); lcd.print(PWD_LABEL); lcd.print(makeChars('*', password.length())); if (status == Uid) { lcd.setCursor(strlen(UID_LABEL) + uid.length(), 0); } else { lcd.setCursor(strlen(PWD_LABEL) + password.length(), 1); } } else if (status == SelfTest) { lcd.print(SELF_TEST_LABEL); if (lastSelfTestResult != ERROR_NONE) { lcd.setCursor(0, 1); lcd.print(SELF_TEST_ERROR_LABEL); lcd.print(lastSelfTestResult); } } else if (status == LoginInProgress) { lcd.print(LOGIN_IN_PROGRESS); } else if (status == LoginFailed) { lcd.print(LOGIN_FAILED); } else if (status == LoginSuccess) { lcd.print(LOGIN_SUCCESS); } } void askUidPassword() { status = Uid; uid = ""; password = ""; updateLcd(); } void login(String uid, String password) { status = LoginInProgress; updateLcd(); delay(LOGIN_FAILED_TIME * 1000); hostCommunication.login(uid, password); status = LoginSuccess; updateLcd(); delay(LOGIN_FAILED_TIME * 1000); askUidPassword(); } void selfTest() { lastSelfTest = ERROR_NONE; status = SelfTest; updateLcd(); bool test = true; while (test) { hostCommunication.debug("Self Testing"); hostCommunication.selfTest(); HostCommunicationResult res = hostCommunication.read(MAX_SELF_TEST_TIME * 1000); if (!res.isSuccess) { lastSelfTestResult = ERROR_HOST_TIMEOUT; } else if (res.length != sizeof(SERIAL_PACKET_TYPE_INT)) { lastSelfTestResult = ERROR_HOST_PROTOCOL; } else { lastSelfTestResult = *(SERIAL_PACKET_TYPE_INT*)res.data; } delete res.data; if (lastSelfTestResult == ERROR_NONE) { test = false; } else { updateLcd(); delay(SELF_TEST_ERROR_INTERVAL * 1000); } } lastSelfTest = millis() / 1000; askUidPassword(); }