# RFID 和 4*4薄膜鍵盤 控制繼電器(依照兩組預設密碼) ## 程式碼 ```c = #include <Keypad.h> #include <Wire.h> #include <LiquidCrystal_I2C.h> // 引用I2C序列顯示器的程式庫 #include <SoftwareSerial.h> #include <PN532_SWHSU.h> #include <PN532.h> SoftwareSerial SWSerial(4, 5); // RX, TX PN532_SWHSU pn532swhsu(SWSerial); PN532 nfc(pn532swhsu); // 宣告繼電器控制腳位 const int relay1Pin = 2; const int relay2Pin = 3; int num = 0 ; int num2 = 0 ; // 宣告兩組RFID卡號 uint8_t uid1[] = {0xE7, 0x87, 0x45, 0xC9}; uint8_t uid2[] = {0x3, 0x7E, 0x76, 0xC}; #define KEY_ROWS 4 // 薄膜按鍵的列數 #define KEY_COLS 4 // 薄膜按鍵的行數 #define LCD_ROWS 2 // LCD顯示器的列數 #define LCD_COLS 16 // LCD顯示器的行數 // 設置按鍵模組 char keymap[KEY_ROWS][KEY_COLS] = { {'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'} }; byte rowPins[KEY_ROWS] = {13, 12, 11, 10}; byte colPins[KEY_COLS] = {9, 8, 7, 6}; Keypad keypad = Keypad(makeKeymap(keymap), rowPins, colPins, KEY_ROWS, KEY_COLS); String passcode1 = "4321"; // 預設密碼 String passcode2 = "1234"; String inputCode = ""; // 暫存用戶的按鍵字串 bool acceptKey = true; // 代表是否接受用戶按鍵輸入的變數,預設為「接受」 String passcode3 = "A"; // LCD顯示器 LiquidCrystal_I2C lcd(0x27, 20, 4); // 設定模組位址0x27/0x3F,以及20行, 4列的顯示形式 void clearRow(byte n) { byte last = LCD_COLS - n; lcd.setCursor(n, 1); // 移動到第2行,"PIN:"之後 for (byte i = 0; i < last; i++) { lcd.print(" "); } lcd.setCursor(n, 1); } // 顯示「歡迎光臨」後,重設LCD顯示文字和輸入狀態。 void resetLocker() { lcd.clear(); lcd.print("Knock, knock..."); lcd.setCursor(0, 1); // 切換到第2行 lcd.print("PIN:"); lcd.cursor(); acceptKey = true; inputCode = ""; } // 比對用戶輸入的密碼 void checkPinCode() { acceptKey = false; // 暫時不接受用戶按鍵輸入 clearRow(0); // 從第0個字元開始清除LCD畫面 lcd.noCursor(); lcd.setCursor(0, 0); // 切換到第1行 // 比對密碼 if (inputCode == passcode1) { lcd.print("Welcome uesr1!"); digitalWrite(relay1Pin, HIGH); // 開啟繼電器1 delay(5000); // 繼電器持續開啟5秒 digitalWrite(relay1Pin, LOW); // 關閉繼電器1 delay(1000); } else if(inputCode == passcode2){ lcd.print("Welcome uesr2!"); digitalWrite(relay2Pin, HIGH); // 開啟繼電器2 delay(5000); // 繼電器持續開啟5秒 digitalWrite(relay2Pin, LOW); // 關閉繼電器2 delay(1000); } else if (inputCode == passcode3 ){ num=0; lcd.clear(); lcd.setCursor(0, 0); lcd.print("Read..."); lcd.noCursor(); lcd.setCursor(0, 1); // 切換到第2行 while(num<10||relay1Pin ==1 || relay2Pin == 1 ){ boolean success; uint8_t uid[7]; // 宣告一個7個元素的陣列,用於存儲RFID卡號 uint8_t uidLength; // 存儲卡號長度 // 使用PN532模組讀取RFID卡號 success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength); if (success ) { // 成功讀取到卡片,進行判斷 // 匹配卡號1 if (memcmp(uid, uid1, 4) == 0) { Serial.println("匹配到卡號1"); lcd.print("Welcome uesr1!"); digitalWrite(relay1Pin, HIGH); // 開啟繼電器1 delay(5000); // 繼電器持續開啟5秒 digitalWrite(relay1Pin, LOW); // 關閉繼電器1 delay(1000); break; } // 匹配卡號2 else if (memcmp(uid, uid2, 4) == 0) { Serial.println("匹配到卡號2"); lcd.print("Welcome uesr2!"); digitalWrite(relay2Pin, HIGH); // 開啟繼電器2 delay(5000); // 繼電器持續開啟5秒 digitalWrite(relay2Pin, LOW); // 關閉繼電器2 delay(1000); break; } else { Serial.println("未知的卡號"); lcd.clear(); lcd.print("***WRONG!!***"); num+=1; num2 += 1 ; } delay(1000); // 延遲一段時間再進行下一次讀卡 }else{ Serial.println("未匹配到"); num += 1 ; delay(1000); } } resetLocker(); // 重設LCD顯示文字和輸入狀態 }else { if (num2 != 4) { lcd.clear(); lcd.print("***WRONG!!***"); delay(1000); resetLocker(); num2 += 1 ; }else { lcd.clear(); lcd.print("Wait 30S"); delay(30000); resetLocker(); num2=0; } } delay(500); resetLocker(); // 重設LCD顯示文字和輸入狀態 } void setup() { Serial.begin(115200); Serial.println("Hello Maker!"); // 初始化繼電器腳位 pinMode(relay1Pin, OUTPUT); pinMode(relay2Pin, OUTPUT); lcd.init(); // 初始化lcd物件 lcd.backlight(); // 開啟背光 resetLocker(); nfc.begin(); uint32_t versiondata = nfc.getFirmwareVersion(); if (!versiondata) { Serial.println("沒有找到 PN532 模組"); while (1); // 程序停止 } // 設置模組讀取ISO14443A類型的RFID卡片 nfc.SAMConfig(); Serial.println("等待 ISO14443A 卡片..."); } void loop() { char key = keypad.getKey(); // 若目前接受用戶輸入,而且有新的字元輸入… if (acceptKey && key != NO_KEY) { if (key == '*') { // 清除畫面 clearRow(4); // 從第4個字元開始清除 inputCode = ""; } else if (key == '#') { // 比對輸入密碼 checkPinCode(); } else { inputCode += key; // 儲存用戶的按鍵字元 lcd.print('*'); } } } ``` ## 接線表 | 繼電器1 IN | 繼電器2 IN | 繼電器 VCC | 繼電器 GND | RN532 GND |RN532 VCC | RN532 TXD | RN532 RXD | |:-----------:|:-----------:|:-----------:|:-----------:|:-----------:|:-----------:|:-----------:|:-----------:| | Arduino D2 | Arduino D3 | 5V | GND | GND|5V | Arduino D4 | Arduino D5| | LCD1602 I2C 正極 | LCD1602 I2C 負極 | LCD1602 I2C SDA | LCD1602 I2C SCL | 4*4薄膜鍵盤 | |:----------------:|:----------------:|:----------------:|:---------------:|:---------------------:| | 5V | GND | Arduino A4 | Arduino A5 | Arduino D6-13| ## 函式庫 - [GitHub](https://github.com/elechouse/PN532)