You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何设置两台Arduino UNO连接的RFID RC522为主从机实现通信?

如何配置两个RFID RC522模块实现Arduino UNO主从通信?

嘿,这个需求我之前帮朋友折腾过好几次,RC522本身支持ISO14443A协议,要实现两台Arduino之间的主从通信,核心是让其中一个模块主动发起读写请求(主机),另一个模拟成被动响应的“虚拟PICC卡片”(从机)。下面我一步步给你拆解实现步骤:

第一步:硬件连接要点

  • 两个RC522模块分别和各自的Arduino UNO连接,接线都是标准SPI引脚,别接错了:
    • SDA → D10
    • SCK → D13
    • MOSI → D11
    • MISO → D12
    • GND → GND
    • 3.3V → 3.3V(敲黑板:RC522绝对不能接5V,一接就烧!
  • 额外小技巧:如果两个模块离得近,给每个模块的3.3V和GND之间接个100nF的陶瓷电容,能减少电源干扰,通信更稳定。

第二步:软件配置与代码实现

首先要用到MFRC522库,这个库默认支持主机模式,而从机模式需要我们手动配置寄存器来模拟PICC卡片。下面是主机和从机的完整代码:

主机代码(主动发起通信)

主机负责主动扫描、识别从机,并发送/接收数据:

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9

MFRC522 mfrc522(SS_PIN, RST_PIN);  // 创建RC522实例

void setup() {
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();  // 初始化模块,默认就是主机模式
  Serial.println("主机已启动,等待连接从机...");
}

void loop() {
  // 检测是否有"卡片"(这里就是我们的从机模块)
  if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
    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();

    // 示例:给从机发送"HELLO"
    byte sendData[] = {'H', 'E', 'L', 'L', 'O'};
    MFRC522::StatusCode status = mfrc522.PCD_TransceiveData(sendData, sizeof(sendData), NULL, 0, NULL, NULL);
    if (status == MFRC522::STATUS_OK) {
      Serial.println("数据发送成功!");
    } else {
      Serial.print("发送失败,错误码: ");
      Serial.println(mfrc522.GetStatusCodeName(status));
    }

    // 结束当前通信
    mfrc522.PICC_HaltA();
    mfrc522.PCD_StopCrypto1();
  }
  delay(100);
}

从机代码(被动响应)

从机需要配置成模拟PICC卡片的模式,等待主机的请求并回复:

#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9

MFRC522 mfrc522(SS_PIN, RST_PIN);

// 自定义从机的UID,主机就是通过这个识别它的
byte slaveUID[] = {0x12, 0x34, 0x56, 0x78};

void setup() {
  Serial.begin(9600);
  SPI.begin();
  mfrc522.PCD_Init();
  
  // 配置RC522为从机模式,模拟PICC卡片
  mfrc522.PCD_WriteRegister(MFRC522::CommandReg, MFRC522::PCD_IDLE);
  mfrc522.PCD_WriteRegister(MFRC522::TxControlReg, 0x00);
  mfrc522.PCD_WriteRegister(MFRC522::ModeReg, 0x3D);  // 设置为模拟PICC模式,CRC初始值0x6363
  
  // 写入我们自定义的UID
  mfrc522.PCD_WriteRegister(MFRC522::TxDataReg, slaveUID[0]);
  mfrc522.PCD_WriteRegister(MFRC522::TxDataReg+1, slaveUID[1]);
  mfrc522.PCD_WriteRegister(MFRC522::TxDataReg+2, slaveUID[2]);
  mfrc522.PCD_WriteRegister(MFRC522::TxDataReg+3, slaveUID[3]);
  
  Serial.println("从机已启动,等待主机连接...");
}

void loop() {
  // 监听主机发来的数据
  byte buffer[18];
  byte bufferSize = sizeof(buffer);
  MFRC522::StatusCode status = mfrc522.PCD_ReceiveData(buffer, &bufferSize, NULL);
  
  if (status == MFRC522::STATUS_OK && bufferSize > 0) {
    Serial.print("收到主机数据: ");
    for (byte i = 0; i < bufferSize; i++) {
      Serial.print((char)buffer[i]);
    }
    Serial.println();
    
    // 示例:回复主机"HI"
    byte response[] = {'H', 'I'};
    mfrc522.PCD_TransceiveData(response, sizeof(response), NULL, 0, NULL, NULL);
  }
  delay(50);
}

关键注意事项

  • 模块一致性:尽量用同一品牌同一批次的RC522模块,不同厂商的模块寄存器可能有细微差异,容易出问题。
  • 通信距离:RC522的有效通信距离大概在1-5cm,两个模块要尽量靠近,别隔太远。
  • 库版本:上面的代码基于最新版的MFRC522库,如果你的库版本比较老,可能需要调整寄存器的配置值。
  • 电源问题:Arduino的3.3V引脚输出电流有限,如果模块工作不稳定,建议给RC522外接一个3.3V/500mA的电源。

内容的提问来源于stack exchange,提问作者Osama Lazim

火山引擎 最新活动