WOKWI ESP32 4 LED + Thingboard UI 控制
Thingboard dashboard儀表板的檔案
https://mega.nz/file/p4dDCSaS#QrfrVfoW55pXwiXqSYSgZPomXUtQFzqIj8fpIAGUQA4
ThingsBoard Dashboard JSON 是用來實作「ESP32 四顆 LED 控制」的儀表板,
透過 setLED1~setLED4 四個 RPC 方法,
從雲端控制 ESP32 上的四個 GPIO(每顆 LED)。
下面是詳細的說明重點:
🔧 每顆 LED 控制元件設定說明(以 LED1 為例)
1. 控制元件類型:
"typeFullFqn": "system.power_button",
"type": "rpc"
表示這是一個「開關按鈕」並連接 ThingsBoard 的 RPC 控制功能。
2. 方法定義:
"method": "setLED1"
按下按鈕時會呼叫 ESP32 上實作的 setLED1 RPC 方法。
方法名稱需與 Arduino 程式碼中的 RPC_Callback 一致。
3. 送出參數:
"valueToData": {
"type": "CONSTANT",
"constantValue": true
}
「開」按鈕會傳送 true,代表開啟 LED。
「關」按鈕則送出 false。
4. 初始化狀態(選擇性):
"initialState": {
"executeRpc": {
"method": "getState"
}
}
儀表板載入時,會執行 getState RPC 方法詢問目前狀態,雖然這方法尚未實作,但可以視需要在 ESP32 中加入。
🧠 裝置連結設定
"targetDevice": {
"type": "device",
"deviceId": "f78040d0-56f1-11f0-9664-ff13eccb47ff"
}
每個按鈕都綁定同一台裝置(ESP32),需確認這個 deviceId 是你的 ESP32 裝置 ID(可以在 ThingsBoard 裡點裝置查詢)。
🔁 RPC 回應建議
在 ESP32 Arduino 程式中,你需要定義:
RPC_Callback callbacks[] = {
{"setLED1", callback_LED1},
{"setLED2", callback_LED2},
{"setLED3", callback_LED3},
{"setLED4", callback_LED4}
};
每個 callback 例如:
void callback_LED1(const JsonVariantConst ¶ms, JsonDocument &response) {
digitalWrite(LED1_PIN, params.as<bool>());
response["result"] = true;
}
✅ 匯入方法教學
進入 ThingsBoard → 登入 → 左側點選 Dashboards。
點右上角「+」 → Import Dashboard。
貼上你給的 JSON 或上傳 .json 檔案 → 儲存。
確認你的 ESP32 裝置已上線並註冊對應的 Access Token。
WokWI程式
#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h> // 新增 ArduinoJson 函式庫
// --- Wi-Fi 配置 ---
//const char* ssid = "您的Wi-Fi名稱"; // 替換成您的 Wi-Fi 名稱
//const char* password = "您的Wi-Fi密碼"; // 替換成您的 Wi-Fi 密碼
const char* ssid = "Wokwi-GUEST";
const char* password = "";
// ==== ThingBoard 設定 ====
const char* mqtt_server = "demo.thingsboard.io"; // 或你自己的伺服器 IP
const int mqtt_port = 1883;
const char* token = "sd63q6qm7r1108u49iji"; // 來自設備的 Access Token
WiFiClient espClient;
PubSubClient client(espClient);
// ==== LED 腳位設定 ====
const int ledPins[4] = {18, 5, 17, 16};
// MQTT RPC 指令處理
void callback(char* topic, byte* payload, unsigned int length) {
StaticJsonDocument<256> doc;
DeserializationError error = deserializeJson(doc, payload, length);
if (error) {
Serial.print("JSON 解析錯誤: ");
Serial.println(error.c_str());
return;
}
String method = doc["method"];
bool value = doc["params"];
int request_id = -1;
// 解析 request_id(從 topic 路徑取出)
String topicStr = String(topic); // 例如 "v1/devices/me/rpc/request/42"
int lastSlash = topicStr.lastIndexOf('/');
if (lastSlash != -1) {
request_id = topicStr.substring(lastSlash + 1).toInt();
}
Serial.print("Received RPC: ");
Serial.println(method + " = " + (value ? "true" : "false"));
int ledIndex = -1;
if (method == "setLED1") ledIndex = 0;
if (method == "setLED2") ledIndex = 1;
if (method == "setLED3") ledIndex = 2;
if (method == "setLED4") ledIndex = 3;
if (ledIndex != -1) {
digitalWrite(ledPins[ledIndex], value ? HIGH : LOW);
// 回覆狀態(如果 request_id 合法)
if (request_id >= 0) {
String responseTopic = "v1/devices/me/rpc/response/" + String(request_id);
StaticJsonDocument<64> resp;
resp["status"] = "ok";
resp["led"] = value;
char response[64];
serializeJson(resp, response);
client.publish(responseTopic.c_str(), response);
Serial.print("Sent RPC response: ");
Serial.println(response);
}
}
}
void publishLEDStatus(int ledIndex, bool state) {
StaticJsonDocument<64> doc;
doc["led" + String(ledIndex + 1)] = state;
char payload[64];
serializeJson(doc, payload);
client.publish("v1/devices/me/telemetry", payload);
}
// 重新連線
void reconnect() {
while (!client.connected()) {
Serial.print("Attempting MQTT connection...");
if (client.connect("ESP32Client", token, NULL)) {
Serial.println("connected");
client.subscribe("v1/devices/me/rpc/request/+"); // RPC 控制
} else {
Serial.print("failed, rc=");
Serial.print(client.state());
Serial.println(" try again in 5 seconds");
delay(5000);
}
}
}
void setup() {
Serial.begin(115200);
// 初始化 LED 腳位
for (int i = 0; i < 4; i++) {
pinMode(ledPins[i], OUTPUT);
digitalWrite(ledPins[i], LOW);
}
// Wi-Fi 連線
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
// MQTT 設定
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
}
沒有留言:
張貼留言