注意事项/前要
通过串口通信可以方便地控制ESP32对RFID标签的读写操作。
本文将展示如何通过串口消息来控制RC522模块的读写操作。
- MFRC522:这是一个支持ISO/IEC 14443A标准的非接触式通信RFID读卡器模块,通常用于读取和写入13.56MHz频率的RFID标签。
- 串口通信:通过串口发送"READ"命令来读取RFID标签的UID和扇区数据,发送"WRITE [TEXT]"命令来写入自定义数据。
- 读写数据:读写数据时,每次执行完一次读写操作,就把卡片重新放置一次,否则容易识别失败。
RC522模块与开发板接线
RC522模块引脚 | Arduino ESP32 引脚 |
SDA | GPIO 21 |
SCK | GPIO 18 |
MOSI | GPIO 23 |
MISO | GPIO 19 |
IRQ | 不接 |
GND | GND |
RST | GPIO 22 |
3.3V | 3.3V |
完整代码
需要确保安装并引用了SPI
和MFRC522
库
默认为MIFARE卡片
- 串口通信:通过串口发送"READ"命令来读取RFID标签的UID和扇区数据,发送"WRITE [TEXT]"命令来写入自定义数据。
- 加密通信:代码中,我使用了密钥A
keyA
来进行数据加密,秘钥默认为0xFF
,秘钥是基于扇区加密的,一个扇区四个块,前三个块为数据,第四个为控制信息和秘钥。 - 数据块大小:每个块独立,每个块为16字节,默认最多写入16字节数据,可以自己根据需求增加换块逻辑。
- 读写数据:写入数据时需要选择扇区和块,这个默认写在全局变量,可自行更改成局部变量,更加灵活。
// 导入所需库
#include <SPI.h>
#include <MFRC522.h>
// 定义RC522模块的引脚
#define SS_PIN 21 // SDA
#define RST_PIN 22 // RST
// 创建MFRC522对象
MFRC522 mfrc522(SS_PIN, RST_PIN);
// 定义目标扇区和块号
int sector = 1;
int blockAddr = 4; // 块4是第一扇区的数据块
// 密钥A
MFRC522::MIFARE_Key keyA;
void setup() {
Serial.begin(115200); // 初始化串口通信
SPI.begin(); // 初始化SPI总线
mfrc522.PCD_Init(); // 初始化MFRC522模块
// 初始化密钥A(全为0xFF)
for (byte i = 0; i < 6; i++) {
keyA.keyByte[i] = 0xFF;
}
Serial.println("RFID读写控制器初始化完成 - 羡林i");
}
void loop() {
if (Serial.available() > 0) {
String command = Serial.readStringUntil('\n');
Serial.print("收到命令: ");
Serial.println(command);
if (command == "READ") {
readRFID();
} else if (command.startsWith("WRITE ")) {
String data = command.substring(6);
writeRFID(data);
} else {
Serial.println("无效命令");
}
// 发送确认消息
Serial.println("命令执行完毕 - 羡林i");
}
}
void readRFID() {
// 检查是否有新的RFID标签
if (!mfrc522.PICC_IsNewCardPresent()) {
Serial.println("未检测到新标签");
return;
}
// 选择其中一个RFID标签
if (!mfrc522.PICC_ReadCardSerial()) {
Serial.println("读取标签失败");
return;
}
// 打印标签的UID
Serial.print("标签UID: ");
for (byte i = 0; i < mfrc522.uid.size; i++) {
Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
Serial.print(mfrc522.uid.uidByte[i], HEX);
}
Serial.println();
// 认证指定扇区
MFRC522::StatusCode status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, blockAddr, &keyA, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print("认证失败: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// 读取扇区数据
byte buffer[18];
byte size = sizeof(buffer);
status = mfrc522.MIFARE_Read(blockAddr, buffer, &size);
if (status != MFRC522::STATUS_OK) {
Serial.print("读取失败: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
Serial.print("扇区数据: ");
for (byte i = 0; i < size; i++) {
Serial.print(buffer[i] < 0x10 ? " 0" : " ");
Serial.print(buffer[i], HEX);
}
Serial.println();
// 停止与标签的通信
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}
void writeRFID(String data) {
// 检查是否有新的RFID标签
if (!mfrc522.PICC_IsNewCardPresent()) {
Serial.println("未检测到新标签");
return;
}
// 选择其中一个RFID标签
if (!mfrc522.PICC_ReadCardSerial()) {
Serial.println("读取标签失败");
return;
}
// 将数据转化为字节数组(最多16字节)
byte dataBlock[16];
data.getBytes(dataBlock, 16);
// 认证指定扇区
MFRC522::StatusCode status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, blockAddr, &keyA, &(mfrc522.uid));
if (status != MFRC522::STATUS_OK) {
Serial.print("认证失败: ");
Serial.println(mfrc522.GetStatusCodeName(status));
return;
}
// 写入数据到指定块
status = mfrc522.MIFARE_Write(blockAddr, dataBlock, 16);
if (status != MFRC522::STATUS_OK) {
Serial.print("写入失败: ");
Serial.println(mfrc522.GetStatusCodeName(status));
} else {
Serial.println("数据写入成功!");
}
// 停止与标签的通信
mfrc522.PICC_HaltA();
mfrc522.PCD_StopCrypto1();
}
开发环境:Arduino IDE、ESP32 Dev Module
代码辅助:ChatGPT-4o
作者:羡林i