最近有个需求就是需要使用esp32来进行NFC卡的读取,但是无奈网上类似的文章太少,所以摸索了很久,解决后发布出来希望可以帮助到有需要的人。
目录
1.我们把NFC卡放到检测区域,串口中会显示已经读取到卡的数据:
esp32连线图:
D/T 连接 21号引脚
C/R 连接 22号引脚
GND 接地
VCC 连接 3V3
下载库文件:
本项目需要一个DFRobot_PN532头文件和pubsubclient头文件,下载地址如下:
DFRobot/DFRobot_PN532 - 码云 - 开源中国 (gitee.com)
导包 :
导包之后又可能会产生库文件报错的情况,这个时候需要按照下面的方式修改一下:
1.打开库文件中的DFRobot_PN532-master\src\DFRobot_PN532.cpp文件
2.找到第315行:
标红的位置改为:
下面附上这部分代码:
改之前:
void DFRobot_PN532::writeData(int block, uint8_t index, uint8_t data)
{
if(!this->nfcEnable)
return;
index = max(min(index,16),1);
this->readData(block);
this->blockData[index - 1] = data;
this->writeData(block, this->blockData);
}
改之后:
void DFRobot_PN532::writeData(int block, uint8_t index, uint8_t data)
{
if(!this->nfcEnable)
return;
if(!this->scan())
return;
if(!this->passWordCheck(block,nfcUid,nfcPassword))
return;
this->readData(block);
this->blockData[index - 1] = data;
this->writeData(block, this->blockData);
}
演示:
1.我们把NFC卡放到检测区域,串口中会显示已经读取到卡的数据:
2.我们使用mqttx软件来给esp32发布消息:
下面的四个字段可以在代码中修改,第一个order字段为1是代表写入,会写入当前数据,为0是为读取,读取卡中数据
{
"order":"1",
"num": "2",
"name": "张三",
"money": "200",
"department": "2"
}
通过软件来发布数据:
3.发布后串口中会显示写入数据:
4.然后把order改为0读取数据:
5.串口就会发送读取数据:
6.然后mqtt服务器上就会接收到卡中的数据:
这样就可以全部完成了
注释:
1.mqtt服务器的搭建由于网上的方法很多,本文章就不详细说明
2.代码中mqtt发送用的topic为rfid/1,接收的为rfid/2
源码:
下面给大家附上源码:
#include <WiFi.h>
#include <PubSubClient.h>
#include <Arduino.h>
#include <SPI.h>
#include <Wire.h>
#include <DFRobot_PN532.h>
#define BLOCK_SIZE 16
#define PN532_IRQ 2
#define INTERRUPT 1
#define POLLING 0
const char *ssid = "你的WiFi名称";
const char *password = "你的WiFi密码";
const char *mqttServer = "你的mqtt服务器IP地址";
const int mqttPort = 1883;
const char *mqttUser = "mqtt服务器用户名";
const char *mqttPassword = "mqtt服务器密码";
WiFiClient espClient;
PubSubClient client(espClient);
// The block to be written
DFRobot_PN532_IIC nfc(PN532_IRQ, POLLING);
//让char转换为字符串
String char2String(char *c)
{
String s = "";
for (int i = 0; i < 16; i++)
{
s += c[i];
}
return s;
}
//把字符串转为json格式
String stringToJson(String key,String value){
String json = "{\"" + key + "\":\"" + value + "\"}";
return json;
}
//在json格式的数据中再加入一条数据
String addJson(String json,String key,String value){
String str = json.substring(0,json.length()-1);
str += ",\"" + key + "\":\"" + value + "\"}";
return str;
}
String json_data="{";
void write(uint8_t block, uint8_t dataWrite[BLOCK_SIZE])
{
if (nfc.scan())
{
if (nfc.writeData(block, dataWrite) != 1)
{
Serial.print("Block ");
Serial.print(block);
Serial.println(" write failure!");
}
else
{
Serial.print("Block ");
Serial.print(block);
Serial.println(" write success!");
Serial.print("Data written(string):");
Serial.println((char *)dataWrite);
Serial.print("Data written(HEX):");
for (int i = 0; i < BLOCK_SIZE; i++)
{
Serial.print(dataWrite[i], HEX);
Serial.print(" ");
}
}
}
}
String read(uint8_t block,String key)
{
uint8_t dataRead[16] = {0};
if (nfc.scan())
{
if (nfc.readData(dataRead, block) != 1)
{
Serial.print("Block ");
Serial.print(block);
Serial.println(" read failure!");
}
else
{
Serial.print("Block ");
Serial.print(block);
Serial.println(" read success!");
Serial.print("Data read(string):");
Serial.println((char *)dataRead);
String data = char2String((char *)dataRead);
Serial.println(data);
Serial.println(data.length());
//判断第一个字符是否为数字,如果是则去掉除数字以外的所有字符
if (data[0] >= '0' && data[0] <= '9')
{
int i = 0;
while (data[i] >= '0' && data[i] <= '9')
{
i++;
}
data = data.substring(0, i);
}
// 如果第一位不为数字,则只保留前6个字符
else
{
data = data.substring(0, 6);
}
if(key=="num")
{
json_data=stringToJson(key,data);
}
else
{
json_data=addJson(json_data,key,data);
}
Serial.println(key+":"+json_data);
return json_data;
}
}
}
//提取json格式中特定的值,双引号也去掉
String getJsonString(String json, String key)
{
int index = json.indexOf(key);
if (index == -1)
{
return "";
}
int start = json.indexOf(":", index);
if (start == -1)
{
return "";
}
int end = json.indexOf(",", start);
if (end == -1)
{
end = json.indexOf("}", start);
}
if (end == -1)
{
return "";
}
String value = json.substring(start + 1, end);
value.trim();
if (value.startsWith("\""))
{
value = value.substring(1);
}
if (value.endsWith("\""))
{
value = value.substring(0, value.length() - 1);
}
return value;
}
//将String转换为uint8_t数组
uint8_t *stringToUint8(String str)
{
uint8_t *data = new uint8_t[str.length()];
for (int i = 0; i < str.length(); i++)
{
data[i] = str[i];
}
return data;
}
String order(String str)
{
String order1 = getJsonString(str, "order");
if (order1 == "1")
{
Serial.println("\n---------------------------------存储数据-------------------------------------\n");
uint8_t *num = stringToUint8(getJsonString(str, "num"));
uint8_t *name = stringToUint8(getJsonString(str, "name"));
uint8_t *money = stringToUint8(getJsonString(str, "money"));
uint8_t *department = stringToUint8(getJsonString(str, "department"));
write(2, num);
write(4, name);
write(6, money);
write(8, department);
return "写入成功";
}
else if (order1 == "0")
{
Serial.println("\n----------------------------------读取数据--------------------------------------\n");
read(2,"num");
read(4,"name");
read(6,"money");
String temp= read(8,"department");
Serial.println(temp);
return temp;
}
}
//把字节流转为json格式
String byteToJson(byte *payload, unsigned int length)
{
String json = "";
for (int i = 0; i < length; i++)
{
json += (char)payload[i];
}
return json;
}
//把字节流转为字符串
String byteToString(byte *payload, unsigned int length)
{
String str = "";
for (int i = 0; i < length; i++)
{
str += (char)payload[i];
}
return str;
}
//将Json格式的字符串转为Json格式对象提取其中的Value值
String getJsonValue(String json, String key)
{
int index = json.indexOf(key);
if (index == -1)
{
return "";
}
int start = json.indexOf(":", index);
if (start == -1)
{
return "";
}
int end = json.indexOf(",", start);
if (end == -1)
{
end = json.indexOf("}", start);
}
String value = json.substring(start + 2, end - 1);
return value;
}
void callback(char *topic, byte *payload, unsigned int length)
{
// Serial.print("Message arrived in topic: ");
// Serial.println(topic);
// Serial.print("Message:");
for (int i = 0; i < length; i++)
{
Serial.print((char)payload[i]);
}
String str = byteToJson(payload, length);
String json_data=order(str);
client.publish("rfid/2", json_data.c_str());
Serial.println(json_data);
}
void setup()
{
Serial.begin(9600);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.println("Connecting to WiFi..");
}
Serial.println("Connected to the WiFi network");
client.setServer(mqttServer, mqttPort);
client.setCallback(callback);
while (!client.connected())
{
Serial.println("Connecting to MQTT...");
if (client.connect("ESP32Client", mqttUser, mqttPassword))
{
Serial.println("connected");
}
else
{
Serial.print("failed with state ");
Serial.print(client.state());
delay(2000);
}
}
client.subscribe("rfid/1");
Serial.print("Initializing");
while (!nfc.begin())
{
Serial.print(".");
delay(1000);
}
Serial.println();
Serial.println("Waiting for a card......");
}
void loop()
{
client.loop();
if (nfc.scan())
{
Serial.println("Card detected!");
}
delay(500);
}