Arduino Uno + RFID-RC522:读取 MIFARE Ultralight 系列卡

前言

由于实验室历史悠久,加上全是硬件人在搞,元器件、芯片、模块等乱七八糟堆在实验室里面。本强迫症患者十分难受,因此想做一个智能仓储系统,加上有朋友的RC522(智能门锁完剩的东西)就直接上手试试。结果普遍都是复旦卡的教学,而我买的是NTAG系列的,代码总是bug。于是开始看库文件和数据手册,总算是完成了NTAG系列卡读写的代码。

硬件部分

Arduino UNO + RC522模块 + NTAG213芯片标签

使用的硬件图片

RC522引脚连接按照MFRC522库中给的指引连接,用的是Arduino UNO因此只需要看红框的内即可

示例代码中给的引脚连接指引

 软件部分

使用Arduino IDE进行代码编写,官网下载地址:Software | Arduino

验证手上的标签是否为MIFARE Ultralight类型卡

打开Arduino IDE(可能要新建一个文件),下载MFRC522库

之后可以在左上角“文件”选项中找到示例,如下图操作打开“DumpInfo”的示例

接着连接已经接好引脚的RC522和Arduino UNO到电脑,选择好开发板和接口(每个人接口不一样,可以通过插拔观察哪个是Arduino的端口)

连接和端口选择都没有问题,直接烧录示例代码即可

如果接线、端口也无误也烧录失败,原因可能是处理器没有选择好,可以参考这篇博客:arduino nano烧录出错_arduino nano无法烧录-CSDN博客

接着按快捷键Ctrl+Shift+M或者菜单栏中打开串口监视器查看输出信息

若没有烧录错误,监视器会弹出下面信息,证明代码烧录成功

 接着直接将要扫描的标签放上RC522,即可打印出标签信息,如下图打印信息说明该卡是MIFARE Ultralight类型卡

卡片读写代码

博主因为没有系统学过,就小白一个,代码都是示例里面搞出来的,没啥分析能用就行。

写入部分用了示例内的“rfid_write_personal_data”,但是总是遇到如下情况

代码显示我 PCD_Authenticate() failed: Timeout in communication. (连接超时)对应这行代码出错

  status = mfrc522.PCD_Authenticate(MFRC522::PICC_CMD_MF_AUTH_KEY_A, block, &key, &(mfrc522.uid));
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("PCD_Authenticate() failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }
  else Serial.println(F("PCD_Authenticate() success: "));

翻看数据手册(示例代码有github链接GitHub - miguelbalboa/rfid: Arduino RFID Library for MFRC522,下载压缩包下来里面有pdf文件)

发现这部分只是给MIFARE Classic类型卡做身份验证,MIFARE Ultralight类型就不用这部分,于是注释掉这部分再来,结果写入出了问题

数据手册第15页说明

报错显示  A MIFARE PICC responded with NAK.上网找和翻数据手册都没有很好的解决方式,试用复旦卡也是一样,于是回去看看源码,发现问题是写入块的地方错误了

  block = 1;
  // Write block
  status = mfrc522.MIFARE_Write(block, buffer, 16);
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("MIFARE_Write() failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }
  else Serial.println(F("MIFARE_Write() success: "));

根据设计前4个块不是数据区是不能写入的(不知道示例为什么这么写,内存可以参考这篇博客UltraLight 卡存储结构-CSDN博客),修改后的代码如下,也完美写入了

读取部分也是采用了示例代码里面的“rfid_read_personal_data”,注释掉身份验证部分也是能正常运行

于是大整合一波,只做了写入一个块的代码,后面要实现写入物品数据还要研究研究

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

#define RST_PIN         9           // Configurable, see typical pin layout above
#define SS_PIN          10          // Configurable, see typical pin layout above

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance

void setup() {
  Serial.begin(9600);        // Initialize serial communications with the PC
  SPI.begin();               // Init SPI bus
  mfrc522.PCD_Init();        // Init MFRC522 card
  Serial.println(F("Write personal data on a MIFARE PICC "));
}

void loop() {
  // put your main code here, to run repeatedly:
  // Prepare key - all keys are set to FFFFFFFFFFFFh at chip delivery from the factory.
  MFRC522::MIFARE_Key key;
  for (byte i = 0; i < 6; i++) key.keyByte[i] = 0xFF;

  // 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;
  }

  Serial.print(F("Card UID:"));    //Dump 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.print(F(" PICC type: "));   // Dump PICC type
  MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
  Serial.println(mfrc522.PICC_GetTypeName(piccType));

  byte buffer[32];
  byte block;
  MFRC522::StatusCode status;
  byte size = sizeof(buffer);
  byte len;
  byte blockcontent[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};

  Serial.setTimeout(20000L) ;     // wait until 20 seconds for input from serial 等待 20 秒,等待来自串口的输入
  // Ask personal data:
  Serial.println(F("Type Family name, ending with #"));
  len = Serial.readBytesUntil('#', (char *) buffer, 30) ; // read family name from serial
  for (byte i = len; i < 30; i++) buffer[i] = ' ';     // pad with spaces

  block = 5; 

  // Write block
  status = mfrc522.MIFARE_Write(block, buffer, 16);
  if (status != MFRC522::STATUS_OK) {
    Serial.print(F("MIFARE_Write() failed: "));
    Serial.println(mfrc522.GetStatusCodeName(status));
    return;
  }
  else Serial.println(F("MIFARE_Write() success: "));

  // read block
  status = mfrc522.MIFARE_Read(block, buffer, &size);
  if (status != MFRC522::STATUS_OK) {
      Serial.print(F("MIFARE_Read() failed: "));
      Serial.println(mfrc522.GetStatusCodeName(status));
      return;
  }
  else Serial.print(F("MIFARE_Read() success: "));
  for (uint8_t i = 0; i < 16; i++)
  {
    if (buffer[i] != 32)
    {
      Serial.write(buffer[i]);
    }
  }
  Serial.println(" ");
  delay(1000); 
  mfrc522.PICC_HaltA(); // Halt PICC
  mfrc522.PCD_StopCrypto1();  // Stop encryption on PCD
}
写入和输出结果

后记

第一次写技术博客,加上自己也很小白,写出来纯纯记录一下,顺便给后面的师弟妹们留遗产装置如果真出来用着的话起码知道怎么回事hhh,如果有哪里写的不好也请大家多多指点。

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
以下是连接RFID-RC522模块到ESP8266并在Arduino IDE上运行的步骤: 材料: - ESP8266开发板 - RFID-RC522模块 - 杜邦线(至少需要7根) 步骤: 1. 连接RFID-RC522模块到ESP8266开发板 - 将RFID-RC522模块的SCK引脚连接到ESP8266的D5引脚 - 将RFID-RC522模块的MOSI引脚连接到ESP8266的D7引脚 - 将RFID-RC522模块的MISO引脚连接到ESP8266的D6引脚 - 将RFID-RC522模块的SS引脚连接到ESP8266的D8引脚 - 将RFID-RC522模块的RST引脚连接到ESP8266的D0引脚 - 将RFID-RC522模块的3.3V引脚连接到ESP8266的3.3V引脚 - 将RFID-RC522模块的GND引脚连接到ESP8266的GND引脚 2. 下载并安装MFRC522库 - 在Arduino IDE中打开“库管理器”(菜单栏:工具 > 管理库) - 搜索“MFRC522”库 - 选择最新版本并点击“安装” 3. 编写代码 - 在Arduino IDE中打开一个新的空白文件 - 复制以下代码并粘贴到文件中 ```c++ #include <SPI.h> #include <MFRC522.h> #define RST_PIN D0 #define SS_PIN D8 MFRC522 mfrc522(SS_PIN, RST_PIN); // 创建MFRC522实例 void setup() { Serial.begin(9600); // 与电脑通信的串口初始化 SPI.begin(); // 初始化SPI总线 mfrc522.PCD_Init(); // 初始化MFRC522 } void loop() { // 检测是否有新的片出现 if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) { // 输出片的UID Serial.print("UID tag :"); String content = ""; byte letter; for (byte i = 0; i < mfrc522.uid.size; i++) { Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""); Serial.print(mfrc522.uid.uidByte[i], HEX); content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : "")); content.concat(String(mfrc522.uid.uidByte[i], HEX)); } Serial.println(); Serial.print("Message : "); content.toUpperCase(); if (content.substring(1) == "XX XX XX XX") { Serial.println("Authorized access"); // 这里可以加入执行授权访问的代码 } else { Serial.println("Access denied"); } } } ``` - 将代码上传到ESP8266开发板 4. 测试 - 打开串口监视器(菜单栏:工具 > 串口监视器) - 将一个RFID片放到RFID-RC522模块旁边 - 串口监视器将会显示片的UID - 如果片的UID与代码中的授权UID匹配,则串口监视器将打印“Authorized access”,否则打印“Access denied”

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值