RFID 感應門(刷一次授權卡 → 開門,刷第二次 → 關門)

 #include <SPI.h>

#include <MFRC522.h>

#include <Servo.h>


#define RST_PIN 9     // 重置腳位

#define SS_PIN 10     // SDA 腳位

#define SERVO_PIN 7   // 伺服馬達腳位

#define BUZZER_PIN 8  // 蜂鳴器腳位


MFRC522 mfrc522(SS_PIN, RST_PIN);  // 建立 RFID 物件

Servo doorServo;                   // 建立伺服馬達物件


// 定義卡片資料結構

struct Card {

  byte uid[4];       // UID

  const char* name;  // 卡片名稱

};


// 多張授權卡片

Card authorizedCards[] = {

  {{0, 48, 163, 17}, "卡片 A"},

  {{51, 192, 55, 254}, "卡片 B"},

  {{228, 25, 201, 113}, "卡片 C"}

};


bool doorOpen = false;  // 記錄門狀態 (false=關, true=開)


void setup() {

  Serial.begin(9600);

  SPI.begin();

  mfrc522.PCD_Init();

  doorServo.attach(SERVO_PIN);

  doorServo.write(0); // 初始關門角度

  pinMode(BUZZER_PIN, OUTPUT);

  Serial.println("請將卡片靠近讀卡器...");

}


void loop() {

  if (!mfrc522.PICC_IsNewCardPresent()) return;

  if (!mfrc522.PICC_ReadCardSerial()) return;


  Serial.print("卡片 UID (10進位): ");

  for (byte i = 0; i < mfrc522.uid.size; i++) {

    Serial.print(mfrc522.uid.uidByte[i], DEC);

    Serial.print(" ");

  }

  Serial.println();


  int cardIndex = checkAuthorized(mfrc522.uid.uidByte);

  if (cardIndex >= 0) {

    Serial.print("授權卡片 → ");

    Serial.println(authorizedCards[cardIndex].name);

    successBeep();


    if (!doorOpen) {

      doorServo.write(90);   // 開門

      doorOpen = true;

      Serial.println("門已打開");

    } else {

      doorServo.write(0);    // 關門

      doorOpen = false;

      Serial.println("門已關閉");

    }

  } else {

    Serial.println("非授權卡片 → 不動作");

    errorBeep();

  }


  mfrc522.PICC_HaltA();

}


// 檢查是否為授權卡

int checkAuthorized(byte *uid) {

  for (byte i = 0; i < sizeof(authorizedCards) / sizeof(Card); i++) {

    bool match = true;

    for (byte j = 0; j < 4; j++) {

      if (uid[j] != authorizedCards[i].uid[j]) {

        match = false;

        break;

      }

    }

    if (match) return i; // 回傳卡片索引

  }

  return -1; // 非授權

}


// 成功提示音

void successBeep() {

  tone(BUZZER_PIN, 1000, 200);

  delay(250);

  tone(BUZZER_PIN, 1500, 200);

  delay(250);

  noTone(BUZZER_PIN);

}


// 失敗警告音

void errorBeep() {

  tone(BUZZER_PIN, 400, 500);

  delay(600);

  noTone(BUZZER_PIN);

}










留言