2023年12月31日 星期日

Node-Red MQTT基本實驗

 Node-Red MQTT基本實驗













ON Bouuton 節點

Payload : on

OFF Bouuton 節點

Payload : off

MQTT out節點

Server :broker.hivemq.com : 1883

Qos=1  保留:

發行主題 : alex9ufo/node-red/out

MQTT in節點

Server :broker.hivemq.com : 1883

Qos=1  保留:

發行主題 : alex9ufo/node-red/out

Audio Out 節點

1.     Microsoft Yatinf—Chinese

Function 節點

var onoff=msg.payload;

 

if (onoff=="on")

{

    msg.payload=true;

}

if (onoff=="off")

{

    msg.payload=false;

return msg;

勤益科大 Bouuton 節點

Payload :  勤益科大

Hello  Bouuton 節點

Payload :  hello

MQTT out節點

Server :broker.hivemq.com : 1883

Qos=1  保留:

發行主題 :  alex9ufo/esp32/hello

MQTT in節點

Server :broker.hivemq.com : 1883

Qos=1  保留:

發行主題 : alex9ufo/esp32/hello

Text 節點

Label : 訂閱主題 :

Value format{{msg.payload}}

Layout: 上中

 

Node-Red程式

[{"id":"5985ccd980cadbc0","type":"mqtt in","z":"67d337ef020161d4","name":"node-red/out","topic":"alex9ufo/node-red/out","qos":"1","datatype":"auto-detect","broker":"841df58d.ee5e98","nl":false,"rap":true,"rh":0,"inputs":0,"x":150,"y":320,"wires":[["7d50813717d9c144","29cfb54d20b988ba"]]},{"id":"7d50813717d9c144","type":"function","z":"67d337ef020161d4","name":"function LED on ,off","func":"var onoff=msg.payload;\n\nif (onoff==\"on\")\n{\n    msg.payload=true;\n}\nif (onoff==\"off\")\n{\n    msg.payload=false;\n}  \nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":330,"y":320,"wires":[["ccb103c0fc516c71"]]},{"id":"ccb103c0fc516c71","type":"ui_led","z":"67d337ef020161d4","order":3,"group":"680cff3c5de3a744","width":3,"height":2,"label":"","labelPlacement":"left","labelAlignment":"left","colorForValue":[{"color":"#ff0000","value":"false","valueType":"bool"},{"color":"#008000","value":"true","valueType":"bool"}],"allowColorForValueInMessage":false,"shape":"circle","showGlow":true,"name":"","x":490,"y":320,"wires":[]},{"id":"cfd2998590e660dd","type":"ui_button","z":"67d337ef020161d4","name":"","group":"680cff3c5de3a744","order":9,"width":3,"height":1,"passthru":false,"label":"ON","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"on","payloadType":"str","topic":"topic","topicType":"msg","x":130,"y":240,"wires":[["3cbd0b17930c8655"]]},{"id":"5da71322cb4f139e","type":"ui_button","z":"67d337ef020161d4","name":"","group":"680cff3c5de3a744","order":11,"width":3,"height":1,"passthru":false,"label":"OFF","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"off","payloadType":"str","topic":"topic","topicType":"msg","x":130,"y":280,"wires":[["3cbd0b17930c8655"]]},{"id":"3cbd0b17930c8655","type":"mqtt out","z":"67d337ef020161d4","name":"node-red/out","topic":"alex9ufo/node-red/out","qos":"1","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"841df58d.ee5e98","x":310,"y":260,"wires":[]},{"id":"18f3c0d36c1ff134","type":"ui_button","z":"67d337ef020161d4","name":"","group":"680cff3c5de3a744","order":14,"width":3,"height":1,"passthru":false,"label":"hello","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"hello","payloadType":"str","topic":"topic","topicType":"msg","x":130,"y":440,"wires":[["e3c069f1897ee572"]]},{"id":"e3c069f1897ee572","type":"mqtt out","z":"67d337ef020161d4","name":"esp32/hello","topic":"alex9ufo/esp32/hello","qos":"1","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"841df58d.ee5e98","x":310,"y":440,"wires":[]},{"id":"3e679a331c7d78a1","type":"mqtt in","z":"67d337ef020161d4","name":"esp32/hello","topic":"alex9ufo/esp32/hello","qos":"1","datatype":"auto-detect","broker":"841df58d.ee5e98","nl":false,"rap":true,"rh":0,"inputs":0,"x":150,"y":500,"wires":[["a59845502a7ca7e7","998d7a289c204070"]]},{"id":"a59845502a7ca7e7","type":"ui_text","z":"67d337ef020161d4","group":"680cff3c5de3a744","order":8,"width":0,"height":0,"name":"","label":"訂閱主題 : ","format":"{{msg.payload}}","layout":"row-center","className":"","x":350,"y":500,"wires":[]},{"id":"1336ba3046dc85e9","type":"ui_button","z":"67d337ef020161d4","name":"","group":"680cff3c5de3a744","order":12,"width":3,"height":1,"passthru":false,"label":"勤益科大","tooltip":"","color":"","bgcolor":"","className":"","icon":"","payload":"勤益科大","payloadType":"str","topic":"topic","topicType":"msg","x":140,"y":400,"wires":[["e3c069f1897ee572"]]},{"id":"29cfb54d20b988ba","type":"ui_audio","z":"67d337ef020161d4","name":"","group":"680cff3c5de3a744","voice":"Microsoft Yating - Chinese (Traditional, Taiwan)","always":"","x":300,"y":360,"wires":[]},{"id":"998d7a289c204070","type":"ui_audio","z":"67d337ef020161d4","name":"","group":"680cff3c5de3a744","voice":"Microsoft Yating - Chinese (Traditional, Taiwan)","always":"","x":340,"y":540,"wires":[]},{"id":"841df58d.ee5e98","type":"mqtt-broker","name":"","broker":"broker.hivemq.com","port":"1883","clientid":"","autoConnect":true,"usetls":false,"compatmode":false,"protocolVersion":"4","keepalive":"15","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"680cff3c5de3a744","type":"ui_group","name":"LED ON OFF","tab":"68b2e080d17dd8ac","order":2,"disp":true,"width":7,"collapse":false,"className":""},{"id":"68b2e080d17dd8ac","type":"ui_tab","name":"LED","icon":"dashboard","order":1,"disabled":false,"hidden":false}]

2023年12月29日 星期五

實驗1-2 2023-08 ESP32 + RFID + MQTT Explorer + Google App MyMQTT + Node-Red

 實驗1-2 2023-08 ESP32 + RFID + MQTT Explorer + Google App MyMQTT + Node-Red


準備工作

1) Arduino 實習1-1 程式   測試MFRC522 正常工作 (硬體正常)

