---
# System prepended metadata

title: RFID 和 4*4薄膜鍵盤 控制繼電器(依照兩組預設密碼)

---

# 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)
