0x6A Logbook

0x6A Logbook
Shi6a的筆記本
  1. 首頁
  2. 自動化技巧
  3. 正文

ESP32 MQTT 實戰教學:從 DHT22 感測器到 Node-RED 儀表板完整搭建

2026 年 5 月 21 日 917點熱度 0人點贊 0條評論

ESP32 MQTT 實戰教學封面

前言:為什麼 IoT 專案最後都會選 MQTT

如果你做過「把感測器資料丟上網頁」的專案,大概都經歷過同一段掙扎:要嘛讓 ESP32 開一個網頁(但你不在同一個網段就看不到),要嘛用 HTTP 定時打 API(但每次都要重新連線,耗電又慢)。

MQTT 解決的正是這件事:它讓裝置「講話」而不是「被問話」。資料一有變化就發布出去,有興趣的人自然會收到。

MQTT 跟 HTTP 差在哪

MQTT 與 HTTP 的差異

關鍵差別在「解耦」:發布者和訂閱者完全不需要知道彼此的存在,甚至不需要同時在線。這對電池供電、偶爾上線的裝置來說是決定性的優勢。

三個角色,各管一件事

MQTT 的三個角色

MQTT 發布訂閱架構

在這篇的專案裡,三個角色分別是:ESP32(Publisher)、Mosquitto(Broker)、Node-RED(Subscriber)。三方唯一的約定就是 Topic 名稱 —— 這裡用的是 sensor/environment。

整體資料流

從感測器到儀表板的資料流

整條鏈路是單向的:感測器讀取 → ESP32 打包成 JSON → 發布到 Broker → Node-RED 訂閱並顯示。而且全部軟體都是開源免費的,硬體成本不到台幣 500 元。

先把 Broker 架起來

Mosquitto 是最輕量也最常見的開源 MQTT Broker,在 Linux 上一行指令就裝好:

# Ubuntu / Debian
sudo apt install mosquitto mosquitto-clients

# 啟動服務
sudo systemctl enable mosquitto
sudo systemctl start mosquitto

# 測試是否正常
mosquitto_sub -h localhost -t "test" &
mosquitto_pub -h localhost -t "test" -m "Hello MQTT"

預設 Port 是 1883(未加密);如果要用 TLS,則是 8883。本機測試用 1883 就好,要對外開放就一定要看完後面的安全性章節。

接線:ESP32 與 DHT22

DHT22 接腳 ESP32 GPIO
VCC(Pin 1) 3.3V
DATA(Pin 2) GPIO4
NC(Pin 3) 不使用
GND(Pin 4) GND

DHT22 接線與注意事項

那一顆上拉電阻(4.7 kΩ~10 kΩ)是整個專案最容易被忽略、卻最常導致失敗的零件。如果你買的是藍色封裝的 DHT22 模組,通常已經內建,可以直接接。

ESP32 程式碼

需要三個程式庫:DHT sensor library(Adafruit)、PubSubClient(MQTT)、ArduinoJson(JSON 封裝)。完整程式如下:

#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <ArduinoJson.h>

// WiFi 設定
const char* ssid = "YOUR_WIFI_SSID";
const char* password = "YOUR_WIFI_PASS";

// MQTT 設定
const char* mqtt_server = "192.168.1.100";  // Broker IP
const int mqtt_port = 1883;
const char* mqtt_topic = "sensor/environment";

// DHT 設定
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

WiFiClient espClient;
PubSubClient client(espClient);

void setup_wifi() {
    delay(10);
    Serial.println();
    Serial.print("連線到 WiFi: ");
    Serial.println(ssid);

    WiFi.begin(ssid, password);
    while (WiFi.status() != WL_CONNECTED) {
        delay(500);
        Serial.print(".");
    }
    Serial.println();
    Serial.print("已連線,IP: ");
    Serial.println(WiFi.localIP());
}

void reconnect() {
    while (!client.connected()) {
        Serial.print("MQTT 連線中...");
        if (client.connect("ESP32_DHT22")) {
            Serial.println("已連線");
        } else {
            Serial.print("失敗,rc=");
            Serial.print(client.state());
            Serial.println(" 5 秒後重試");
            delay(5000);
        }
    }
}