2) Arduino 實習1-2 程式   測試MFRC522 正常工作 (硬體正常)

3) Node-Red 安裝   節點 dashboard UI 的安裝

4) MQTT Client 軟體  MQTT Explorer 下載安裝  https://mqtt-explorer.com/

5) Andriod APP MyMQTT 下載安裝   https://play.google.com/store/apps/details?id=at.tripwire.mqtt.client&hl=zh_TW&gl=US

或 Snopper MQTT APP 

6) MQTT相關概念

7)  broker.mqtt-dashboard.com  =  broker.hivemq.com    MQTT Server (Broker)

8) 每一個 node-red MQTT in 及 MQTT out 的節點 中 alex9ufo/esp32/RFID  alex9ufo/esp32/led 需修改成自己的
例如  john9012/esp32/RFID ,  john9012/esp32/led

包含MQTT Explorer / MyMQTT / Snooper MQTT 中的訂閱發行主題都需要 隨之更改  john9012/esp32/RFID ,  john9012/esp32/led


9)  需修改wifi 密碼 MQTT Broker topic Mqtt username , password

// WiFi
const char *ssid = "alex9ufo"; // Enter your Wi-Fi name
const char *password = "alex9981";  // Enter Wi-Fi password

// MQTT Broker
const char *mqtt_broker = "broker.mqtt-dashboard.com";
const char *topic1 = "alex9ufo/esp32/led";
const char *topic2 = "alex9ufo/esp32/RFID";

const char *mqtt_username = "alex9ufo";
const char *mqtt_password = "public";
const int mqtt_port = 1883;

 實驗1-2 2023-08  ESP32 + RFID + MQTT Explorer + Google App MyMQTT + Node-Red






