Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. #include <Arduino.h>
  2. #include <Keypad/Keypad.h>
  3. #include <LiquidCrystal.h>
  4. #include "config.h"
  5. #include "HostCommunication.h"
  6. char keys[KP_ROWS][KP_COLS] = {
  7. {'1','2','3','A'},
  8. {'4','5','6','B'},
  9. {'7','8','9','C'},
  10. {'*','0','#','.'}
  11. };
  12. byte rowPins[KP_ROWS] = {A3, A2, A0, A1};
  13. byte colPins[KP_COLS] = {8, 9, 10, 11};
  14. Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, KP_ROWS, KP_COLS);
  15. LiquidCrystal lcd(2, 3, 4, 5, 6, 7);
  16. String uid;
  17. String password;
  18. enum Status {
  19. Uid,
  20. Password,
  21. SelfTest,
  22. LoginInProgress,
  23. LoginFailed,
  24. LoginSuccess
  25. };
  26. Status status = Uid;
  27. unsigned long lastActivity = 0;
  28. unsigned long lastSelfTest = 0;
  29. int lastSelfTestResult = ERROR_NONE;
  30. HostCommunication hostCommunication;
  31. void setup() {
  32. hostCommunication.init();
  33. lcd.begin(LCD_COLS, LCD_ROWS);
  34. lcd.blink();
  35. lcd.noAutoscroll();
  36. selfTest();
  37. }
  38. String makeChars(char c, int count) {
  39. char str[count + 1];
  40. memset(str, c, count);
  41. str[count] = 0;
  42. return String(str);
  43. }
  44. bool handleUidPassword(String& str, int maxLength, char key) {
  45. int len = str.length();
  46. if (key >= '0' && key <= '9') {
  47. if (len < maxLength) {
  48. str += key;
  49. return true;
  50. }
  51. }
  52. else if (key == 'C' || key == '*') {
  53. if (len > 0) {
  54. str = str.substring(0, len - 1);
  55. return true;
  56. }
  57. else if (status == Password) {
  58. status = Uid;
  59. return true;
  60. }
  61. }
  62. return false;
  63. }
  64. void loop() {
  65. unsigned long secs = millis() / 1000;
  66. if (handleKeyPad()) {
  67. lastActivity = secs;
  68. updateLcd();
  69. }
  70. if ((uid.length() != 0 || password.length() != 0) && secs - lastActivity >= MAX_IDLE_TIME) {
  71. askUidPassword();
  72. }
  73. if (uid.length() == 0 && password.length() == 0 && secs - lastSelfTest >= SELF_TEST_INTERVAL) {
  74. selfTest();
  75. }
  76. }
  77. bool handleKeyPad()
  78. {
  79. char key = keypad.getKey();
  80. if (key != NO_KEY) {
  81. if (status == Uid) {
  82. if (key == '#') {
  83. if (uid.length() != 0) {
  84. status = Password;
  85. return true;
  86. }
  87. }
  88. else {
  89. return handleUidPassword(uid, UID_MAX_LEN, key);
  90. }
  91. }
  92. else if (status == Password) {
  93. if (key == '#') {
  94. if (password.length() != 0) {
  95. login(uid, password);
  96. return true;
  97. }
  98. }
  99. else {
  100. return handleUidPassword(password, PWD_MAX_LEN, key);
  101. }
  102. }
  103. }
  104. return false;
  105. }
  106. void updateLcd()
  107. {
  108. hostCommunication.debug("Update LCD");
  109. lcd.clear();
  110. if (status == Uid || status == Password)
  111. {
  112. lcd.setCursor(0, 0);
  113. lcd.print(UID_LABEL);
  114. lcd.print(uid);
  115. lcd.setCursor(0, 1);
  116. lcd.print(PWD_LABEL);
  117. lcd.print(makeChars('*', password.length()));
  118. if (status == Uid) {
  119. lcd.setCursor(strlen(UID_LABEL) + uid.length(), 0);
  120. }
  121. else {
  122. lcd.setCursor(strlen(PWD_LABEL) + password.length(), 1);
  123. }
  124. }
  125. else if (status == SelfTest) {
  126. lcd.print(SELF_TEST_LABEL);
  127. if (lastSelfTestResult != ERROR_NONE) {
  128. lcd.setCursor(0, 1);
  129. lcd.print(SELF_TEST_ERROR_LABEL);
  130. lcd.print(lastSelfTestResult);
  131. }
  132. }
  133. else if (status == LoginInProgress) {
  134. lcd.print(LOGIN_IN_PROGRESS);
  135. }
  136. else if (status == LoginFailed) {
  137. lcd.print(LOGIN_FAILED);
  138. }
  139. else if (status == LoginSuccess) {
  140. lcd.print(LOGIN_SUCCESS);
  141. }
  142. }
  143. void askUidPassword()
  144. {
  145. status = Uid;
  146. uid = "";
  147. password = "";
  148. updateLcd();
  149. }
  150. void login(String uid, String password)
  151. {
  152. status = LoginInProgress;
  153. updateLcd();
  154. delay(LOGIN_FAILED_TIME * 1000);
  155. hostCommunication.login(uid, password);
  156. status = LoginSuccess;
  157. updateLcd();
  158. delay(LOGIN_FAILED_TIME * 1000);
  159. askUidPassword();
  160. }
  161. void selfTest()
  162. {
  163. lastSelfTest = ERROR_NONE;
  164. status = SelfTest;
  165. updateLcd();
  166. bool test = true;
  167. while (test) {
  168. hostCommunication.debug("Self Testing");
  169. hostCommunication.selfTest();
  170. HostCommunicationResult res = hostCommunication.read(MAX_SELF_TEST_TIME * 1000);
  171. if (!res.isSuccess) {
  172. lastSelfTestResult = ERROR_HOST_TIMEOUT;
  173. }
  174. else if (res.length != sizeof(SERIAL_PACKET_TYPE_INT)) {
  175. lastSelfTestResult = ERROR_HOST_PROTOCOL;
  176. }
  177. else {
  178. lastSelfTestResult = *(SERIAL_PACKET_TYPE_INT*)res.data;
  179. }
  180. delete res.data;
  181. if (lastSelfTestResult == ERROR_NONE) {
  182. test = false;
  183. }
  184. else {
  185. updateLcd();
  186. delay(SELF_TEST_ERROR_INTERVAL * 1000);
  187. }
  188. }
  189. lastSelfTest = millis() / 1000;
  190. askUidPassword();
  191. }