void setup() {
    Serial.begin(115200);
    dht.begin();
    setup_wifi();
    client.setServer(mqtt_server, mqtt_port);
}

void loop() {
    if (!client.connected()) {
        reconnect();
    }
    client.loop();

    // 每 10 秒讀取一次
    static unsigned long lastMsg = 0;
    if (millis() - lastMsg > 10000) {
        lastMsg = millis();

        float h = dht.readHumidity();
        float t = dht.readTemperature();

        if (isnan(h) || isnan(t)) {
            Serial.println("DHT22 讀取失敗");
            return;
        }

        // 封裝 JSON
        JsonDocument doc;
        doc["temperature"] = t;
        doc["humidity"] = h;
        doc["device"] = "esp32-lobby";

        char buffer[256];
        size_t n = serializeJson(doc, buffer);
        client.publish(mqtt_topic, buffer, n);

        Serial.printf("已發布: %.1f°C, %.1f%%\r\n", t, h);
    }
}

這段程式有一個值得學的細節:用 millis() 而不是 delay() 來控制上報間隔。這樣在等待的期間,ESP32 仍然能處理 WiFi 與 MQTT 的維護工作,斷線重連邏輯才有機會執行。

Node-RED 儀表板

Node-RED 是視覺化的物聯網編程工具,用來接 MQTT 資料並畫成圖表非常直觀。安裝:

# 安裝 Node-RED
sudo npm install -g node-red

# 安裝儀表板套件
npm install node-red-dashboard

# 啟動
node-red

裝好之後,整個儀表板其實只有三個節點:

Node-RED 儀表板的三個節點

拉線、Deploy,打開 /ui 就能看到溫濕度即時更新的指針圖表。

安全性設定:對外開放前一定要做

如果你的 Broker 會暴露在網際網路上(例如架在雲端 VPS),沒有密碼保護等於把感測器資料公開展示。先建立密碼檔:

# 建立密碼檔案
sudo mosquitto_passwd -c /etc/mosquitto/passwd esp32_client
# 輸入密碼:your_password

# 編輯設定檔 /etc/mosquitto/mosquitto.conf
echo "allow_anonymous false" >> /etc/mosquitto/mosquitto.conf
echo "password_file /etc/mosquitto/passwd" >> /etc/mosquitto/mosquitto.conf

# 重啟服務
sudo systemctl restart mosquitto

ESP32 端也要跟著加上帳號密碼:

// 在 connect 時加入帳密
client.connect("ESP32_DHT22", "esp32_client", "your_password");

如果要把這套系統推進到工業環境,原文的建議是:加上 TLS 加密、使用 QoS 1 確保資料不遺失,並考慮用 EMQX 取代 Mosquitto。

四個一定會遇到的問題

MQTT 專案的四個常見問題

其中兩個最值得先記住:DHT22 回傳 NaN 有 99% 是上拉電阻;而用 delay() 控制上報間隔會讓 WiFi 與 MQTT 的維護工作停擺,這是新手最常犯的錯,也是斷線問題的常見元凶。

總結

這個專案把「感測器 → 雲端 → 儀表板」的完整鏈路走了一遍,四個重點:

  • 發布/訂閱取代請求/回應:裝置主動講話,不需要被問
  • 三方只靠 Topic 約定:Publisher、Broker、Subscriber 完全解耦
  • Broker 是唯一要維運的元件:1883 未加密、8883 走 TLS
  • 硬體的坑都在電阻上:DHT22 的上拉電阻決定成敗

下一步很自然:把資料存進資料庫、加上告警規則,或是換成支援 QoS 與叢集的 EMQX。這些都只是同一套架構往外延伸而已。

標籤: DHT22 ESP32 MQTT Node-RED 教學
最後更新:2026 年 9 月 30 日

shi6a

這個人很懶,什麼都沒留下

點贊
< 上一篇
下一篇 >

文章評論

razz evil exclaim smile redface biggrin eek confused idea lol mad twisted rolleyes wink cool arrow neutral cry mrgreen drooling persevering
取消回覆

COPYRIGHT © 2026 0x6A Logbook. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang