本文旨在補充《超圖解 Arduino 互動設計入門》第17章的RFID應用單元。
實驗說明:典型的RFID應用,例如門禁卡,都是事先在微電腦中儲存特定RFID卡片的識別碼。當持卡人掃描門禁卡時,系統將讀取並且比對儲存值,如果有相符,就開門讓持卡人通過。本文採用一個伺服馬達來模擬旋轉門鎖的動作。
一開始,伺服馬達位於0度位置,掃描有效的卡片時,伺服馬達將旋轉到90度;再次掃描有效的卡片,它將轉回0度。
若掃描無效的卡片,伺服馬達將維持在0度,或者從90度轉回0度。
實驗材料:
- Mifare RFID-RC522模組×1
- Mifare Classic標籤,至少兩個。
- 伺服馬達×1
實驗電路:
Mifare RFID-RC522模組與Arduino板的接線與「Mifare RFID-RC522模組實驗(二)」單元相同,另外在數位2腳連接伺服馬達:
實驗程式:
本文的程式延續「Mifare RFID-RC522模組實驗(二)」單元,在其中加入控制伺服馬達的程式,一開始先定義與伺服馬達相關的變數:
#include <Servo.h> // 引用伺服馬達程式庫 #define SERVO_PIN 2 // 伺服馬達的控制訊號接腳 bool lockerSwitch = false; // 伺服馬達(模擬開關)的切換狀態,預設為「關」 Servo servo; // 宣告伺服馬達物件
接著定義控制伺服馬達轉動(模擬開鎖或關鎖)的自訂函式:
// 開鎖或關鎖 void locker(bool toggle) { if (toggle) { servo.write(90); // 開鎖 } else { servo.write(0); // 關鎖 } delay(15); // 等伺服馬達轉到定位 }
在setup()函式裡面初始化伺服馬達物件,接著關鎖(轉動到0度)。
void setup() { : : mfrc522.PCD_Init(); // 初始化MFRC522讀卡機模組 servo.attach(SERVO_PIN); // 將伺服馬達物件附加在數位2腳 locker(lockerSwitch); // 關鎖 }
最後,修改loop()函式裡面的比對卡片UID值的程式碼當中,加入開鎖或解鎖的敘述(一開始,lockerSwitch的值為false,每執行一次,就反轉一次):
完整的程式碼:
#include <SPI.h> #include <MFRC522.h> // 引用程式庫 #include <Servo.h> // 引用伺服馬達程式庫 #define RST_PIN A0 // 讀卡機的重置腳位 #define SS_PIN 10 // 晶片選擇腳位 #define SERVO_PIN 2 // 伺服馬達的控制訊號接腳 bool lockerSwitch = false; // 伺服馬達的狀態 Servo servo; // 宣告伺服馬達物件 struct RFIDTag { // 定義結構 byte uid[4]; char *name; }; struct RFIDTag tags[] = { // 初始化結構資料,請自行修改RFID識別碼。 {{60,209,110,133}, "Arduino"}, {{212,211,192,97}, "Raspberry Pi"}, {{21,8,10,83}, "Espruino"} }; byte totalTags = sizeof(tags) / sizeof(RFIDTag); // 計算結構資料筆數,結果為3。 MFRC522 mfrc522(SS_PIN, RST_PIN); // 建立MFRC522物件 // 開鎖或關鎖 void locker(bool toggle) { if (toggle) { servo.write(90); // 開鎖 } else { servo.write(0); // 關鎖 } delay(15); // 等伺服馬達轉到定位 } void setup() { Serial.begin(9600); Serial.println(); Serial.print("size of RFIDTag:"); Serial.println(sizeof(RFIDTag)); Serial.print("size of tag:"); Serial.println(sizeof(tags)); Serial.println("RFID reader is ready!"); SPI.begin(); mfrc522.PCD_Init(); // 初始化MFRC522讀卡機模組 servo.attach(SERVO_PIN); // 將伺服馬達物件附加在數位2腳 locker(lockerSwitch); } void loop() { // 確認是否有新卡片 if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) { byte *id = mfrc522.uid.uidByte; // 取得卡片的UID byte idSize = mfrc522.uid.size; // 取得UID的長度 bool foundTag = false; // 是否找到紀錄中的標籤,預設為「否」。 for (byte i=0; i<totalTags; i++) { if (memcmp(tags[i].uid, id, idSize) == 0) { // 比對陣列資料值 Serial.println(tags[i].name); // 顯示標籤的名稱 foundTag = true; // 設定成「找到標籤了!」 lockerSwitch = !lockerSwitch; // 切換鎖的狀態 locker(lockerSwitch); // 開鎖或關鎖 break; // 退出for迴圈 } } if (!foundTag) { // 若掃描到紀錄之外的標籤,則顯示"Wrong card!"。 Serial.println("Wrong card!"); // 如果鎖是開啟狀態,則關閉它。 if (lockerSwitch) { lockerSwitch = false; locker(lockerSwitch); } } mfrc522.PICC_HaltA(); // 讓卡片進入停止模式 } }
請問需要自行修改RFID識別碼的部份
為什麼改成自己的卡片之後還是不行呢
是讀取完識別碼之後將他換算成四進制嗎?
請參閱《Mifare RFID-RC522模組實驗(一):讀取Mifare RFID卡的UID識別碼》的程式和說明,把讀取到的識別碼填入上文程式。
thanks,
jeffrey
為什麼我用你第一個《Mifare RFID-RC522模組實驗(一):讀取Mifare RFID卡的UID識別碼》所出現的UID碼 卻不能使用在這個程式上面,而且只要輸入有英文的UID碼就會錯誤
因為RFIDtag的第一組資料型態是byte,請問你的字元資料有用單引號括起來嗎?
thanks,
jeffrey
struct RFIDTag tags[] = { // 初始化結構資料,請自行修改RFID識別碼。
{{‘A9′,’2B’,’9D’,’1A’}, “Arduino”}, 你說的單引號是這樣? 這個代碼是我們磁扣碼 但感應時顯示wrong card
{{212,211,192,97}, “Raspberry Pi”},
{{21,8,10,83}, “Espruino”}
};
不是,byte類型代表數字0~255或單一字元,C語言用單引號包圍一個字元,這些基礎知識書本都有說明,請自行參考或者請教專題老師。
thanks,
jeffrey
有英文的是HEX
請用
{0xA9,0x2B,0x9D,0x1A}
謝謝yu-min的補充說明!
thanks,
jeffrey
不好意思 我想請問 為何顯示WRONG CARD時 (已先輸入對應UID卡片) 伺服馬達卻無法回歸0度?
你可以在判斷為wrong card的條件敘述中,加入轉動servo的敘述試試看。
thanks,
jeffrey
老師好,請問可以套用你上方部分的程式片段到我的學校專題內嗎~?
沒問題~
thanks,
jeffrey
請問一個ARDUINO UNO可以接多少塊RFID ???
單純就硬體接線來說,不計算消耗電流,每個SPI週邊至少要佔用一條晶片選擇線,因此你可以自行計算總共可以接多少RFID讀卡機。
have fun!
jeffrey
老師~~~我想請問如果我要用同一張RFID卡開啟和關閉那個馬達應該要怎麼做???
上面的程式就是用同一張卡來開啟和關閉馬達。
thanks,
jeffrey
老師您好
我想把伺服馬達弄成可復歸回0度,所以把開關鎖的地方弄成這樣
void locker(bool toggle) {
if (toggle) {
servo.write(90); // 開鎖
delay(1000);
servo.write(0);
} else {
servo.write(0); // 關鎖
}
delay(15); // 等伺服馬達轉到定位
}
可是變成了卡片必須感應到兩次才會動作
因為根據你的程式,感應第一次時,伺服馬達轉90度後一秒轉回0度;第2次感應時,馬達維持在0度,不動作。
第3次感應,馬達才又轉90度…以此類推。
thanks,
jeffrey
老師您好
請問在開鎖後10分鐘內忘了關鎖就有蜂鳴器提醒
直到用卡鎖了,蜂鳴器才停
可以如何改寫
請拿出筆、紙規劃一下程式流程,就能寫出來了。
thanks,
jeffrey
想問問如何控制伺福馬達,因為我照這城市上船玩ARDUINO後伺福馬達一職不受控制
請確認伺服馬達的接線,或者換一個馬達試試。