使用 MQTT 協議進行消息發布和訂閱
在這節課中,我們將學習如何使用 MakePico 開發板通過 MQTT 協議進行消息的發布和訂閱。這是一種常用於物聯網(IoT)應用中的通信方法,允許設備之間通過消息隊列進行數據傳輸。我們將介紹如何設置 MQTT 客戶端、訂閱和發布消息,以及確保持續的 MQTT 連接。
步驟 1:引入 PubSubClient 函數庫並設置 MQTT 參數
首先,我們需要引入 PubSubClient
函數庫,這個庫為我們提供了處理 MQTT 通信所需的所有功能。接著,設置 MQTT 服務器的地址、用戶端 ID,以及發布和訂閱的主題名稱。
#include <WiFi.h> #include <PubSubClient.h> // 創建 WiFi 和 MQTT 客戶端實例 WiFiClient espClient; PubSubClient mclient(espClient); // 設置 MQTT 伺服器地址和用戶端 ID const char* mqttServer = "broker.emqx.io"; // MQTT伺服器地址 String clientID = "HK20231125"; // 用戶端 ID // 設置 MQTT 主題名稱 String pubtopic = "YuanDevice/HK/respone/1"; // 發布的主題 String subtopic = "YuanDevice/HK/request/1"; // 訂閱的主題
解釋:
mqttServer
是 MQTT 伺服器的地址,這裡使用的是公共 MQTT 伺服器broker.emqx.io
。clientID
是 MQTT 客戶端的唯一標識符,用於識別不同的客戶端。pubtopic
和subtopic
分別是用於消息發布和訂閱的主題名稱,這些名稱將用於消息的傳輸和接收。
步驟 2:創建 MQTT 回調函數並管理 MQTT 連接
我們需要創建一個回調函數 callback
來處理接收到的 MQTT 消息。接著,設置一個名為 connect_mqtt
的自定義函數來管理 MQTT 的連接,確保客戶端能夠成功連接到 MQTT 伺服器並訂閱指定的主題。
// MQTT 回調函數,處理接收到的消息 void callback(char* topic, byte* message, unsigned int length) { String messageTemp; for (int i = 0; i < length; i++) { messageTemp += (char)message[i]; } Serial.print("Received message: "); Serial.println(messageTemp); // 打印接收到的消息 } // 連接到 MQTT 伺服器的函數 void connect_mqtt() { while (!mclient.connected()) { mclient.setServer(mqttServer, 1883); // 設置 MQTT 伺服器地址和端口 mclient.setCallback(callback); // 設置回調函數處理訂閱的消息 if (mclient.connect(clientID.c_str())) { // 嘗試連接 Serial.println("Connected to MQTT Server"); mclient.subscribe(subtopic.c_str()); // 訂閱主題 Serial.print("Subscribed to topic: "); Serial.println(subtopic); } else { Serial.print("Failed to connect, retrying in 1 second..."); delay(1000); // 連接失敗後等待 1 秒再重試 } } }
解釋:
callback
函數負責處理接收到的 MQTT 消息,這裡將消息內容轉換為字符串並輸出到串行監視器。connect_mqtt
函數用於連接到 MQTT 伺服器,並在成功連接後訂閱指定的主題。如果連接失敗,函數將等待 1 秒後重試,直到成功連接。
步驟 3:在主迴圈中檢查並維持 Wi-Fi 和 MQTT 連接
最後,我們需要在 loop
主迴圈中檢查 Wi-Fi 和 MQTT 的連接狀態,確保設備始終處於聯機狀態,並能夠正常進行消息的發布和訂閱。
void loop() { // 檢查 Wi-Fi 連接狀態 while (WiFi.status() != WL_CONNECTED && espflag == 0x01) { espflag = 0x00; } // 如果 Wi-Fi 未連接,重新連接 if (espflag == 0x00) { connetrouter(); } // 如果 Wi-Fi 已連接,檢查 MQTT 連接 else if (espflag == 0x01) { if (!mclient.connected()) { connect_mqtt(); // 如果 MQTT 斷開,重新連接 } mclient.loop(); // 維持 MQTT 連接,處理傳入的消息 } }
解釋:
loop
函數不斷檢查 Wi-Fi 和 MQTT 的連接狀態,並根據狀態做出相應處理,確保設備始終在線並能夠接收和發布 MQTT 消息。mclient.loop()
方法用於處理所有傳入的 MQTT 消息,並確保持續的 MQTT 連接。
步驟 4:上傳代碼並測試 MQTT 通信
- 上傳代碼:
- 將代碼上傳到 MakePico 開發板,並打開串行監視器以查看調試信息。
- 測試 MQTT 通信:
- 使用 MQTT 客戶端工具(如 MQTTX 或 MQTT Explorer)向
YuanDevice/HK/request/1
主題發布消息。 - 觀察串行監視器,檢查設備是否成功接收並處理了消息。
- 使用 MQTT 客戶端工具(如 MQTTX 或 MQTT Explorer)向