【ESP32-RFID】| 使用RFID-RC522读写器基于串口进行RFID读写操作

注意事项/前要

通过串口通信可以方便地控制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

完整代码

需要确保安装并引用了SPIMFRC522

默认为MIFARE卡片

  • 串口通信:通过串口发送"READ"命令来读取RFID标签的UID和扇区数据,发送"WRITE [TEXT]"命令来写入自定义数据。
  • 加密通信:代码中,我使用了密钥AkeyA来进行数据加密,秘钥默认为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

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值