WOKWI + IoT MQTT Panel+ Node-Red
// Wifi 與 MQttClient 程式庫
#include <ArduinoMqttClient.h>
#include <WiFi.h>
//#include "arduino_secrets1.h"
//#define LED 13 //定義LED接腳
int LED = 13;
const char ssid[] = "Wokwi-GUEST"; // Enter your Wi-Fi name
const char pass[] = ""; // Enter Wi-Fi password
WiFiClient wifiClient;
MqttClient mqttClient(wifiClient);
//const char broker[] = "test.mosquitto.org";
const char broker[] = "broker.emqx.io";
int port = 1883;
String json = "";
const char *SubTopic1 = "alex9ufo/sw1";
const char *PubTopic2 = "alex9ufo/led1";
const char willTopic[] = "alex9ufo/2024/RFID/Starting";
//==========================================================
//布林代數 LED狀態 是否連上網路ESP32 ready ?
bool ledState = false;
bool atwork = false;
bool Send = false; //true
String LEDjson = "";
int Count= 0;
bool Flash = false; //true
bool Timer = false; //true
//===========================================================
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 message="";
// use the Stream interface to print the contents
while (mqttClient.available()) {
//Serial.print((char)mqttClient.read());
message += (char)mqttClient.read();
}
Serial.println(message);
message.trim();
Topic.trim();
if (Topic=="alex9ufo/sw1") {
if (message == "on") {
digitalWrite(LED, LOW); // Turn on the LED
//ledState = true; //ledState = ture HIGH
//設定 各個 旗號
LEDjson ="ON";
Flash = false;
Send = true ;
Serial.print("LED =");
Serial.println(LEDjson);
}
if (message == "off" ) {
digitalWrite(LED, HIGH); // Turn off the LED
//ledState = false; //ledState = false LOW
LEDjson ="OFF";
Flash = false;
Send = true ;
Serial.print("LED =");
Serial.println(LEDjson);
}
if (message == "flash" ) {
digitalWrite(LED, HIGH); // Turn off the LED
Flash = true;
Timer = false;
LEDjson ="FLASH";
Send = true ;
Serial.print("LED =");
Serial.println(LEDjson);
}
if (message == "timer" ) {
digitalWrite(LED, LOW); // Turn off the LED
Flash = false;
Timer = true;
LEDjson ="TIMER";
Send = true ;
Count= 11;
Serial.print("LED =");
Serial.println(LEDjson);
}
Serial.println();
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());
}
//===========================================================
//判斷 旗號Flash , Timer 是否為真
void LED_Message() {
//判斷 旗號 Flash / timer 是否為真 ? 閃爍 定時
if (Flash){
digitalWrite(LED, !digitalRead(LED));
delay(500);
if (digitalRead(LED))
ledState = true;
else
ledState = false;
} //(Flash)
if (Timer) {
digitalWrite(LED, LOW);
delay(500);
if (digitalRead(LED))
ledState = true;
else
ledState = false;
Count=Count-1;
if (Count == 0 ){
Timer=false;
digitalWrite(LED, HIGH);
ledState = false;
}
} //(Timer)
////判斷 旗號 Send 是否為真 回傳MQTT訊息到MQTT Broker
if (Send) {
// Convert JSON string to character array
Serial.print("Publish message: ");
Serial.println(LEDjson);
LEDjson.trim();
bool retained = false;
int qos = 1;
bool dup = false;
// Publish JSON character array to MQTT topic
mqttClient.beginMessage(PubTopic2, LEDjson.length(), retained, qos, dup); //LED Status
mqttClient.print(LEDjson);
mqttClient.endMessage();
Send = false; //處理過後 旗號 Send為假
}
}
//===========================================================
void setup() {
pinMode(LED, OUTPUT);
digitalWrite(LED, HIGH); // Turn off the LED initially
//Initialize serial and wait for port to open:
Serial.begin(115200); // Initialize serial communications with the PC
while (!Serial); // Do nothing if no serial port is opened (added for Arduinos based on ATMEGA32U4)
setup_wifi();
Serial.println("You're connected to the network");
Serial.println();
String willPayload = "ESP32 Start working....!";
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(SubTopic1);
// 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(SubTopic1, subscribeQos);
}
//===========================================================
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();
LED_Message();
}
////===========================================================
[
{
"id": "c5aa76af923f7f58",
"type": "sqlite",
"z": "5ac0dcc9b2371c86",
"mydb": "f5c97c74cc496505",
"sqlquery": "msg.topic",
"sql": "",
"name": "LED_STATUS",
"x": 540,
"y": 380,
"wires": [
[
"27efa6abf9cbb4ee"
]
]
},
{
"id": "b828b27417d30085",
"type": "function",
"z": "5ac0dcc9b2371c86",
"name": "CREATE DATABASE",
"func": "//CREATE TABLE LEDSTATUS (\n//id INTEGER,\n//STATUS TEXT,\n//Date DATE,\n//Time TIME,\n//PRIMARY KEY (id)\n//);\n//CREATE TABLE LEDSTATUS (id INTEGER,STATUS TEXT,Date DATE,Time TIME,PRIMARY KEY (id));\nmsg.topic = \"CREATE TABLE LEDSTATUS (id INTEGER,STATUS TEXT,Date DATE,Time TIME,PRIMARY KEY (id))\";\nreturn msg;\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 320,
"y": 380,
"wires": [
[
"c5aa76af923f7f58"
]
]
},
{
"id": "7c9ce84a58e9c7c6",
"type": "ui_button",
"z": "5ac0dcc9b2371c86",
"name": "",
"group": "a4f973bfe806b409",
"order": 7,
"width": 2,
"height": 1,
"passthru": false,
"label": "建立LED資料庫",
"tooltip": "",
"color": "",
"bgcolor": "",
"className": "",
"icon": "",
"payload": "建立資料庫",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"x": 100,
"y": 380,
"wires": [
[
"b828b27417d30085",
"8a34af6b3043f18b"
]
]
},
{
"id": "d600380920810b2c",
"type": "ui_button",
"z": "5ac0dcc9b2371c86",
"name": "",
"group": "a4f973bfe806b409",
"order": 1,
"width": 2,
"height": 1,
"passthru": false,
"label": "ON",
"tooltip": "",
"color": "",
"bgcolor": "",
"className": "",
"icon": "",
"payload": "on",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"x": 70,
"y": 20,
"wires": [
[
"853f81265d7f417a",
"c46e8dac6baed7b8",
"b6406d3708209514"
]
]
},
{
"id": "8a81fcaa99d572b0",
"type": "ui_button",
"z": "5ac0dcc9b2371c86",
"name": "",
"group": "a4f973bfe806b409",
"order": 2,
"width": 2,
"height": 1,
"passthru": false,
"label": "OFF",
"tooltip": "",
"color": "",
"bgcolor": "",
"className": "",
"icon": "",
"payload": "off",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"x": 70,
"y": 60,
"wires": [
[
"853f81265d7f417a",
"c46e8dac6baed7b8",
"b6406d3708209514"
]
]
},
{
"id": "184a7cf3f412a863",
"type": "ui_button",
"z": "5ac0dcc9b2371c86",
"name": "",
"group": "a4f973bfe806b409",
"order": 3,
"width": 2,
"height": 1,
"passthru": false,
"label": "TIMER",
"tooltip": "",
"color": "",
"bgcolor": "",
"className": "",
"icon": "",
"payload": "timer",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"x": 80,
"y": 100,
"wires": [
[
"853f81265d7f417a",
"c46e8dac6baed7b8",
"b6406d3708209514"
]
]
},
{
"id": "9d0bd7688496f671",
"type": "ui_button",
"z": "5ac0dcc9b2371c86",
"name": "",
"group": "a4f973bfe806b409",
"order": 4,
"width": 2,
"height": 1,
"passthru": false,
"label": "FLASH",
"tooltip": "",
"color": "",
"bgcolor": "",
"className": "",
"icon": "",
"payload": "flash",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"x": 80,
"y": 140,
"wires": [
[
"853f81265d7f417a",
"c46e8dac6baed7b8",
"b6406d3708209514"
]
]
},
{
"id": "eb51a0c1908bb83d",
"type": "function",
"z": "5ac0dcc9b2371c86",
"name": "INSERT",
"func": "var Today = new Date();\nvar yyyy = Today.getFullYear(); //年\nvar MM = Today.getMonth()+1; //月\nvar dd = Today.getDate(); //日\nvar h = Today.getHours(); //時\nvar m = Today.getMinutes(); //分\nvar s = Today.getSeconds(); //秒\nif(MM<10)\n{\n MM = '0'+MM;\n}\n\nif(dd<10)\n{\n dd = '0'+dd;\n}\n\nif(h<10)\n{\n h = '0'+h;\n}\n\nif(m<10)\n{\n m = '0' + m;\n}\n\nif(s<10)\n{\n s = '0' + s;\n}\nvar var_date = yyyy+'/'+MM+'/'+dd;\nvar var_time = h+':'+m+':'+s;\n\nvar myLED = msg.payload;\n\n\nmsg.topic = \"INSERT INTO LEDSTATUS ( STATUS , Date , Time ) VALUES ($myLED, $var_date , $var_time ) \" ;\nmsg.payload = [myLED, var_date , var_time ]\nreturn msg;\n\n\n//INSERT INTO LEDSTATUS (\n//id INTEGER,\n//STATUS TEXT,\n//Date DATE,\n//Time TIME,\n//PRIMARY KEY (id)\n//);\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 280,
"y": 240,
"wires": [
[
"c2294ca83046a6a8",
"ed45bf6fa0449143"
]
]
},
{
"id": "853f81265d7f417a",
"type": "ui_audio",
"z": "5ac0dcc9b2371c86",
"name": "",
"group": "a4f973bfe806b409",
"voice": "Microsoft Hanhan - Chinese (Traditional, Taiwan)",
"always": true,
"x": 245,
"y": 80,
"wires": [],
"l": false
},
{
"id": "c2294ca83046a6a8",
"type": "sqlite",
"z": "5ac0dcc9b2371c86",
"mydb": "f5c97c74cc496505",
"sqlquery": "msg.topic",
"sql": "",
"name": "LED_STATUS",
"x": 440,
"y": 240,
"wires": [
[
"727a752dd0efde03",
"8a83c8bbcfd46f16"
]
]
},
{
"id": "27efa6abf9cbb4ee",
"type": "debug",
"z": "5ac0dcc9b2371c86",
"name": "debug ",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 690,
"y": 380,
"wires": []
},
{
"id": "727a752dd0efde03",
"type": "debug",
"z": "5ac0dcc9b2371c86",
"name": "debug ",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 630,
"y": 240,
"wires": []
},
{
"id": "3c4ed0b0d50c313b",
"type": "ui_button",
"z": "5ac0dcc9b2371c86",
"name": "",
"group": "a4f973bfe806b409",
"order": 9,
"width": 2,
"height": 1,
"passthru": false,
"label": "檢視資料庫資料",
"tooltip": "",
"color": "",
"bgcolor": "",
"className": "",
"icon": "",
"payload": "檢視資料",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"x": 100,
"y": 320,
"wires": [
[
"8a83c8bbcfd46f16",
"8a34af6b3043f18b"
]
]
},
{
"id": "8a83c8bbcfd46f16",
"type": "function",
"z": "5ac0dcc9b2371c86",
"name": "檢視資料",
"func": "//INSERT INTO LEDSTATUS (\n//id INTEGER,\n//STATUS TEXT,\n//Date DATE,\n//Time TIME,\n//PRIMARY KEY (id)\n//);\n\n//SELECT * FROM LEDSTATUS ORDER BY id DESC LIMIT 50;\n\nmsg.topic = \"SELECT * FROM LEDSTATUS ORDER BY id DESC LIMIT 50\";\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 400,
"y": 320,
"wires": [
[
"063f373de357143f"
]
]
},
{
"id": "479ed14e926a7249",
"type": "ui_table",
"z": "5ac0dcc9b2371c86",
"group": "a4f973bfe806b409",
"name": "",
"order": 10,
"width": 8,
"height": 7,
"columns": [],
"outputs": 0,
"cts": false,
"x": 730,
"y": 320,
"wires": []
},
{
"id": "063f373de357143f",
"type": "sqlite",
"z": "5ac0dcc9b2371c86",
"mydb": "f5c97c74cc496505",
"sqlquery": "msg.topic",
"sql": "",
"name": "LED_STATUS",
"x": 580,
"y": 320,
"wires": [
[
"479ed14e926a7249"
]
]
},
{
"id": "ab233348d9ada221",
"type": "sqlite",
"z": "5ac0dcc9b2371c86",
"mydb": "f5c97c74cc496505",
"sqlquery": "msg.topic",
"sql": "",
"name": "LED_STATUS",
"x": 860,
"y": 440,
"wires": [
[
"c0418a0d5597ab8c"
]
]
},
{
"id": "6d75b939206467c1",
"type": "ui_button",
"z": "5ac0dcc9b2371c86",
"name": "",
"group": "a4f973bfe806b409",
"order": 5,
"width": 2,
"height": 1,
"passthru": false,
"label": "刪除所有資料 ",
"tooltip": "",
"color": "",
"bgcolor": "",
"className": "",
"icon": "",
"payload": "刪除所有資料 ",
"payloadType": "str",
"topic": "topic",
"topicType": "msg",
"x": 100,
"y": 440,
"wires": [
[
"4b5568863d72eab6",
"2719587fe3d60360"
]
]
},
{
"id": "cd756cbe3e25a9ef",
"type": "function",
"z": "5ac0dcc9b2371c86",
"name": "DELETE ALL DATA",
"func": "//CREATE TABLE LEDSTATUS (\n//id INTEGER,\n//STATUS TEXT,\n//Date DATE,\n//Time TIME,\n//PRIMARY KEY (id)\n//);\n//CREATE TABLE LEDSTATUS (id INTEGER,STATUS TEXT,Date DATE,Time TIME,PRIMARY KEY (id));\nmsg.topic = \"DELETE from LEDSTATUS\";\nreturn msg;\n",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 670,
"y": 440,
"wires": [
[
"ab233348d9ada221"
]
]
},
{
"id": "4b5568863d72eab6",
"type": "ui_audio",
"z": "5ac0dcc9b2371c86",
"name": "",
"group": "a4f973bfe806b409",
"voice": "Microsoft Hanhan - Chinese (Traditional, Taiwan)",
"always": true,
"x": 225,
"y": 500,
"wires": [],
"l": false
},
{
"id": "2719587fe3d60360",
"type": "ui_toast",
"z": "5ac0dcc9b2371c86",
"position": "prompt",
"displayTime": "3",
"highlight": "",
"sendall": true,
"outputs": 1,
"ok": "OK",
"cancel": "Cancel",
"raw": true,
"className": "",
"topic": "",
"name": "",
"x": 290,
"y": 440,
"wires": [
[
"a83b6434dccb201a"
]
]
},
{
"id": "a83b6434dccb201a",
"type": "function",
"z": "5ac0dcc9b2371c86",
"name": "OK or Cancel",
"func": "var topic=msg.payload;\nif (topic==\"\"){\n return [msg,null];\n \n}\nif (topic==\"Cancel\"){\n return [null,msg];\n \n}\nreturn msg;",
"outputs": 2,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 460,
"y": 440,
"wires": [
[
"cd756cbe3e25a9ef"
],
[]
]
},
{
"id": "8a34af6b3043f18b",
"type": "ui_audio",
"z": "5ac0dcc9b2371c86",
"name": "",
"group": "a4f973bfe806b409",
"voice": "Microsoft Hanhan - Chinese (Traditional, Taiwan)",
"always": true,
"x": 245,
"y": 340,
"wires": [],
"l": false
},
{
"id": "c0418a0d5597ab8c",
"type": "link out",
"z": "5ac0dcc9b2371c86",
"name": "link out 57",
"mode": "link",
"links": [
"8159eed66b810c64"
],
"x": 845,
"y": 380,
"wires": []
},
{
"id": "8159eed66b810c64",
"type": "link in",
"z": "5ac0dcc9b2371c86",
"name": "link in 55",
"links": [
"c0418a0d5597ab8c"
],
"x": 915,
"y": 380,
"wires": [
[
"8a83c8bbcfd46f16"
]
]
},
{
"id": "c46e8dac6baed7b8",
"type": "mqtt out",
"z": "5ac0dcc9b2371c86",
"name": "Control LED out",
"topic": "alex9ufo/sw1",
"qos": "1",
"retain": "true",
"respTopic": "",
"contentType": "",
"userProps": "",
"correl": "",
"expiry": "",
"broker": "603bb104.d6134",
"x": 280,
"y": 20,
"wires": []
},
{
"id": "1e1d4be0b371f61e",
"type": "mqtt in",
"z": "5ac0dcc9b2371c86",
"name": "Control LED in",
"topic": "alex9ufo/led1",
"qos": "1",
"datatype": "auto-detect",
"broker": "603bb104.d6134",
"nl": false,
"rap": true,
"rh": 0,
"inputs": 0,
"x": 100,
"y": 240,
"wires": [
[
"eb51a0c1908bb83d"
]
]
},
{
"id": "ed45bf6fa0449143",
"type": "function",
"z": "5ac0dcc9b2371c86",
"name": "增加 日期 時間",
"func": "var ms1=msg.payload[0];\nvar ms2=msg.payload[1];\nvar ms3=msg.payload[2];\n\nmsg.payload=\"新增一筆:\"+ms1+\", 日期: \"+ms2+\", 時間:\"+ms3;\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 440,
"y": 560,
"wires": [
[
"0d83415fea7049d4"
]
]
},
{
"id": "0d83415fea7049d4",
"type": "function",
"z": "5ac0dcc9b2371c86",
"name": "Set Line API ",
"func": "msg.headers = {'content-type':'application/x-www-form-urlencoded','Authorization':'Bearer A4wwPNh2WqB7dlfeQyyIAwtggn1kfZSI5LkkCdia1gB'};\nmsg.payload = {\"message\":msg.payload};\nreturn msg;\n\n//oR7KdXvK1eobRr2sRRgsl4PMq23DjDlhfUs96SyUBZu",
"outputs": 1,
"noerr": 0,
"x": 610,
"y": 560,
"wires": [
[
"efb7573d4730829c"
]
]
},
{
"id": "efb7573d4730829c",
"type": "http request",
"z": "5ac0dcc9b2371c86",
"name": "",
"method": "POST",
"ret": "txt",
"paytoqs": false,
"url": "https://notify-api.line.me/api/notify",
"tls": "",
"persist": false,
"proxy": "",
"authType": "",
"x": 760,
"y": 560,
"wires": [
[
"cbb012945f38ffa1"
]
]
},
{
"id": "cbb012945f38ffa1",
"type": "debug",
"z": "5ac0dcc9b2371c86",
"name": "debug ",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 890,
"y": 560,
"wires": []
},
{
"id": "485a0a5eba40e7a6",
"type": "comment",
"z": "5ac0dcc9b2371c86",
"name": "Line Notify Message ",
"info": "",
"x": 510,
"y": 500,
"wires": []
},
{
"id": "b6406d3708209514",
"type": "debug",
"z": "5ac0dcc9b2371c86",
"name": "debug ",
"active": true,
"tosidebar": true,
"console": false,
"tostatus": false,
"complete": "payload",
"targetType": "msg",
"statusVal": "",
"statusType": "auto",
"x": 310,
"y": 140,
"wires": []
},
{
"id": "f5c97c74cc496505",
"type": "sqlitedb",
"db": "C:\\Users\\User\\.node-red\\2024EX_LED2.db",
"mode": "RWC"
},
{
"id": "a4f973bfe806b409",
"type": "ui_group",
"name": "LED",
"tab": "3469785e1c4b892d",
"order": 1,
"disp": true,
"width": 8,
"collapse": false,
"className": ""
},
{
"id": "603bb104.d6134",
"type": "mqtt-broker",
"name": "",
"broker": "broker.emqx.io",
"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": "3469785e1c4b892d",
"type": "ui_tab",
"name": "2024勤益2",
"icon": "dashboard",
"order": 126,
"disabled": false,
"hidden": false
}
]
沒有留言:
張貼留言