前言
由于实验室历史悠久,加上全是硬件人在搞,元器件、芯片、模块等乱七八糟堆在实验室里面。本强迫症患者十分难受,因此想做一个智能仓储系统,加上有朋友的RC522(智能门锁完剩的东西)就直接上手试试。结果普遍都是复旦卡的教学,而我买的是NTAG系列的,代码总是bug。于是开始看库文件和数据手册,总算是完成了NTAG系列卡读写的代码。
硬件部分
Arduino UNO + RC522模块 + NTAG213芯片标签
![](https://img-blog.csdnimg.cn/ba56fa10434040f397f810276b778bf8.jpeg)
RC522引脚连接按照MFRC522库中给的指引连接,用的是Arduino UNO因此只需要看红框的内即可
![](https://img-blog.csdnimg.cn/754cda47c72e4b488ff3d656522c8a50.png)
软件部分
使用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类型就不用这部分,于是注释掉这部分再来,结果写入出了问题
![](https://img-blog.csdnimg.cn/b95d3e721c664ee986d053a72af40840.png)
报错显示 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
}
![](https://img-blog.csdnimg.cn/449e278338c34fffa2f91f2e351da64b.png)
后记
第一次写技术博客,加上自己也很小白,写出来纯纯记录一下,顺便给后面的师弟妹们留遗产装置如果真出来用着的话起码知道怎么回事hhh,如果有哪里写的不好也请大家多多指点。