- Arduino UNO 開發版 *1
- RFID RC522 模組
- SPI Library (見備註)
- MFRC522 Library (見備註)
PIN 腳對應表:
RFID RC522
|
Arudino UNO
|
3.3V
|
3.3V
|
RST
|
9
|
GND
|
GND
|
IRQ
|
|
MISO
|
12
|
MOSI
|
11
|
SCK
|
13
|
SDA/NSS
|
10
|
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
int block=2;
byte blockcontent[16] = {"Hello world"};
byte readbackblock[18];
void setup() {
Serial.begin(9600);
SPI.begin();
mfrc522.PCD_Init();
Serial.println("Scan a MIFARE Classic card");
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
}
void loop(){
mfrc522.PCD_Init();
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
if ( !mfrc522.PICC_ReadCardSerial()) {
return;
}
Serial.println("card selected");
readBlock(block, readbackblock);
Serial.print("read block: ");
for (int j=0 ; j<16 ; j++){
Serial.write (readbackblock[j]);
}
Serial.println("");
}
int writeBlock(int blockNumber, byte arrayAddress[]){
int largestModulo4Number=blockNumber/4*4;
int trailerBlock=largestModulo4Number+3;
if (blockNumber > 2 && (blockNumber+1)%4 == 0){
Serial.print(blockNumber);
Serial.println(" is a trailer block:");
return 2;
}
Serial.print(blockNumber);
Serial.println(" is a data block:");
byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print("PCD_Authenticate() failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return 3;//return "3" as error message
}
status = mfrc522.MIFARE_Write(blockNumber, arrayAddress, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print("MIFARE_Write() failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return 4;//return "4" as error message
}
Serial.println("block was written");
}
int readBlock(int blockNumber, byte arrayAddress[]) {
int largestModulo4Number=blockNumber/4*4;
int trailerBlock=largestModulo4Number+3;
byte status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, trailerBlock, &key, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print("PCD_Authenticate() failed (read): ");
Serial.println(mfrc522.GetStatusCodeName(status));
return 3;//return "3" as error message
}
byte buffersize = 18;//we need to define a variable with the read buffer size, since the MIFARE_Read method below needs a pointer to the variable that contains the size...
status = mfrc522.MIFARE_Read(blockNumber, arrayAddress, &buffersize);//&buffersize is a pointer to the buffersize variable; MIFARE_Read requires a pointer instead of just a number
if (status != MFRC522::STATUS_OK) {
Serial.print("MIFARE_read() failed: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return 4;
}
Serial.println("block was read");
delay(500);
}
Step1. 貼上程式碼
Step2. 燒入程式
如果你把上面的程式碼整個貼上,你會發現無法執行,因為你並沒有SPI和MFRC522的Library,所以第一步驟要先從Library加入,可以參考此連結。
Step3. 插上RFID模組, PIN腳請參考上方PIN腳對應表
Step4. 測試
打開Serial Monitor 如果成功,會照順序出現以下畫面:
表示RFID已經初始化成功
Hello World就是上方程式碼預設寫入的內容,後面方框是沒有資料的意思。
Step5. 了解程式碼
#include <SPI.h>
#include <MFRC522.h>
#define SS_PIN 10
#define RST_PIN 9
MFRC522 mfrc522(SS_PIN, RST_PIN);
MFRC522::MIFARE_Key key;
以上都僅僅是定義 RFID 開發需要用到的工具,還有對應的PIN
int block=2;
byte blockcontent[16] = {"Hello world"};
byte readbackblock[18];
block 可以理解成開鎖的位置,一般市面上買到的白卡都會在2的位置,若是要正確讀取或者寫值,就是要輸入正確的block位置。bloclcontent 是一個長度為16的 byte 陣列,紀錄的要寫入 RFID 白卡的內容,因為是教學需要,所以在一開始就預設好,學習之後可以在loop()內任意修改。
readbackblock 是存著讀取 RFID 卡後存資料的變數。
void setup() {
Serial.begin(9600);
SPI.begin();
mfrc522.PCD_Init();
Serial.println("Scan a MIFARE Classic card");
for (byte i = 0; i < 6; i++) {
key.keyByte[i] = 0xFF;
}
}
setup() 內就是照做就好。目的是為了讓 RFID 可以正常使用。
Serial所做的事情是為了讓操作的人可以瞭解現在執行的狀況。
mfrc522.PCD_Init();
if ( ! mfrc522.PICC_IsNewCardPresent()) {
return;
}
if ( !mfrc522.PICC_ReadCardSerial()) {
return;
}
在loop()內的一開始就要加入上面的動作,而且一定要放在loop內,是為了讓使用者可以一直讀取卡片。若將 mfrc522.PCD_Init() 放在 setup()內,就只能讀取一次卡片。
下面兩個執行的動作照順序是:判斷是不是另外一張卡片;卡片是否可以被讀取。之後可以你可以在這兩個function的{}加入其他動作,像是Serial.print()告知使用者發生什麼樣的錯誤,導致無法讀取卡片。
writeBlock(block, blockcontent);
readBlock(block, readbackblock);
Serial.print("read block: ");
for (int j=0 ; j<16 ; j++){
Serial.write (readbackblock[j]);
}
writeBlock() 是將 blockcontent 的內容寫入卡片內。這是因為是示範用,所以直接寫在讀取的動作前面,正常是不可能這樣使用的,而且通常寫入需要一段時間,想像你在7-11使用悠遊卡也不是馬上就好。
readBlock() 是讀取的動作,而讀取到的資料就放在 readbackblock 內。
而讀取後就是要顯示,一般分為兩種,這裡是把所有資料給顯示出來,常用的方式就用 for 迴圈,注意:這裏要用Serial.write()才會正常把"Hello world"給顯示出來,你可以稍微試試看使用Serial.print(),看看會有什麼不一樣的結果顯示,Tip : 可以朝 ASCII 思考。
備註:
下載:MFRC522 Library
沒有留言 :
張貼留言