// MQTT Broker
const char *mqtt_broker = "broker.mqtt-dashboard.com";
const char *topic1 = "alex9ufo/esp32/led";
const char *topic2 = "alex9ufo/esp32/RFID";


































  或






Node-Red 程式 

[{"id":"e4cba267a9614782","type":"tab","label":"2023 EX1-2 實驗","disabled":false,"info":"","env":[]},{"id":"580c94b9d2d28477","type":"ui_button","z":"e4cba267a9614782","name":"","group":"a79f81eec37ec414","order":2,"width":2,"height":1,"passthru":false,"label":"LED 開","tooltip":"","color":"white","bgcolor":"","className":"","icon":"fa-circle","payload":"on","payloadType":"str","topic":"","topicType":"str","x":140,"y":80,"wires":[["e04b9ae6c9cf13a0","1ddef96e0b39a7ed","5763812d921d3686"]]},{"id":"8d12b5b63d88d34d","type":"ui_button","z":"e4cba267a9614782","name":"","group":"a79f81eec37ec414","order":4,"width":2,"height":1,"passthru":false,"label":"LED 關","tooltip":"","color":"black","bgcolor":"","className":"","icon":"fa-circle-o","payload":"off","payloadType":"str","topic":"","topicType":"str","x":140,"y":160,"wires":[["e04b9ae6c9cf13a0","1ddef96e0b39a7ed","5763812d921d3686"]]},{"id":"e04b9ae6c9cf13a0","type":"mqtt out","z":"e4cba267a9614782","name":"Control LED","topic":"alex9ufo/esp32/led","qos":"1","retain":"true","respTopic":"","contentType":"","userProps":"","correl":"","expiry":"","broker":"70940176.2b2d3","x":410,"y":80,"wires":[]},{"id":"17fde028714c2ffe","type":"comment","z":"e4cba267a9614782","name":"Node-Red publish 到 HiveMQ Broker  , ESP32訂閱","info":"將 alex9ufo/inTopic 到(publish)HiveMQ Broker \n給 Arduino 訂閱(Subscribe)","x":270,"y":40,"wires":[]},{"id":"1ddef96e0b39a7ed","type":"ui_audio","z":"e4cba267a9614782","name":"","group":"a79f81eec37ec414","voice":"Google US English","always":true,"x":400,"y":180,"wires":[]},{"id":"5763812d921d3686","type":"ui_text","z":"e4cba267a9614782","group":"a79f81eec37ec414","order":7,"width":10,"height":2,"name":"","label":"Node-RED發行到MQTT的資料","format":"{{msg.payload}}","layout":"row-left","className":"","x":470,"y":140,"wires":[]},{"id":"1eaabded303264f6","type":"ui_audio","z":"e4cba267a9614782","name":"","group":"a79f81eec37ec414","voice":"Google US English","always":"","x":380,"y":340,"wires":[]},{"id":"a205cc8ff1b96783","type":"mqtt in","z":"e4cba267a9614782","name":"RFID Card","topic":"alex9ufo/esp32/RFID","qos":"2","datatype":"utf8","broker":"841df58d.ee5e98","nl":false,"rap":true,"rh":0,"inputs":0,"x":160,"y":380,"wires":[["1eaabded303264f6","49d0a9e2f1d09530","c702f883eaed76eb"]]},{"id":"49d0a9e2f1d09530","type":"debug","z":"e4cba267a9614782","name":"debug 94","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":380,"y":420,"wires":[]},{"id":"a04b2d423bfd191b","type":"comment","z":"e4cba267a9614782","name":"Node-Red  subscribe HiveMQ Broker  , ESP32發行","info":"將 alex9ufo/inTopic 到(publish)HiveMQ Broker \n給 Arduino 訂閱(Subscribe)","x":260,"y":280,"wires":[]},{"id":"c702f883eaed76eb","type":"ui_text","z":"e4cba267a9614782","group":"a79f81eec37ec414","order":9,"width":10,"height":2,"name":"","label":"Node-RED 訂閱MQTT的資料","format":"{{msg.payload}}","layout":"row-left","className":"","x":440,"y":380,"wires":[]},{"id":"c20cdf6cdf2609a4","type":"ui_spacer","z":"e4cba267a9614782","name":"spacer","group":"d783cb980c3979fc","order":15,"width":1,"height":1},{"id":"e85e51a3af48216e","type":"ui_spacer","z":"e4cba267a9614782","name":"spacer","group":"d783cb980c3979fc","order":17,"width":3,"height":1},{"id":"120bd836dfca057a","type":"ui_spacer","z":"e4cba267a9614782","name":"spacer","group":"d783cb980c3979fc","order":19,"width":2,"height":1},{"id":"9af8d8fdb9bd9a15","type":"ui_spacer","z":"e4cba267a9614782","name":"spacer","group":"d783cb980c3979fc","order":25,"width":4,"height":1},{"id":"b81b04473eaa039b","type":"ui_spacer","z":"e4cba267a9614782","name":"spacer","group":"d783cb980c3979fc","order":26,"width":4,"height":1},{"id":"93cbde851c449753","type":"ui_spacer","z":"e4cba267a9614782","name":"spacer","group":"a79f81eec37ec414","order":1,"width":2,"height":1},{"id":"2ed0422762fdc986","type":"ui_spacer","z":"e4cba267a9614782","name":"spacer","group":"a79f81eec37ec414","order":3,"width":2,"height":1},{"id":"5bc60d501ce5110e","type":"ui_spacer","z":"e4cba267a9614782","name":"spacer","group":"a79f81eec37ec414","order":5,"width":2,"height":1},{"id":"e3355f613e6766e8","type":"ui_spacer","z":"e4cba267a9614782","name":"spacer","group":"a79f81eec37ec414","order":6,"width":10,"height":1},{"id":"91c8bde2df5233d2","type":"ui_spacer","z":"e4cba267a9614782","name":"spacer","group":"a79f81eec37ec414","order":8,"width":10,"height":1},{"id":"a79f81eec37ec414","type":"ui_group","name":"Default","tab":"eeb8e179.a47a4","order":2,"disp":true,"width":"10","collapse":false,"className":""},{"id":"70940176.2b2d3","type":"mqtt-broker","name":"","broker":"broker.mqtt-dashboard.com","port":"1883","clientid":"","autoConnect":true,"usetls":false,"protocolVersion":4,"keepalive":"15","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"841df58d.ee5e98","type":"mqtt-broker","name":"","broker":"broker.hivemq.com","port":"1883","clientid":"","autoConnect":true,"usetls":false,"compatmode":false,"protocolVersion":"4","keepalive":"15","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","birthMsg":{},"closeTopic":"","closePayload":"","closeMsg":{},"willTopic":"","willQos":"0","willPayload":"","willMsg":{},"userProps":"","sessionExpiry":""},{"id":"d783cb980c3979fc","type":"ui_group","name":"Demo","tab":"0449b3b1fea99d52","order":1,"disp":true,"width":"10","collapse":false,"className":""},{"id":"eeb8e179.a47a4","type":"ui_tab","name":"2024 實驗EX1-2","icon":"dashboard","disabled":false,"hidden":false},{"id":"0449b3b1fea99d52","type":"ui_tab","name":"Demo","icon":"dashboard","disabled":false,"hidden":false}]



Node-RED基礎教學
今日講解Node-RED分成兩部分
一、安裝/刪除節點
二、匯入/匯出流程
一、安裝/刪除節點
1.點選右上角的三條橫線下拉選單→「節點管理」(圖1)


2.進入後可以看到已安裝的節點,在此可以禁用或刪除



3.被刪除的節點可以再次重新安裝
4.切換至安裝頁面,上方可輸入關鍵字搜尋
(安裝sqlite)




5.選取要得節點後按下右下角安裝即會進入安裝狀態
特別提醒:安裝和刪除時請確保Node-RED正確運作,切勿關閉或斷線,會造成系統異常而無法開啟和編輯

6.新增的節點將會出現於主畫面左側的節點區



二、匯入/匯出流程

1.點選右上角的三條橫線下拉選單→「匯入、匯出」



(1)匯入:將外部檔案放入自己的Node-RED中編輯使用

(2)匯出:將自己的專案轉成jason或文字碼供他人使用

2.點選「匯入」→「匯入所選檔案」→「匯入」


特別提醒:若匯入他人資料時本身沒有資料中的結點,Node-RED會無法辨識而跳出警示,需要針對該節點去新增安裝後重新匯入一次,始得正常使用
3.點選「匯出」→「現在的節點」→「下載」


(1)按下下載後會匯出jason檔案,需要時再使用匯入功能即可取回資料至Node-RED中
(2)下載旁的「匯出到剪貼簿」會生成文字碼(記事本可開啟),兩種都可以作為匯出的方式
(3)建議當專案完成後即可匯出檔案作為備份以免遺失

Node-Red 操作結果

1) 先觀察 Arduino 是否 連上Wifi 


2)  輸入 127.0.0.1:1880/ui  
進入    Node-Red  UI人機介面



