WiFi
IoT
遠距控制
MQTT
在了解各類 IoT 網路架構以及 ESP32 WiFi 網路伺服器管理資源後,學習 MQTT 如何破除不同網域的限制,進行遠端遙控。
- 方便分佈廣闊、大量的石油管線感測器,透過昻貴的人造衛星通訊,傳遞輕量、可靠的資料,便於降低電力損耗和網路擁塞,達到低頻寬、低硬體的需求。
- (為何不用 UDP?)
- 透過 broker 執行一對多通訊 (MQTT Broker 就是 Server)
- Client 可以向 broker 的主動發佈 (當 publisher) 及訂閱 (當 subscriber) 內容
- topic message 的最大容量為 256MB
- 代表的是發送與接收訊息的品質,可設定 0 ~ 2
- 若 topic 沒人訂閱,則 payload 內容被丟棄
- Topic 命名原則:
a) 是由 utf-8 編碼組成,如同 Http 的 URL 的概念,但以 "/" 進行分階層
b) 不可以使用 "$"、"#"、"+"、或空隔(space)
- 利用特殊符號訂閱 Topic :
a) ”#”: 代表的垂直的概念,指的是該階層以下的全部Topic都訂閱:
ex: myhome/groundfloor/#
b) ”+”: 代表水平的概念,使用該符號的階層所處的階層可以替換成任何字元:
ex: myhome/groundfloor/+/temperature
[注意:myhome/#/temperature 是不符合規定的]
- 當 publisher 對 MQTT 連線斷掉時,Topic 還會自動保留。
- 重新連線後 Topic 還存在。
- 發送訊息後會將訊息保持在 Topic 上,使的新的加入者也可以獲取最新的息。
- 若在沒有設定的情況下,新加入的 subscriber 不會收到上一個已發送過的訊息。
- 當 publisher 斷線的時候,可指定 lwt 的 Topic,與想要傳送的訊息。
接入服務語法指令
動作 | WiFi | WiFiMulti | WiFi Client | MQTT Client |
---|---|---|---|---|
宣告物件 | WiFiMulti wifiMulti | WiFiClient client | PubSubClient MQTTClient(client) | |
模式宣告 | WiFi.mode(WIFI_?) | WiFi.mode(WIFI_?) | ||
增加清單 | wifiMulti.addAP("SSID_1", "password_1") | |||
連線伺服器 | client.connect(ip, port) | MQTTClient.setServer(MQTTServer, MQTTPort) | ||
連線 | WiFi.begin(ssid,password) | wifiMulti.run() | MQTTClient.connect(id, MQTTUser, MQTTPassword) | |
檢查狀態 | WiFi.status()==WL_CONNECTED | wifiMulti.run()==WL_CONNECTED | MQTTClient.connect() | |
關閉(斷線) | WiFi.mode(WIFI_OFF) | WiFi.mode(WIFI_OFF) | client.stop(); | MQTTClient.disconnect() |
啟動 ESP32 藍牙功能
- 依課本 p.208 的硬體需求
- 修改課本 p.210 程式中的 mqttserver 和 topic,並上傳
hint:
- 先安裝 library Nick O'Leary 的 pubsubclient
- 程式先包含 library:
#include <WiFi.h>
#include <PubSubClient.h>- broker (MQTTServer) 為 broker.emqx.io
MQTTPort 為 1883
MQTTUser 為 emqx
MQTTPassword 為 public- 設定 publish 的 topic
設定 subscribe 的 topic- 設定 publish 的間隔時間(15秒以內),並以 MQTTClient.loop() 更新訂閱狀態
- 建立 WiFiClient 物件
WiFiClient WifiClient;
- 基於 WiFiClient 物件,建立 MQTTClient 物件
PubSubClient MQTTClient(WifiClient);
- 連接 broker (MQTTServer):
MQTTClient.setServer(MQTTServer, MQTTPort);
MQTTClient.setCallback(MQTTCallback);[當 subscribe 的 topic 有更新時,執行MQTTCallback 副程式]
- 訂閱 topic 為 MQTTClient.subscribe(主題)
發佈 topic 資料為 MQTTClient.publish(主題, 字元)
觀察:當打開 App terminal 後,連續收到 "Hello World"。
ESP32 透過mqtt將溫濕度數值,向手機傳送
- 需一部 Android 手機,並下戴安裝 "MQTT Dash"
依程式修改 mqttserver 連線 ,並訂閱 topic
hint:
在 App 上輸入:
- MQTTServer connection 為 broker.emqx.io
port 為 1883- subscribe YourTopic/…/temp 或 humi
publish YourTopic/…/led
觀察:當打開 App terminal 後,連續收到溫濕度數值,並可以控制 LED 的啟閉。
跨網域訂閱其他同學的 ESP32 topic
hint:
在 App 上輸入:
- subscribe 其他同學的 YourTopic/…/temp 或 humi
- publish 其他同學的 YourTopic/…/led
觀察:當打開 App terminal 後,收到其他同學 ESP32 的溫濕度數值連續收到溫濕度數值,並可以控制 LED 的啟閉。
- #include <WiFiClientSecure.h>
const char* ca_cert= *****\n;- 利用 server 的 CA certificate 建立加密的 WiFi 連線
// init wifi secure client
WiFiClientSecure espClient;
espClient.setCACert(ca_cert);
1)IOT物聯網應用第十四章 – 尤濬哲(夜市小霸王) 編著
2)What is MQTT?
3)MQTT教學(五):「保留」發布訊息以及QoS品質設定
4)[深入淺出MQTT]: v3.1.1與v5 的差異
5)MQTT on ESP32: A Beginner's Guide