2024年1月28日 星期日

ESP32 使用 ArduinoMqttClient 程式庫 執行MQTT + MFRC522 RFID Reader 讀取UID 號碼

 ESP32 使用 ArduinoMqttClient 程式庫 執行MQTT + MFRC522 RFID Reader 讀取UID 號碼









//定義MFRC522 RFID read 與 ESP32 介面 接腳連接Pin assign

/* Wiring RFID RC522 module  
==============================================================
GND     = GND   3.3V    = 3.3V
The following table shows the typical pin layout used:
 *             MFRC522      ESP32    
 *             Reader/PCD            
 * Signal      Pin          Pin        
 * -----------------------------------
 * RST/Reset   RST          GPIO27  
 * SPI SS      SDA(SS)      GPIO5    
 * SPI MOSI    MOSI         GPIO23    
 * SPI MISO    MISO         GPIO19    
 * SPI SCK     SCK          GPIO18    
 *
[1] (1, 2) Configurable, typically defined as RST_PIN in sketch/program.
[2] (1, 2) Configurable, typically defined as SS_PIN in sketch/program.
[3] The SDA pin might be labeled SS on some/older MFRC522 boards
=============================================================
*/



/*
  ArduinoMqttClient - WiFi Simple Receive Callback

  This example connects to a MQTT broker and subscribes to a single topic.
  When a message is received it prints the message to the Serial Monitor,
  it uses the callback functionality of the library.

*/

#include <ArduinoMqttClient.h>
#include <WiFi.h>
#include "arduino_secrets.h"

///////please enter your sensitive data in the Secret tab/arduino_secrets.h
//char ssid[] = "TOTOLINK_A3002MU";    // your network SSID (name)
//char pass[] = "24063173";    // your network password (use for WPA, or use as key for WEP)

char ssid[] = "dlink-103A";    // your network SSID (name)
char pass[] = "bdcce12882";    // your network password (use for WPA, or use as key for WEP)


// To connect with SSL/TLS:
// 1) Change WiFiClient to WiFiSSLClient.
// 2) Change port value from 1883 to 8883.
// 3) Change broker value to a server with a known SSL/TLS root certificate
//    flashed in the WiFi module.

WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);

//const char broker[] = "test.mosquitto.org";
const char broker[] = "broker.mqtt-dashboard.com";
int        port     = 1883;

const char willTopic[] = "alex9ufo/will";
const char inTopic[]   = "alex9ufo/in";
const char outTopic[]  = "alex9ufo/out";


const long interval = 30000;
unsigned long previousMillis = 0;
int count = 0;
#define LED 2   //定義LED接腳
//定義MFRC522 RFID read 與 ESP32 介面 接腳連接Pin assign
/* Wiring RFID RC522 module  
==============================================================
GND     = GND   3.3V    = 3.3V
The following table shows the typical pin layout used:
 *             MFRC522      ESP32    
 *             Reader/PCD            
 * Signal      Pin          Pin        
 * -----------------------------------
 * RST/Reset   RST          GPIO27  
 * SPI SS      SDA(SS)      GPIO5    
 * SPI MOSI    MOSI         GPIO23    
 * SPI MISO    MISO         GPIO19    
 * SPI SCK     SCK          GPIO18    
 *
[1] (1, 2) Configurable, typically defined as RST_PIN in sketch/program.
[2] (1, 2) Configurable, typically defined as SS_PIN in sketch/program.
[3] The SDA pin might be labeled SS on some/older MFRC522 boards
=============================================================
*/
//===========================================================
#include <SPI.h>
#include <MFRC522.h>

#define RST_PIN      27        // 讀卡機的重置腳位
#define SS_PIN       5        // 晶片選擇腳位
MFRC522 mfrc522(SS_PIN, RST_PIN);    // 建立MFRC522物件
MFRC522::MIFARE_Key key;  // 儲存金鑰
MFRC522::StatusCode status;
String json = "";
const char *topic1 = "alex9ufo/RFID/read";
const char *topic3 = "alex9ufo/RFID/back";