3) LED  ON 








4) LED  OFF



5) RFID 感應顯示 UID
 



Arduino ESP32 程式

//Wifi  + MQTT
#include <WiFi.h>
#include <PubSubClient.h>

//RFID SPI + RC522
#include <SPI.h>
#include <MFRC522.h>

// GPIO 2 D1
#define LED 2

/* Wiring RFID RC522 module
=============================================================================
GND     = GND   3.3V    = 3.3V
The following table shows the typical pin layout used:
 *             MFRC522      ESP32     Arduino       Arduino   Arduino    Arduino          Arduino
 *             Reader/PCD             Uno/101       Mega      Nano v3    Leonardo/Micro   Pro Micro
 * Signal      Pin          Pin       Pin           Pin       Pin        Pin              Pin
 * -----------------------------------------------------------------------------------------
 * RST/Reset   RST          GPIO27    9             5         D9         RESET/ICSP-5     RST
 * SPI SS      SDA(SS)      GPIO5     10            53        D10        10               10
 * SPI MOSI    MOSI         GPIO23    11 / ICSP-4   51        D11        ICSP-4           16
 * SPI MISO    MISO         GPIO19    12 / ICSP-1   50        D12        ICSP-1           14
 * SPI SCK     SCK          GPIO18    13 / ICSP-3   52        D13        ICSP-3           15
 *
[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
=============================================================================
*/
// SPI 
#define SS_PIN  5  // ESP32 pin GIOP5
#define RST_PIN 27 // ESP32 pin GIOP27


