作業3,4 ESP32 + MFRC522的測試程式
MFRC522 RFID Reader/Writer Pinout and Wiring to the ESP32
源自於 https://randomnerdtutorials.com/esp32-mfrc522-rfid-reader-arduino/
/***
ESP32
Signal MFRC522 WROOM-32
RST/Reset RST 21
SPI SS SDA 5
SPI MOSI MOSI 23
SPI MISO MISO 19
SPI SCK SCK 18
***/
#include <MFRC522v2.h>
#include <MFRC522DriverSPI.h>
//#include <MFRC522DriverI2C.h>
#include <MFRC522DriverPinSimple.h>
#include <MFRC522Debug.h>
// Learn more about using SPI/I2C or check the pin assigment for your board: https://github.com/OSSLibraries/Arduino_MFRC522v2#pin-layout
MFRC522DriverPinSimple ss_pin(5);
MFRC522DriverSPI driver{ss_pin}; // Create SPI driver
//MFRC522DriverI2C driver{}; // Create I2C driver
MFRC522 mfrc522{driver}; // Create MFRC522 instance
void setup() {
Serial.begin(115200); // Initialize serial communication
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4).
mfrc522.PCD_Init(); // Init MFRC522 board.
MFRC522Debug::PCD_DumpVersionToSerial(mfrc522, Serial); // Show details of PCD - MFRC522 Card Reader details.
Serial.println(F("Scan PICC to see UID, SAK, type, and data blocks..."));
}
void loop() {
// Reset the loop if no new card present on the sensor/reader. This saves the entire process when idle.
if (!mfrc522.PICC_IsNewCardPresent()) {
return;
}
// Select one of the cards.
if (!mfrc522.PICC_ReadCardSerial()) {
return;
}
// Dump debug info about the card; PICC_HaltA() is automatically called.
MFRC522Debug::PICC_DumpToSerial(mfrc522, Serial, &(mfrc522.uid));
delay(2000);
}
09:46:19.726 -> Firmware Version: 0x92 = v2.0
09:46:19.726 -> Scan PICC to see UID, SAK, type, and data blocks...
09:46:22.147 -> Card UID: BE 36 2B 83
09:46:22.147 -> Card SAK: 08
09:46:22.147 -> PICC type: MIFARE 1KB
09:46:22.147 -> Sector Block 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 AccessBits
09:46:22.147 -> 15 63 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.147 -> 62 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.147 -> 61 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.195 -> 60 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.195 -> 14 59 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.195 -> 58 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.195 -> 57 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.195 -> 56 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.195 -> 13 55 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.195 -> 54 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.244 -> 53 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.244 -> 52 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.244 -> 12 51 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.244 -> 50 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.244 -> 49 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.244 -> 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.244 -> 11 47 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.293 -> 46 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.293 -> 45 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.293 -> 44 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.293 -> 10 43 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.293 -> 42 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.293 -> 41 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.293 -> 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.341 -> 9 39 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.341 -> 38 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.341 -> 37 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.341 -> 36 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.341 -> 8 35 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.341 -> 34 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.341 -> 33 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.390 -> 32 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.390 -> 7 31 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.390 -> 30 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.390 -> 29 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.390 -> 28 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.390 -> 6 27 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.390 -> 26 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.390 -> 25 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.438 -> 24 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.438 -> 5 23 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.438 -> 22 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.438 -> 21 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.438 -> 20 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.438 -> 4 19 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.438 -> 18 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.486 -> 17 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.486 -> 16 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.486 -> 3 15 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.486 -> 14 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.486 -> 13 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.486 -> 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.486 -> 2 11 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.534 -> 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.534 -> 9 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.534 -> 8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.534 -> 1 7 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.534 -> 6 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.534 -> 5 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.534 -> 4 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.582 -> 0 3 00 00 00 00 00 00 FF 07 80 69 FF FF FF FF FF FF [ 0 0 1 ]
09:46:22.582 -> 2 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.582 -> 1 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 [ 0 0 0 ]
09:46:22.582 -> 0 BE 36 2B 83 20 08 04 00 62 63 64 65 66 67 68 69 [ 0 0 0 ]
09:46:22.631 ->
- MFRC522讀卡器:這是一個常見的用於讀取MHz 非接觸式卡片的IC晶片。
- SAK(Select Acoustic):這是當讀卡器選擇一張卡片時,該卡片回傳的獨特識別碼,用於向讀卡器確認其身份。
- :這個值表示讀取到的卡片是屬於k MIFARE Classic 系列的一種。

台灣常見的 NFC 卡片,Mifare Classic 1k 絕對是榜上有名,因為舊版的悠遊卡、一卡通都是使用這種卡片,今天的文章就讓筆者來介紹這種卡片吧。
Mifare Classic 1k 卡,簡稱 M1 或 S50 卡,是非接觸式智慧卡的一種,這種卡片採用 ISO 14443A 的規範,通訊頻率是高頻 (13.56 MHz),卡片內部有 1024 Bytes 的資料,也是在 ChameleonUltra 硬體上最早支援模擬的卡片種類。
如何辨識 Mifare Classic 1k 卡
你的智慧型手機 (Android) 可以辨識大多數高頻 (13.56 MHz) 卡,除了智慧型手機之外,在你身邊應該有不少支援這種卡片的讀卡機,在此筆者以 Android 的 NFC TagInfo 進行辨識。這類卡片在沒有使用密碼的情況下,可以讀到 UID、ATQA、SAK 等資訊(這些是卡片的公開資訊),通常如果看到 ATQA=0004, SAK=08 或是 ATQA=0004, SAK=88 的話就是 Mifare Classic 1k 卡片。
支援這種卡片的 Android APP
- NFC TagInfo:可以讀取卡號及檢測高頻卡的卡片類型,例如捷運、悠遊卡新舊卡、一卡通新舊卡、愛金卡、自然人憑證、無線感應信用卡、護照、NFC SIM,但這個 APP 因為很久沒更新所以新版 Android 可能不支援。
- MIFARE Classic Tool:針對 Mifare Classic 卡片所提供的工具包。這個應用程式可以讀取、寫入、及修改 CUID 中國魔術卡。
- NFC TagInfo by NXP:這個 NXP 自己出的 APP,對於辨識使用 NXP 自己家的 NFC 晶片比較準確。
卡片資料結構
Mifare Classic 1k 卡片總共有 1024 Bytes;卡片總共被分成 16 個 Sectors,每個 Sector 有 64 Bytes;每個 Sector 又被分成 4 個 Blocks,每個 Block 有 16 Bytes。

每個 Sector 的 0-2 個 Block 是資料區塊 (Data block),可以用來存放資料,每個 Sector 的第 3 個 Block 是控制區塊 (Control block),用來存放存取控制資料,裡面有 Sector Key A、Sector Key B 及存取權限。

Data block 還可以被設定成特殊的 Value block,可以用來存放 32 位元的有號整數,值區域會對整數進行備份,避免資料發生錯誤,並且會有額外四個指令:遞增、遞減、備份、還原可以執行。
存取權限的部分在修改前,通常會建議直接透過一些工具直接計算權限(搜尋 MIFARE Classic 1K Access Bits Calculator 就能找到),避免不小心設定錯誤導致整個 Block 資料被鎖死(俗稱變磚)。

第 0 個 Sector 的第 0 個 Block 是特殊的 Block,被規劃成製造商區塊 (Manufacturer block),這個區塊會在製造時寫入一個唯讀的資料,通常用來存放卡片的 UID 及製造商資料。





沒有留言:
張貼留言