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 推送的資料
這種設計的好處是發布者和訂閱者完全解耦——它們不需要知道彼此的存在,甚至不需要同時在線。
二、系統架構總覽
整個資料流是單向的:感測器讀取環境資料 → 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 元。
如果你要將這個系統部署到工業環境,建議加上 TLS 加密、使用 QoS 1 確保資料不遺失,並考慮用 EMQX 取代 Mosquitto 以獲得更好的效能。
文章評論