// WiFi
const char *ssid = "alex9ufo"; // Enter your Wi-Fi name
const char *password = "alex9981";  // Enter Wi-Fi password

// MQTT Broker
const char *mqtt_broker = "broker.mqtt-dashboard.com";
const char *topic1 = "alex9ufo/esp32/led";
const char *topic2 = "alex9ufo/esp32/RFID";

const char *mqtt_username = "alex9ufo";
const char *mqtt_password = "public";
const int mqtt_port = 1883;

bool ledState = false;

WiFiClient espClient;
PubSubClient client(espClient);
MFRC522 rfid(SS_PIN, RST_PIN); // Create MFRC522 instance

long lastMsg = 0;
char msg[50];
String json = "";    
char jsonChar1[50];  //client.publish("alex9ufo/Esp32/RFID"

//宣告任務Task1
TaskHandle_t Task1;

// Wifi reconnect
unsigned long previousMillis = 0;
unsigned long interval = 30000;
//===========================================================
//任務1副程式Task1_senddata
void Task1_senddata(void * pvParameters ) {
  //無窮迴圈
  for (;;) {
    //偵測上傳旗標是否為true
    Serial.println("Reading RFID tag");
    if (rfid.PICC_IsNewCardPresent()) { // new tag is available
      if (rfid.PICC_ReadCardSerial()) { // NUID has been readed
        MFRC522::PICC_Type piccType = rfid.PICC_GetType(rfid.uid.sak);
        Serial.print("RFID/NFC Tag Type: ");
        Serial.println(rfid.PICC_GetTypeName(piccType));
        String rfidno="";
        // print UID in Serial Monitor in the hex format
        Serial.print("UID:");
        for (int i = 0; i < rfid.uid.size; i++) {
          Serial.print(rfid.uid.uidByte[i] < 0x10 ? " 0" : " ");
          Serial.print(rfid.uid.uidByte[i], HEX);
        }
        Serial.println();

        String json = printHex(rfid.uid.uidByte, rfid.uid.size);
        json.trim();
        json.toUpperCase();
        // Convert JSON string to character array
        json.toCharArray(jsonChar1, json.length()+1);
   
        if  (client.connected()) {
            Serial.print("Publish message: ");
            Serial.println(json);
            // Publish JSON character array to MQTT topic
            client.publish(topic2,jsonChar1);
             
          rfid.PICC_HaltA(); // halt PICC
          rfid.PCD_StopCrypto1(); // stop encryption on PCD
        }  
        else
        {
          Serial.print("MQTT not connected ");
        }
     
      }
    }


    else  
    {
      // PN532 probably timed out waiting for a card
      Serial.println("Timed out waiting for a card");
    }      
    //Task1休息,delay(X)不可省略
    delay(1000);
  }
}

