0x6A Logbook

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

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

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

MQTT 實戰教學來了!MQTT(Message Queuing Telemetry Transport)是物聯網(IoT)領域最廣泛使用的通訊協定,從智慧家居到工業 4.0 感測器網路,幾乎都會看到它的身影。它的設計核心是輕量級、低頻寬、發布/訂閱(Publish/Subscribe)模式,非常適合 ESP32 MQTT 這種資源有限的微控制器應用場景。

這篇文章會帶你實際搭建一整套 MQTT 資料流:從 DHT22 感測器 → ESP32 → MQTT Broker → Node-RED 儀表板,全部用開源工具完成。

目錄

  • 一、MQTT 核心概念
  • 二、系統架構總覽
  • 三、搭建 MQTT Broker(Mosquitto)
  • 四、接線:ESP32 + DHT22
  • 五、ESP32 程式碼(Arduino IDE)
  • 六、Node-RED 儀表板
  • 七、MQTT 安全性設定
  • 八、常見問題

一、MQTT 核心概念

MQTT 和傳統的 HTTP 不同,它不是 Client/Server 請求回應,而是發布/訂閱模型:

  • Publisher(發布者):傳送資料到某個 Topic,例如 ESP32 發布到 sensor/temperature
  • Broker(代理):負責接收發布者的訊息,並轉送給所有訂閱該 Topic 的客戶端
  • Subscriber(訂閱者):訂閱感興趣的 Topic,收到 Broker 推送的資料

這種設計的好處是發布者和訂閱者完全解耦——它們不需要知道彼此的存在,甚至不需要同時在線。

二、系統架構總覽

MQTT 架構圖
圖 1:MQTT 系統架構 — DHT22 → ESP32 → Mosquitto → Node-RED

整個資料流是單向的:感測器讀取環境資料 → ESP32 打包為 JSON → 透過 WiFi 發布到 MQTT Broker → Node-RED 訂閱並顯示在儀表板上。

三、搭建 MQTT Broker(Mosquitto)

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),使用 Port 8883。

四、接線:ESP32 + DHT22

DHT22 是常用數位溫濕度感測器,精度 ±0.5°C,使用單匯流排(OneWire)通訊:

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

⚠️ 注意:DATA 腳和 VCC 之間需要接一顆 4.7kΩ~10kΩ 上拉電阻,否則 DHT22 無法正常通訊。如果沒有電阻,有些模組(藍色封裝的 DHT22 模組)已經內建了上拉電阻,可以直接用。

五、ESP32 程式碼

使用 Arduino IDE,需要安裝以下程式庫:

  • 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);
    }
}

六、Node-RED 儀表板

Node-RED 是一個視覺化物聯網編程工具,可以非常直觀地接收 MQTT 資料並顯示:

安裝步驟

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

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

# 啟動
node-red

流程配置

在 Node-RED 編輯器(http://localhost:1880)中:

  • 加入 MQTT Input 節點,設定 Server 為 192.168.1.100:1883,Topic 為 sensor/environment
  • 加入 JSON Parse 節點,解析收到的 JSON
  • 加入兩個 Dashboard Gauge 節點,分別顯示溫度和濕度
  • 將三個節點連接起來→ Deploy

打開儀表板(http://localhost:1880/ui),你應該能看到溫濕度即時更新的指針圖表。

七、MQTT 安全性設定

如果 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");

八、常見問題

Q1:ESP32 連不上 Broker

先確認 ESP32 和 Broker 在同一個網段。用 ping 192.168.1.100 測試。如果 ping 不通,檢查防火牆:sudo ufw allow 1883。

Q2:DHT22 一直回傳 NaN

99% 是上拉電阻的問題。DATA 腳和 VCC 之間必須有 4.7k~10kΩ 電阻。另外,DHT22 的上電穩定時間約 2 秒,剛開機的前兩次讀取失敗是正常的。

Q3:WiFi 連線不穩,MQTT 頻繁斷線

ESP32 的 WiFi 在 2.4GHz 頻段容易受干擾。建議:

  • 讓 ESP32 靠近 AP
  • 在 loop() 中加入斷線重連邏輯(上面程式碼已經包含)
  • 考慮使用 ESP32 的外部天線版本

Q4:資料傳送間隔怎麼控制?

程式碼中使用 millis() 而非 delay() 來控制間隔,這樣 ESP32 可以在等待期間處理 WiFi 和 MQTT 的維護工作。調整 if (millis() - lastMsg > 10000) 中的 10000(毫秒)即可改變間隔。

總結

MQTT 是 IoT 專案中最實用的通訊協定之一。這篇文章涵蓋了從感測器到儀表板的完整鏈路,所有軟體都是開源免費的,硬體成本不到台幣 500 元。

📖 延伸閱讀:SPI 通訊教學 · I2C 通訊教學

如果你要將這個系統部署到工業環境,建議加上 TLS 加密、使用 QoS 1 確保資料不遺失,並考慮用 EMQX 取代 Mosquitto 以獲得更好的效能。

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

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