切到鍵盤輸入模式無法輸入-Arduino中文社区 - Powered by Discuz!

Arduino中文社区

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 352|回复: 1

[未解决] 切到鍵盤輸入模式無法輸入

[复制链接]
发表于 2022-4-23 18:51 | 显示全部楼层 |阅读模式
本帖最后由 neko_0xff 于 2022-4-23 18:53 编辑

各位前輩,不好意思打擾了
我用Mega2560+RFID+Keyboard來組成一個驗証機制的部分,其中用Keyboard來控制顯示於LCD的menu,但進到了輸入密碼的模式就無法進行輸入和驗証
---

功能
  • 使用4x4鍵盤控制
    • A: 退出選擇模式
    • B: +(往上)
    • C: -(往下)
    • D: 確定模式

  • 模式
    • 01 Password
    • 02 RFID
    • 03 Password => RFID
    • 04 RFID => Password

問題
當切到鍵盤輸入模式時,LCD+Serial Port 都無輸出且無法進行驗証
詳細文件

- https://hackmd.io/@zangmenhsu/rJ8gOZeB9

---
程式碼
  1. /*定義按鍵模組*/
  2. #define KEY_ROWS  4        // 按鍵模組的列數
  3. #define KEY_COLS   4       // 按鍵模組的行數

  4. /*接腳*/
  5. #define ledG     A0            //LED GREEN
  6. #define ledR     A1            //LED  RED
  7. #define buzzer  A2          //蜂鳴器
  8. #define RST_PIN        11     //MFRC522:Reset      
  9. #define SS_PIN          12   //MFRC522:SDA

  10. /*定義函式庫&函數*/
  11. #include <LiquidCrystal_I2C.h>
  12. #include <Wire.h>
  13. #include <Keypad.h>   
  14. #include <SPI.h>
  15. #include <MFRC522.h>

  16. void lcd_init();
  17. void updateMenu();
  18. void executeAction();
  19. void bz1();
  20. void bz2();
  21. void mfrc522_init();
  22. void UID_output();
  23. void UID_check();
  24. void bz_time(int pin,int Delaytime);
  25. int unlock_status(int status_event);
  26. void checkPinCode();
  27. void RFIDMode();
  28. void PasswordMode();
  29. void action1();
  30. void action2();
  31. void action3();
  32. void action4();

  33. /*初始化Keypad物件*/
  34. int menu=1;
  35. char rcv;
  36. int sw= 22;
  37. int State = 0;   // 按鈕的狀態
  38. char keymap[KEY_ROWS][KEY_COLS] = {{'1', '2', '3','A'},{'4', '5', '6','B'},{'7', '8', '9','C'},{'*', '0', '#','D'}}; // 依照行、列排列的按鍵字元(二維陣列)
  39. byte rowPins[KEY_ROWS] = { 22, 23, 24, 25}; // 按鍵模組,列從左1~4接腳
  40. byte colPins[KEY_COLS] = {26, 27, 28,29};     // 按鍵模組,行從左5~8接腳。
  41. String inputCode = "";
  42. String passcode = "6789";   // 4x4預設密碼
  43. // 語法:Keypad(makeKeymap(按鍵字元的二維陣列), 模組列接腳, 模組行接腳, 模組列數, 模組行數)
  44. Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, KEY_ROWS, KEY_COLS);
  45. char key_mode = myKeypad.getKey();

  46. /*I2C LCD 設定*/
  47. /*UNO接腳:  SDA: A4 , SCLA: A5 */
  48. /*Mega 2560接腳: SDA:20 , SCLA:21 */
  49. LiquidCrystal_I2C lcd(0x27,16,2);  //設定LCD位置0x27,設定LCD大小為16*2

  50. /*RFID 設定*/
  51. /* UNO接腳:
  52. *  MOSI: 11
  53. *  MISO: 12
  54. *  SCK: 13
  55. */
  56. /*Mega2560接腳:
  57. *  MOSI: 51
  58. *  MISO: 50
  59. *  SCK: 52
  60. */
  61. byte uid[]={0xC5, 0x37, 0x37, 0x45};
  62. MFRC522 mfrc522;   // 建立MFRC522實體

  63. void setup() {
  64.   // put your setup code here, to run once:
  65.   lcd_init();
  66. SPI.begin();
  67. Serial.begin(9600);
  68. pinMode(sw, INPUT_PULLUP); //設定按鈕的接腳為輸入,因為我們要讀取它的狀態
  69. mfrc522_init();
  70. pinMode(ledG, OUTPUT);
  71. pinMode(ledR, OUTPUT);
  72. pinMode(buzzer,OUTPUT);
  73. }

  74. void loop() {
  75.   // put your main code here, to run repeatedly:
  76.   State = digitalRead(sw);  //讀取按鍵的狀態
  77.   int mode;
  78.   char key=myKeypad.getKey();
  79.   Serial.print(key);
  80.   switch(key){
  81.       case 'A':
  82.            lcd.clear();
  83.            lcd.setCursor(0,0);
  84.            lcd.print("Mode Choose:");
  85.            lcd.setCursor(0,1);
  86.            lcd.print(">_<");
  87.            break;
  88.       case 'B':
  89.            menu++; //up
  90.            updateMenu();
  91.            delay(100);
  92.            while(!key=='B');
  93.            break;
  94.       case 'C':
  95.            menu--; //down
  96.            updateMenu();
  97.            delay(100);
  98.            while(!key=='C');
  99.            break;
  100.       case 'D':
  101.            executeAction();
  102.            updateMenu();
  103.            delay(100);
  104.           while(!key=='D');
  105.           break;
  106.   }
  107.   /*
  108.   if(key =='A'){
  109.      lcd.clear();
  110.      lcd.setCursor(0,0);
  111.      lcd.print("Mode Choose:");
  112.      lcd.setCursor(0,1);
  113.      lcd.print(">_<");
  114.   }else if (key == 'B'){  
  115.     menu++; //up
  116.     updateMenu();
  117.     delay(100);
  118.     while(!key=='B');
  119.   }else if(key == 'C'){
  120.      menu--; //down
  121.      updateMenu();
  122.      delay(100);
  123.      while(!key=='C');
  124.   }else if(key == 'D'){
  125.      executeAction();
  126.      updateMenu();
  127.      delay(100);
  128.      while(!key=='D');
  129.   }
  130.   */
  131. }

  132. /*LCD init*/
  133. void lcd_init(){
  134.   lcd.init(); //初始化LCD
  135.   lcd.backlight(); //開啟背光
  136.   lcd.clear();
  137.   lcd.setCursor(0,0);
  138.   lcd.print("Mode Choose:");
  139.   lcd.setCursor(0,1);
  140.   lcd.print(">_<");
  141. }

  142. void updateMenu() {
  143.   switch (menu) {
  144.     case 0:
  145.       menu = 0;
  146.       lcd.setCursor(0,0);
  147.       lcd.print("Mode Choose:");
  148.       lcd.setCursor(0,1);
  149.       lcd.print("------>_<--------");
  150.       break;
  151.     case 1:
  152.       lcd.clear();
  153.       lcd.setCursor(0,0);
  154.       lcd.print("Mode Choose:");
  155.       lcd.setCursor(0, 1);
  156.       lcd.print("01 Key");
  157.       break;
  158.     case 2:
  159.       lcd.clear();
  160.       lcd.setCursor(0,0);
  161.       lcd.print("Mode Choose:");
  162.       lcd.setCursor(0, 1);
  163.       lcd.print("02 RFID");
  164.       break;
  165.     case 3:
  166.       lcd.clear();
  167.       lcd.setCursor(0,0);
  168.       lcd.print("Mode Choose:");
  169.       lcd.setCursor(0, 1);
  170.       lcd.print("03 Key=>RFID");
  171.       break;
  172.     case 4:
  173.       lcd.clear();
  174.       lcd.setCursor(0,0);
  175.       lcd.print("Mode Choose:");
  176.       lcd.setCursor(0, 1);
  177.       lcd.print("04 RFID=>Key");
  178.       break;
  179.     case 5:
  180.       menu = 4;
  181.       break;
  182.   }
  183. }


  184. void executeAction() {
  185.   switch (menu) {
  186.     case 1:
  187.       action1();
  188.       break;
  189.     case 2:
  190.       action2();
  191.       break;
  192.     case 3:
  193.       action3();
  194.       break;
  195.     case 4:
  196.       action4();
  197.       break;
  198.   }
  199. }

  200. void action1() {
  201.   lcd.clear();
  202.   PasswordMode();
  203.   delay(10000);
  204. }
  205. void action2() {
  206.   lcd.clear();
  207.   RFIDMode();
  208.   lcd.setCursor(0,0);
  209.   lcd.print("RFID Card Check");
  210.   delay(1500);
  211. }
  212. void action3() {
  213.   lcd.clear();
  214.   lcd.setCursor(0, 1);
  215.   lcd.print(">Executing #3");
  216.   delay(1500);
  217. }
  218. void action4() {
  219.   lcd.clear();
  220.   lcd.setCursor(0, 1);
  221.   lcd.print(">Executing #4");
  222.   delay(1500);
  223. }

  224. /*RFID init*/
  225. void mfrc522_init(){
  226.   mfrc522.PCD_Init(SS_PIN, RST_PIN); // 初始化MFRC522卡
  227.   Serial.print(F("Reader "));
  228.   Serial.print(F(": "));
  229.   mfrc522.PCD_DumpVersionToSerial();
  230.   Serial.println();
  231. }

  232. void PasswordMode(){
  233.    lcd.setCursor(0,0);
  234.    lcd.print("Enter Password:");
  235.    inputCode = "";
  236.    char key_mode = myKeypad.getKey();

  237.    switch(key_mode){
  238.         case '*':
  239.                lcd.clear();
  240.                inputCode = "";
  241.               delay(100);
  242.               break;
  243.         case '#':
  244.                checkPinCode();
  245.                break;
  246.         default:
  247.                Serial.println(key_mode);
  248.                 inputCode += key_mode;  
  249.                 lcd.setCursor(0,1);
  250.                 lcd.print(inputCode);
  251.                 delay(100);
  252.                 break;
  253.     }
  254.    
  255.    /*if(key == '*'){
  256.           //按下'*'則清除字元
  257.           lcd.clear();
  258.           inputCode = "";
  259.           delay(100);
  260.       }else if (key == '#'){  
  261.            // 按下'#'進行確認,密碼是否正確
  262.           checkPinCode();
  263.           delay(100);
  264.      }else if (key){  
  265.         // 若有按鍵被按下則LCD&序列埠顯示按鍵的字元
  266.         Serial.println(key);
  267.          inputCode += key;  
  268.          lcd.setCursor(0,1);
  269.          lcd.print(inputCode);
  270.          delay(100);
  271.        }*/
  272.       
  273. }
  274. void RFIDMode(){
  275.     if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
  276.        lcd.setCursor(0,0);
  277.        lcd.print("RFID Card Check");
  278.        UID_output();  // 顯示該卡片的UID
  279.        UID_check();   //該卡片的UID是否和原本的一樣
  280.     }
  281.     clearStatus();  //清除鎖的狀態
  282. }
  283. /*顯示該卡片的UID*/
  284. void UID_output(){
  285.        Serial.print(F("Card UID:"));
  286.        dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size); // 顯示卡片的UID
  287.        Serial.println();
  288.        Serial.print(F("PICC type: "));
  289.        MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
  290.        Serial.println(mfrc522.PICC_GetTypeName(piccType));  //顯示卡片的類型
  291. }

  292. /*把取得的UID,拿來比對我們指定好的UID*/
  293. void UID_check(){
  294.       bool they_match = true; // 初始值是假設為真
  295.       for ( int i = 0; i < 4; i++ ) { // 卡片UID為4段,分別做比對
  296.         if ( uid[i] != mfrc522.uid.uidByte[i] ) {
  297.           they_match = false; // 如果任何一個比對不正確,they_match就為false,然後就結束比對
  298.           break;
  299.         }
  300.       }
  301.       
  302.       //在監控視窗中顯示比對的結果
  303.       if(they_match) unlock_status(1);
  304.       else unlock_status(0);
  305.       
  306.       mfrc522.PICC_HaltA();  // 卡片進入停止模式
  307. }

  308. /*鎖的狀態*/
  309. int unlock_status(int status_event){
  310.     lcd.setCursor(0,1);
  311.     if(status_event == 1){
  312.         Serial.print(F("Access Granted!"));
  313.         Serial.println();
  314.         lcd.print("Welcome home!");
  315.         digitalWrite(ledG, HIGH);
  316.         Serial3.write("R");
  317.         bz1();
  318.         delay(2000);
  319.         lcd.clear();
  320.         inputCode = "";
  321.         return 1;
  322.     }else if(status_event == 0){
  323.         Serial.print(F("Access Denied!"));
  324.         Serial.println();
  325.         lcd.print("****!!WRONG!!****");
  326.         digitalWrite(ledR, HIGH);
  327.         bz2();
  328.         delay(50);
  329.         lcd.clear();
  330.         inputCode = "";
  331.         return 0;
  332.     }     
  333. }

  334. /*清除鎖的狀態*/
  335. void clearStatus(){
  336.   digitalWrite(ledG, LOW);
  337.   digitalWrite(ledR, LOW);
  338.   lcd.setCursor(0,0);
  339.   lcd.print("Mode Choose:");
  340. }

  341. void bz_time(int pin,int Delaytime){
  342.       digitalWrite(pin,HIGH);
  343.       delay(Delaytime);
  344.       digitalWrite(pin,LOW);
  345.       delay(Delaytime);
  346. }
  347. void dump_byte_array(byte *buffer, byte bufferSize) {
  348.   for (byte i = 0; i < bufferSize; i++) {
  349.     Serial.print(buffer[i] < 0x10 ? " 0" : " ");
  350.     Serial.print(buffer[i], HEX);
  351.   }
  352. }

  353. /* 比對密碼*/
  354. void checkPinCode() {
  355.   int var;
  356.   //比對密碼判斷
  357.   if(inputCode == passcode) var=1;
  358.   else var=0;
  359.   unlock_status(var);
  360. }


  361. /*beep 01*/
  362. void bz1(){
  363.   for(int j=0;j<2;j++){
  364.     for(int i=0;i<25;i++) bz_time(buzzer,1);
  365.     delay(50);
  366.     Serial.print(j);
  367.   }
  368. }

  369. /*beep 02*/
  370. void bz2(){
  371.   for(int i=0;i<100;i++)  bz_time(buzzer,3);
  372. }
复制代码




您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|Archiver|手机版|Arduino中文社区

GMT+8, 2024-12-29 07:38 , Processed in 0.070479 second(s), 15 queries .

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表