//===========================================================
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 reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect

    if (client.connect("esp32-client-")) {
      Serial.println("connected");
      // Subscribe
      client.subscribe("alex9ufo/esp32/led");
      client.subscribe("alex9ufo/esp32/RFID");      
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
      if (WiFi.status() != WL_CONNECTED)  {
        Serial.println("Reconnecting to WiFi...");
        WiFi.disconnect();
        WiFi.reconnect();
      }
    }
  }
}
//===========================================================
void callback(char *topic, byte *payload, unsigned int length) {
    Serial.print("Message arrived in topic: ");
    Serial.println(topic);
    Serial.print("Message: ");
    String message;
    for (int i = 0; i < length; i++) {
        message += (char) payload[i];  // Convert *byte to string
    }
    Serial.print(message);
    if (message == "on" && !ledState) {
        digitalWrite(LED, HIGH);  // Turn on the LED
        ledState = true;
    }
    if (message == "off" && ledState) {
        digitalWrite(LED, LOW); // Turn off the LED
        ledState = false;
    }
    Serial.println();
    Serial.println("-----------------------");
}
//===========================================================

void setup() {
    // Set software serial baud to 115200;
    Serial.begin(115200);
    delay(1000); // Delay for stability
    //======================================================
    // Connecting to a WiFi network
    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.println("Connecting to WiFi...");
    }
    Serial.println("Connected to the WiFi network");

    // Setting LED pin as output
    pinMode(LED, OUTPUT);
    digitalWrite(LED, LOW);  // Turn off the LED initially
    //======================================================
    SPI.begin();           // Init SPI bus
    rfid.PCD_Init();    // Init MFRC522

    Serial.println(F("Ready!"));
    Serial.println(F("======================================================"));
    Serial.println("Tap an RFID/NFC tag on the RFID-RC522 reader");


    // Connecting to an MQTT broker
    client.setServer(mqtt_broker, mqtt_port);
    client.setCallback(callback);
    while (!client.connected()) {
        String client_id = "esp32-client-";
        client_id += String(WiFi.macAddress());
        Serial.printf("The client %s connects to the public MQTT broker\n", client_id.c_str());
        if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) {
            Serial.println("Public HiveMQ MQTT broker (broker.mqtt-dashboard.com) connected");
        } else {
            Serial.print("Failed with state ");
            Serial.print(client.state());
            delay(2000);
        }
    }

    // Publish and subscribe
    client.subscribe(topic1);
    //在核心0啟動任務1
    xTaskCreatePinnedToCore(
    Task1_senddata, /*任務實際對應的Function*/
      "Task1",        /*任務名稱*/
      10000,          /*堆疊空間*/
      NULL,           /*無輸入值*/
      0,              /*優先序0*/
      &Task1,         /*對應的任務變數位址*/
      0);             /*指定在核心0執行 */

}
//===========================================================
void loop() {
  if (!client.connected()) {
      reconnect();
      Serial.print(" client not connected  reconnect ");
      delay(200);
  }
  client.loop();
  // Process LED message

  unsigned long currentMillis = millis();
  // if WiFi is down, try reconnecting
  if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >=interval)) {
    Serial.print(millis());
    Serial.println("Reconnecting to WiFi...");
    WiFi.disconnect();
    WiFi.reconnect();
    previousMillis = currentMillis;
    client.setCallback(callback);
  }

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

Messaging API作為替代方案

  LINE超好用功能要沒了!LINE Notify明年3月底終止服務,有什麼替代方案? LINE Notify將於2025年3月31日結束服務,官方建議改用Messaging API作為替代方案。 //CHANNEL_ACCESS_TOKEN = 'Messaging ...