2026年10月30日 星期五

MFRC522 X 2

 MFRC522  X  2 



wokwi esp32 程式

#include <SPI.h>
#include <MFRC522.h>

// 定義 Reader 1 腳位與前綴
#define SS_1_PIN  5
#define RST_1_PIN 21
const String CARD1_PREFIX = "AA:";

// 定義 Reader 2 腳位與前綴
#define SS_2_PIN  4
#define RST_2_PIN 22
const String CARD2_PREFIX = "BB:";

// 宣告兩個 MFRC522 實體
MFRC522 rfid1(SS_1_PIN, RST_1_PIN);
MFRC522 rfid2(SS_2_PIN, RST_2_PIN);

// 讀取卡片 UID 並串接 Leading Code 的函式
void readCard(MFRC522 &mfrc522, String prefix) {
  // 檢查是否有新卡片並讀取
  if (!mfrc522.PICC_IsNewCardPresent() || !mfrc522.PICC_ReadCardSerial()) {
    return;
  }

  // 組合 Prefix + UID 格式
  String fullCode = prefix;
  for (byte i = 0; i < mfrc522.uid.size; i++) {
    if (i > 0) fullCode += ":";
    if (mfrc522.uid.uidByte[i] < 0x10) fullCode += "0";
    fullCode += String(mfrc522.uid.uidByte[i], HEX);
  }
  fullCode.toUpperCase();

  // 輸出帶有前綴碼的完整字串
  Serial.print("感應結果 -> ");
  Serial.println(fullCode);

  mfrc522.PICC_HaltA();
  mfrc522.PCD_StopCrypto1();
  delay(1000); // 防重複感應延遲
}

void setup() {
  Serial.begin(115200);
  SPI.begin();

  // 初始化第一個讀卡機
  rfid1.PCD_Init();
  Serial.println("MFRC522 #1 (CARD1) Ready");

  // 初始化第二個讀卡機
  rfid2.PCD_Init();
  Serial.println("MFRC522 #2 (CARD2) Ready");
}

void loop() {
  // 輪詢讀取兩個 MFRC522
  readCard(rfid1, CARD1_PREFIX);
  readCard(rfid2, CARD2_PREFIX);
 
  delay(50);
}


這段程式碼的目的是利用 ESP32 控制 2 個 MFRC522 RFID 讀卡機,並在讀取到卡片 UID 時,自動為兩個讀卡機加上不同的 前綴碼 (Leading Code) 進行區隔(rfid1 加 AA:、rfid2 加 BB:)。

關鍵功能與流程拆解

1. 模組腳位與前綴定義

  • SS_1_PIN (5) 與 SS_2_PIN (4):SPI 通訊的片選腳位 (CS/SDA)。SPI 匯流排上可以接多個裝置,ESP32 透過切換這兩個腳位的電位來決定要和哪一個讀卡機對話。

  • CARD1_PREFIX ("AA:") 與 CARD2_PREFIX ("BB:"):讀卡機 1 輸出的字串開頭為 AA:,讀卡機 2 輸出的字串開頭為 BB:。

2. 自訂讀卡函式 readCard()

這個函式採用引用傳遞 (MFRC522 &mfrc522),可以同時支援兩個讀卡機實體:

  • 偵測與讀取:PICC_IsNewCardPresent() 檢查有無卡片靠近,PICC_ReadCardSerial() 嘗試讀取卡片的 UID 序號。若無卡片則直接返回。

  • 字串組裝:

    • 先將傳入的前綴字串(如 AA:)存入 fullCode。

    • 用 for 迴圈將 UID 的每個 byte 轉成 16 進位(HEX),並處理小於 0x10 的補零(例如 05 而非 5),用冒號 : 串接起來。

    • toUpperCase():統一將 Hex 英文字母轉為大寫(如 aa:bb 轉成 AA:BB)。

  • 停止通訊與防重複:

    • PICC_HaltA() 與 PCD_StopCrypto1():讓卡片進入休眠,結束目前的加密通訊。

    • delay(1000):讀取後暫停 1 秒,防止同一次感應被重複觸發多次。

3. 初始化 setup()

  • 設定 Serial 傳輸埠傳輸速率為 115200 baud。

  • SPI.begin() 初始化 ESP32 的 SPI 匯流排(預設腳位:SCK=18, MISO=19, MOSI=23)。

  • 分別呼叫 rfid1.PCD_Init() 與 rfid2.PCD_Init() 完成兩個讀卡機晶片的初始化。

4. 主迴圈 loop()

  • 程式會不斷交替輪詢呼叫 readCard(rfid1, CARD1_PREFIX) 與 readCard(rfid2, CARD2_PREFIX)。

  • 只要有任何一台讀卡機感應到卡片,Serial Monitor 就會印出結果,例如:

    • 讀卡機 1 感應到 UID 為 01:02:03:04 的卡片,印出:感應結果 -> AA:01:02:03:04

    • 讀卡機 2 感應到同一張卡片,印出:感應結果 -> BB:01:02:03:04

沒有留言:

張貼留言

MQTT + SQLite + Tkinter + Telegram 雙向門禁管理後台系統 (作業3)

MQTT + SQLite + Tkinter + Telegram 雙向門禁管理後台系統 。 它透過多執行緒(Multithreading)同時處理 MQTT 訊息接收、GUI 視窗介面更新、SQLite 資料庫讀寫,以及 Telegram Bot 的推播與指令監聽。 一、 系...