經由MQTT協定的2個WOKWI ESP32 雙向通訊 (ESP32 to ESP32 MQTT Communication )
使用兩個 ESP32 建立一個遠端控制系統。
MQTT Broker:mqtt-dashboard.comTopic (主題):
alex9ufo/switchPB訊息內容: on, off, flash, timer
on/off/flash/timer 到 alex9ufo/switchPB。接收: 訂閱
執行: 訂閱 alex9ufo/DHT22,解析 JSON 格式並顯示於 LCD。alex9ufo/switchPB 控制 LED 動作。發送: 每 2 秒讀取 DHT22 數據並發行 JSON 到
alex9ufo/DHT22。引腳連接提醒:
Button: GPIO 34 (外部下拉電阻)。
LCD: SDA=21, SCL=22。
LED: GPIO 2。
DHT22: GPIO 15。
發送端:按鈕 + LCD (含序列埠監控)
#include <WiFi.h>
#include <PubSubClient.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ArduinoJson.h>
const int buttonPin = 34;
LiquidCrystal_I2C lcd(0x27, 16, 2);
const char* mqtt_server = "mqtt-dashboard.com";
WiFiClient espClient;
PubSubClient client(espClient);
volatile int stateCounter = 0;
volatile bool sendFlag = false;
float sharedTemp = 0, sharedHum = 0;
volatile bool dataUpdated = false;
TaskHandle_t Task0;
void Task0code(void * pvParameters) {
for (;;) {
if (WiFi.status() != WL_CONNECTED) {
WiFi.begin("Wokwi-GUEST", "");
while (WiFi.status() != WL_CONNECTED) delay(500);
Serial.println("[Core 0] WiFi Reconnected");
}
if (!client.connected()) {
if (client.connect("ESP32_Button_Core0")) {
client.subscribe("alex9ufo/DHT22");
Serial.println("[Core 0] MQTT Connected & Subscribed to DHT22");
}
}
if (sendFlag) {
const char* cmds[] = {"on", "off", "flash", "timer"};
const char* msg = cmds[stateCounter - 1];
client.publish("alex9ufo/switchPB", msg);
// 新增:顯示發行的訊息
Serial.printf("[Core 0] ---> Published to switchPB: %s\n", msg);
sendFlag = false;
}
client.loop();
delay(10);
}
}
void callback(char* topic, byte* payload, unsigned int length) {
StaticJsonDocument<200> doc;
deserializeJson(doc, payload, length);
sharedTemp = doc["temp"];
sharedHum = doc["hum"];
dataUpdated = true;
// 新增:顯示收到的訂閱訊息
Serial.printf("[Core 0] <--- Received DHT22: Temp=%.1f, Hum=%.1f\n", sharedTemp, sharedHum);
}
void setup() {
Serial.begin(115200);
pinMode(buttonPin, INPUT);
lcd.init();
lcd.backlight();
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
xTaskCreatePinnedToCore(Task0code, "Task0", 10000, NULL, 1, &Task0, 0);
Serial.println("System Initialized (Sender)");
}
void loop() {
static int lastButtonState = LOW;
int reading = digitalRead(buttonPin);
if (reading == HIGH && lastButtonState == LOW) {
delay(50);
stateCounter = (stateCounter % 4) + 1;
sendFlag = true;
Serial.printf("[Core 1] Button Pressed. State: %d\n", stateCounter);
}
lastButtonState = reading;
if (dataUpdated) {
lcd.setCursor(0, 0);
lcd.printf("Temp: %.1f C ", sharedTemp);
lcd.setCursor(0, 1);
lcd.printf("Hum : %.1f %% ", sharedHum);
dataUpdated = false;
}
delay(10);
}
接收端:LED + DHT22 (含序列埠監控)
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <ArduinoJson.h>
#define DHTPIN 15
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const int ledPin = 2;
const char* mqtt_server = "mqtt-dashboard.com";
WiFiClient espClient;
PubSubClient client(espClient);
volatile int currentModeCode = 0;
unsigned long myTimerStart = 0;
float t_val = 0, h_val = 0;
TaskHandle_t Task0_Comm;
void Task0_CommCode(void * pvParameters) {
for (;;) {
if (!client.connected()) {
if (client.connect("ESP32_LED_Core0")) {
client.subscribe("alex9ufo/switchPB");
Serial.println("[Core 0] MQTT Connected & Subscribed to switchPB");
}
}
static unsigned long lastUpdate = 0;
if (millis() - lastUpdate > 5000) { // 每5秒發行一次
StaticJsonDocument<200> doc;
doc["temp"] = t_val;
doc["hum"] = h_val;
char buffer[128];
serializeJson(doc, buffer);
client.publish("alex9ufo/DHT22", buffer);
// 新增:顯示發行的訊息
Serial.printf("[Core 0] ---> Published DHT Data: %s\n", buffer);
lastUpdate = millis();
}
client.loop();
delay(10);
}
}
void callback(char* topic, byte* payload, unsigned int length) {
String msg = "";
for (int i = 0; i < length; i++) msg += (char)payload[i];
// 新增:顯示收到的訂閱訊息
Serial.printf("[Core 0] <--- Received switchPB: %s\n", msg.c_str());
if (msg == "off") currentModeCode = 0;
else if (msg == "on") currentModeCode = 1;
else if (msg == "flash") currentModeCode = 2;
else if (msg == "timer") {
currentModeCode = 3;
myTimerStart = millis();
}
}
void setup() {
Serial.begin(115200);
pinMode(ledPin, OUTPUT);
dht.begin();
WiFi.begin("Wokwi-GUEST", "");
while (WiFi.status() != WL_CONNECTED) delay(500);
client.setServer(mqtt_server, 1883);
client.setCallback(callback);
xTaskCreatePinnedToCore(Task0_CommCode, "CommTask", 10000, NULL, 1, &Task0_Comm, 0);
Serial.println("System Initialized (Receiver)");
}
void loop() {
t_val = dht.readTemperature();
h_val = dht.readHumidity();
// 根據 currentModeCode 執行 LED 動作
if (currentModeCode == 1) digitalWrite(ledPin, HIGH);
else if (currentModeCode == 0) digitalWrite(ledPin, LOW);
else if (currentModeCode == 2) digitalWrite(ledPin, (millis() / 500) % 2);
else if (currentModeCode == 3) {
if (millis() - myTimerStart < 5000) digitalWrite(ledPin, HIGH);
else {
digitalWrite(ledPin, LOW);
currentModeCode = 0;
Serial.println("[Core 1] Timer Finished. LED Off.");
}
}
delay(100);
}





沒有留言:
張貼留言