|
本帖最后由 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
---
程式碼- /*定義按鍵模組*/
- #define KEY_ROWS 4 // 按鍵模組的列數
- #define KEY_COLS 4 // 按鍵模組的行數
- /*接腳*/
- #define ledG A0 //LED GREEN
- #define ledR A1 //LED RED
- #define buzzer A2 //蜂鳴器
- #define RST_PIN 11 //MFRC522:Reset
- #define SS_PIN 12 //MFRC522:SDA
- /*定義函式庫&函數*/
- #include <LiquidCrystal_I2C.h>
- #include <Wire.h>
- #include <Keypad.h>
- #include <SPI.h>
- #include <MFRC522.h>
- void lcd_init();
- void updateMenu();
- void executeAction();
- void bz1();
- void bz2();
- void mfrc522_init();
- void UID_output();
- void UID_check();
- void bz_time(int pin,int Delaytime);
- int unlock_status(int status_event);
- void checkPinCode();
- void RFIDMode();
- void PasswordMode();
- void action1();
- void action2();
- void action3();
- void action4();
- /*初始化Keypad物件*/
- int menu=1;
- char rcv;
- int sw= 22;
- int State = 0; // 按鈕的狀態
- char keymap[KEY_ROWS][KEY_COLS] = {{'1', '2', '3','A'},{'4', '5', '6','B'},{'7', '8', '9','C'},{'*', '0', '#','D'}}; // 依照行、列排列的按鍵字元(二維陣列)
- byte rowPins[KEY_ROWS] = { 22, 23, 24, 25}; // 按鍵模組,列從左1~4接腳
- byte colPins[KEY_COLS] = {26, 27, 28,29}; // 按鍵模組,行從左5~8接腳。
- String inputCode = "";
- String passcode = "6789"; // 4x4預設密碼
- // 語法:Keypad(makeKeymap(按鍵字元的二維陣列), 模組列接腳, 模組行接腳, 模組列數, 模組行數)
- Keypad myKeypad = Keypad(makeKeymap(keymap), rowPins, colPins, KEY_ROWS, KEY_COLS);
- char key_mode = myKeypad.getKey();
- /*I2C LCD 設定*/
- /*UNO接腳: SDA: A4 , SCLA: A5 */
- /*Mega 2560接腳: SDA:20 , SCLA:21 */
- LiquidCrystal_I2C lcd(0x27,16,2); //設定LCD位置0x27,設定LCD大小為16*2
- /*RFID 設定*/
- /* UNO接腳:
- * MOSI: 11
- * MISO: 12
- * SCK: 13
- */
- /*Mega2560接腳:
- * MOSI: 51
- * MISO: 50
- * SCK: 52
- */
- byte uid[]={0xC5, 0x37, 0x37, 0x45};
- MFRC522 mfrc522; // 建立MFRC522實體
- void setup() {
- // put your setup code here, to run once:
- lcd_init();
- SPI.begin();
- Serial.begin(9600);
- pinMode(sw, INPUT_PULLUP); //設定按鈕的接腳為輸入,因為我們要讀取它的狀態
- mfrc522_init();
- pinMode(ledG, OUTPUT);
- pinMode(ledR, OUTPUT);
- pinMode(buzzer,OUTPUT);
- }
- void loop() {
- // put your main code here, to run repeatedly:
- State = digitalRead(sw); //讀取按鍵的狀態
- int mode;
- char key=myKeypad.getKey();
- Serial.print(key);
- switch(key){
- case 'A':
- lcd.clear();
- lcd.setCursor(0,0);
- lcd.print("Mode Choose:");
- lcd.setCursor(0,1);
- lcd.print(">_<");
- break;
- case 'B':
- menu++; //up
- updateMenu();
- delay(100);
- while(!key=='B');
- break;
- case 'C':
- menu--; //down
- updateMenu();
- delay(100);
- while(!key=='C');
- break;
- case 'D':
- executeAction();
- updateMenu();
- delay(100);
- while(!key=='D');
- break;
- }
- /*
- if(key =='A'){
- lcd.clear();
- lcd.setCursor(0,0);
- lcd.print("Mode Choose:");
- lcd.setCursor(0,1);
- lcd.print(">_<");
- }else if (key == 'B'){
- menu++; //up
- updateMenu();
- delay(100);
- while(!key=='B');
- }else if(key == 'C'){
- menu--; //down
- updateMenu();
- delay(100);
- while(!key=='C');
- }else if(key == 'D'){
- executeAction();
- updateMenu();
- delay(100);
- while(!key=='D');
- }
- */
- }
- /*LCD init*/
- void lcd_init(){
- lcd.init(); //初始化LCD
- lcd.backlight(); //開啟背光
- lcd.clear();
- lcd.setCursor(0,0);
- lcd.print("Mode Choose:");
- lcd.setCursor(0,1);
- lcd.print(">_<");
- }
- void updateMenu() {
- switch (menu) {
- case 0:
- menu = 0;
- lcd.setCursor(0,0);
- lcd.print("Mode Choose:");
- lcd.setCursor(0,1);
- lcd.print("------>_<--------");
- break;
- case 1:
- lcd.clear();
- lcd.setCursor(0,0);
- lcd.print("Mode Choose:");
- lcd.setCursor(0, 1);
- lcd.print("01 Key");
- break;
- case 2:
- lcd.clear();
- lcd.setCursor(0,0);
- lcd.print("Mode Choose:");
- lcd.setCursor(0, 1);
- lcd.print("02 RFID");
- break;
- case 3:
- lcd.clear();
- lcd.setCursor(0,0);
- lcd.print("Mode Choose:");
- lcd.setCursor(0, 1);
- lcd.print("03 Key=>RFID");
- break;
- case 4:
- lcd.clear();
- lcd.setCursor(0,0);
- lcd.print("Mode Choose:");
- lcd.setCursor(0, 1);
- lcd.print("04 RFID=>Key");
- break;
- case 5:
- menu = 4;
- break;
- }
- }
- void executeAction() {
- switch (menu) {
- case 1:
- action1();
- break;
- case 2:
- action2();
- break;
- case 3:
- action3();
- break;
- case 4:
- action4();
- break;
- }
- }
- void action1() {
- lcd.clear();
- PasswordMode();
- delay(10000);
- }
- void action2() {
- lcd.clear();
- RFIDMode();
- lcd.setCursor(0,0);
- lcd.print("RFID Card Check");
- delay(1500);
- }
- void action3() {
- lcd.clear();
- lcd.setCursor(0, 1);
- lcd.print(">Executing #3");
- delay(1500);
- }
- void action4() {
- lcd.clear();
- lcd.setCursor(0, 1);
- lcd.print(">Executing #4");
- delay(1500);
- }
- /*RFID init*/
- void mfrc522_init(){
- mfrc522.PCD_Init(SS_PIN, RST_PIN); // 初始化MFRC522卡
- Serial.print(F("Reader "));
- Serial.print(F(": "));
- mfrc522.PCD_DumpVersionToSerial();
- Serial.println();
- }
-
- void PasswordMode(){
- lcd.setCursor(0,0);
- lcd.print("Enter Password:");
- inputCode = "";
- char key_mode = myKeypad.getKey();
- switch(key_mode){
- case '*':
- lcd.clear();
- inputCode = "";
- delay(100);
- break;
- case '#':
- checkPinCode();
- break;
- default:
- Serial.println(key_mode);
- inputCode += key_mode;
- lcd.setCursor(0,1);
- lcd.print(inputCode);
- delay(100);
- break;
- }
-
- /*if(key == '*'){
- //按下'*'則清除字元
- lcd.clear();
- inputCode = "";
- delay(100);
- }else if (key == '#'){
- // 按下'#'進行確認,密碼是否正確
- checkPinCode();
- delay(100);
- }else if (key){
- // 若有按鍵被按下則LCD&序列埠顯示按鍵的字元
- Serial.println(key);
- inputCode += key;
- lcd.setCursor(0,1);
- lcd.print(inputCode);
- delay(100);
- }*/
-
- }
- void RFIDMode(){
- if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
- lcd.setCursor(0,0);
- lcd.print("RFID Card Check");
- UID_output(); // 顯示該卡片的UID
- UID_check(); //該卡片的UID是否和原本的一樣
- }
- clearStatus(); //清除鎖的狀態
- }
- /*顯示該卡片的UID*/
- void UID_output(){
- Serial.print(F("Card UID:"));
- dump_byte_array(mfrc522.uid.uidByte, mfrc522.uid.size); // 顯示卡片的UID
- Serial.println();
- Serial.print(F("PICC type: "));
- MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
- Serial.println(mfrc522.PICC_GetTypeName(piccType)); //顯示卡片的類型
- }
- /*把取得的UID,拿來比對我們指定好的UID*/
- void UID_check(){
- bool they_match = true; // 初始值是假設為真
- for ( int i = 0; i < 4; i++ ) { // 卡片UID為4段,分別做比對
- if ( uid[i] != mfrc522.uid.uidByte[i] ) {
- they_match = false; // 如果任何一個比對不正確,they_match就為false,然後就結束比對
- break;
- }
- }
-
- //在監控視窗中顯示比對的結果
- if(they_match) unlock_status(1);
- else unlock_status(0);
-
- mfrc522.PICC_HaltA(); // 卡片進入停止模式
- }
- /*鎖的狀態*/
- int unlock_status(int status_event){
- lcd.setCursor(0,1);
- if(status_event == 1){
- Serial.print(F("Access Granted!"));
- Serial.println();
- lcd.print("Welcome home!");
- digitalWrite(ledG, HIGH);
- Serial3.write("R");
- bz1();
- delay(2000);
- lcd.clear();
- inputCode = "";
- return 1;
- }else if(status_event == 0){
- Serial.print(F("Access Denied!"));
- Serial.println();
- lcd.print("****!!WRONG!!****");
- digitalWrite(ledR, HIGH);
- bz2();
- delay(50);
- lcd.clear();
- inputCode = "";
- return 0;
- }
- }
- /*清除鎖的狀態*/
- void clearStatus(){
- digitalWrite(ledG, LOW);
- digitalWrite(ledR, LOW);
- lcd.setCursor(0,0);
- lcd.print("Mode Choose:");
- }
- void bz_time(int pin,int Delaytime){
- digitalWrite(pin,HIGH);
- delay(Delaytime);
- digitalWrite(pin,LOW);
- delay(Delaytime);
- }
- void dump_byte_array(byte *buffer, byte bufferSize) {
- for (byte i = 0; i < bufferSize; i++) {
- Serial.print(buffer[i] < 0x10 ? " 0" : " ");
- Serial.print(buffer[i], HEX);
- }
- }
- /* 比對密碼*/
- void checkPinCode() {
- int var;
- //比對密碼判斷
- if(inputCode == passcode) var=1;
- else var=0;
- unlock_status(var);
- }
- /*beep 01*/
- void bz1(){
- for(int j=0;j<2;j++){
- for(int i=0;i<25;i++) bz_time(buzzer,1);
- delay(50);
- Serial.print(j);
- }
- }
- /*beep 02*/
- void bz2(){
- for(int i=0;i<100;i++) bz_time(buzzer,3);
- }
复制代码
|
|