123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229 |
- #include <Arduino.h>
- #include <Keypad/Keypad.h>
- #include <LiquidCrystal.h>
-
-
- #define KP_ROWS 4
- #define KP_COLS 4
- 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);
-
-
- #define LCD_ROWS 2
- #define LCD_COLS 16
- LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
-
-
- #define SELF_TEST_LABEL "Self testing..."
- #define SELF_TEST_ERROR_LABEL "Error: "
- #define UID_LABEL "UID:"
- #define PWD_LABEL "PWD:"
- #define LOGIN_IN_PROGRESS "Login..."
- #define LOGIN_FAILED "Login failed"
- #define LOGIN_SUCCESS "Access granted"
-
- #define UID_MAX_LEN 12
- #define PWD_MAX_LEN 12
- String uid;
- String password;
- enum Status {
- Uid,
- Password,
- SelfTest,
- LoginInProgress,
- LoginFailed,
- LoginSuccess
- };
- Status status = Uid;
-
- #define MAX_IDLE_TIME 20
- unsigned long lastActivity = 0;
-
- #define LOGIN_FAILED_TIME 2
-
- #define SELF_TEST_INTERVAL 60
- #define SELF_TEST_ERROR_INTERVAL 2
- #define MAX_SELF_TEST_TIME 5
- unsigned long lastSelfTest = 0;
- #define SELF_TEST_NO_ERROR '0'
- int lastSelfTestResult = SELF_TEST_NO_ERROR;
-
- void setup() {
- Serial.begin(9600);
- Serial.println("Starting...");
-
- 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()
- {
- Serial.println("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 != SELF_TEST_NO_ERROR) {
- 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);
-
- Serial.println(uid);
- Serial.println(password);
-
- status = LoginSuccess;
- updateLcd();
-
- delay(LOGIN_FAILED_TIME * 1000);
-
- askUidPassword();
- }
-
- void selfTest()
- {
- lastSelfTest = SELF_TEST_NO_ERROR;
- status = SelfTest;
- updateLcd();
-
- bool test = true;
- while (test) {
- unsigned long secs = millis() / 1000;
- Serial.println("Self Testing");
- while (Serial.available() == 0 && (millis() / 1000) - secs < MAX_SELF_TEST_TIME);
- if (Serial.available() > 0) {
- lastSelfTestResult = Serial.read();
- if (lastSelfTestResult == SELF_TEST_NO_ERROR) {
- test = false;
- }
- else {
- updateLcd();
- delay(SELF_TEST_ERROR_INTERVAL * 1000);
- }
- }
- }
- lastSelfTest = millis() / 1000;
- askUidPassword();
- }
|