ESP32使用DFROBOT通过MQTT服务器进行NFC读写

最近有个需求就是需要使用esp32来进行NFC卡的读取,但是无奈网上类似的文章太少,所以摸索了很久,解决后发布出来希望可以帮助到有需要的人。

目录

esp32连线图:

下载库文件:

导包 :

演示:

1.我们把NFC卡放到检测区域,串口中会显示已经读取到卡的数据:

2.我们使用mqttx软件来给esp32发布消息:

 3.发布后串口中会显示写入数据:

 4.然后把order改为0读取数据:

 5.串口就会发送读取数据:

 6.然后mqtt服务器上就会接收到卡中的数据:

注释: 

源码: 


esp32连线图:

 

D/T  连接  21号引脚

C/R  连接  22号引脚

GND  接地

VCC  连接  3V3

下载库文件:

本项目需要一个DFRobot_PN532头文件和pubsubclient头文件,下载地址如下:

DFRobot/DFRobot_PN532 - 码云 - 开源中国 (gitee.com)

pubsubclient: A client library for the Arduino Ethernet Shield that provides support for MQTT. (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);
}

  • 3
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值