byte sector = 15;   // 指定讀寫的「區段」,可能值:0~15
byte block = 1;     // 指定讀寫的「區塊」,可能值:0~3
byte blockData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} ;   // 最多可存入16個字元
// 若要清除區塊內容,請寫入16個 0
//byte blockData[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
// 暫存讀取區塊內容的陣列,MIFARE_Read()方法要求至少要18位元組空間,來存放16位元組。
byte bufferarray[18] = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 } ;
bool RD_flag=false;
bool Pub_flag=false;
//===========================================================
void onMqttMessage(int messageSize) {
  // we received a message, print out the topic and contents
  Serial.print("Received a message with topic '");
  Serial.print(mqttClient.messageTopic());
  String Topic= mqttClient.messageTopic();
  Serial.print("', duplicate = ");
  Serial.print(mqttClient.messageDup() ? "true" : "false");
  Serial.print(", QoS = ");
  Serial.print(mqttClient.messageQoS());
  Serial.print(", retained = ");
  Serial.print(mqttClient.messageRetain() ? "true" : "false");
  Serial.print("', length ");
  Serial.print(messageSize);
  Serial.println(" bytes:");
  String topicIN="";
  // use the Stream interface to print the contents
  while (mqttClient.available()) {
    //Serial.print((char)mqttClient.read());
    topicIN=topicIN+(char)mqttClient.read();

  }

  Serial.println(topicIN);
  topicIN.trim();

  String  sec1 ,blk1 ,text1;
  sec1=topicIN.substring(0,2);
  blk1=topicIN.substring(3,5);
  text1=topicIN.substring(6);
  sector = sec1.toInt();
  block  = blk1.toInt();


  if (Topic.substring(14,18) == "read") {
    sec1=topicIN.substring(0,2);
    blk1=topicIN.substring(3,5);
    //String  text1=message.subString(6);
    sector = sec1.toInt();
    block  = blk1.toInt();  

 
    RD_flag=true;
    Serial.print ("Topic: ");    
    Serial.println(Topic);
    Serial.print ("Sector: ");
    Serial.print(sec1);
    Serial.print ("  Block: ");
    Serial.print(blk1);
    Serial.println();
  }
}
//===========================================================
//副程式  setup wifi
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);     //print ssid
  WiFi.begin(ssid, pass);  //初始化WiFi 函式庫並回傳目前的網路狀態
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }   //假設 wifi 未連接 show ………

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}  
//===========================================================
void dump_byte_array(byte *buffer, byte bufferSize) {
  for (byte i = 0; i < bufferSize; i++) {
    Serial.print(buffer[i] < 0x10 ? " 0" : " ");
    Serial.print(buffer[i], HEX);
  }
}
//===========================================================
String printHex(byte *buffer, byte bufferSize) {
      String id = "";
      for (byte i = 0; i < bufferSize; i++) {
        id += buffer[i] < 0x10 ? "0" : "";
        id += String(buffer[i], HEX);
        id +=" ";
      }
      return id;
}
//===========================================================
void setup() {
  pinMode(LED, OUTPUT);     // 設置板上LED引腳為輸出模式
  digitalWrite(LED, HIGH);  // 啟動後關閉板上LED
  //Initialize serial and wait for port to open:
  Serial.begin(115200);
  // Connecting to a WiFi network
  setup_wifi();
  Serial.println("You're connected to the network");
  Serial.println();

  // You can provide a unique client ID, if not set the library uses Arduino-millis()
  // Each client must have a unique client ID
  // mqttClient.setId("clientId");

  // You can provide a username and password for authentication
  // mqttClient.setUsernamePassword("username", "password");

  // By default the library connects with the "clean session" flag set,
  // you can disable this behaviour by using
  // mqttClient.setCleanSession(false);

  // set a will message, used by the broker when the connection dies unexpectedly
  // you must know the size of the message beforehand, and it must be set before connecting
  String willPayload = "oh no!";
  bool willRetain = true;
  int willQos = 1;

  mqttClient.beginWill(willTopic, willPayload.length(), willRetain, willQos);
  mqttClient.print(willPayload);
  mqttClient.endWill();

  Serial.print("Attempting to connect to the MQTT broker: ");
  Serial.println(broker);

  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());

    while (1);
  }

  Serial.println("You're connected to the MQTT broker!");
  Serial.println();

  // set the message receive callback
  mqttClient.onMessage(onMqttMessage);

  Serial.print("Subscribing to topic: ");
  Serial.println(inTopic);
  Serial.println(topic1);
 
  Serial.println();

  // subscribe to a topic
  // the second parameter sets the QoS of the subscription,
  // the the library supports subscribing at QoS 0, 1, or 2
  int subscribeQos = 1;

  mqttClient.subscribe(inTopic, subscribeQos);
  mqttClient.subscribe(topic1, subscribeQos);

  // topics can be unsubscribed using:
  // mqttClient.unsubscribe(inTopic);

  Serial.print("Waiting for messages on topic: ");
  Serial.println(inTopic);
  Serial.println();
  //啟動 mfrc522
  SPI.begin();
  mfrc522.PCD_Init();   // 初始化MFRC522讀卡機模組
  Serial.println(F("Please scan MIFARE Classic card..."));
  // 準備金鑰(用於key A和key B),出廠預設為6組 0xFF。
  for (byte i = 0; i < 6; i++) {
    key.keyByte[i] = 0xFF;
  }
}
//===========================================================
void loop() {
  // call poll() regularly to allow the library to receive MQTT messages and
  // send MQTT keep alives which avoids being disconnected by the broker
  mqttClient.poll();

 
 if (mfrc522.PICC_IsNewCardPresent() && mfrc522.PICC_ReadCardSerial()) {
   
     Serial.println(F("Please scan MIFARE Classic card..."));
    // 確認是否有新卡片
   
    byte *id = mfrc522.uid.uidByte;   // 取得卡片的UID
    byte idSize = mfrc522.uid.size;   // 取得UID的長度
    String Type;
    Serial.print("PICC type: ");      // 顯示卡片類型
    // 根據卡片回應的SAK值(mfrc522.uid.sak)判斷卡片類型
    MFRC522::PICC_Type piccType = mfrc522.PICC_GetType(mfrc522.uid.sak);
    Type= mfrc522.PICC_GetTypeName(piccType);
    Serial.println(mfrc522.PICC_GetTypeName(piccType));

    Serial.print("UID Size: ");       // 顯示卡片的UID長度值
    Serial.println(idSize);
 
    for (byte i = 0; i < idSize; i++) {  // 逐一顯示UID碼
      Serial.print("id[");
      Serial.print(i);
      Serial.print("]: ");
      Serial.println(id[i], HEX);       // 以16進位顯示UID值
    }
    Serial.println();



    json="";
    json = json +(" Card UID: ");
    String json1=printHex(mfrc522.uid.uidByte, mfrc522.uid.size);
    json1.toUpperCase();
    json = json + json1;
    json.trim();
    json = json +(" , PICC type: ");
    json =  json + Type;
    json.trim();

    bool retained = false;
    int qos = 1;
    bool dup = false;

    mqttClient.beginMessage(topic3,  json.length(), retained, qos, dup);
    mqttClient.print(json);
    mqttClient.endMessage();

    Serial.println();
    // Dump debug info about the card; PICC_HaltA() is automatically called
    // 令卡片進入停止狀態
    mfrc522.PICC_HaltA();
    mfrc522.PCD_StopCrypto1(); // stop encryption on PCD

}


}
//===========================================================


沒有留言:

張貼留言

2024_09 作業3 以Node-Red 為主

 2024_09 作業3  (以Node-Red 為主  Arduino 可能需要配合修改 ) Arduino 可能需要修改的部分 1)mqtt broker  2) 主題Topic (發行 接收) 3) WIFI ssid , password const char br...