- ESP32物聯網教程
- 首頁
- 物聯網簡述
- ESP32簡介
- 在Arduino IDE中安裝ESP32開發板
- 設定RTOS進行雙核和多執行緒操作
- ESP32與MPU6050介面連線
- ESP32與模擬感測器的介面連線
- ESP32首選項
- ESP32 SPIFFS儲存(晶片自帶的迷你SD卡)
- ESP32與OLED顯示屏介面連線
- ESP32上的WiFi
- 使用HTTP透過WiFi傳輸資料
- 使用HTTPS透過WiFi傳輸資料
- 使用MQTT透過WiFi傳輸資料
- 透過藍牙傳輸資料
- 使用NTP客戶端獲取當前時間
- 執行ESP32韌體的(OTA)更新
- ESP32的應用
- 開發者後續步驟
- ESP32物聯網實用資源
- 快速指南
- 實用資源
- 討論
使用MQTT透過WiFi傳輸資料
MQTT(訊息佇列遙測傳輸)在物聯網裝置中獲得了廣泛的關注。它是一個通常在TCP/IP上執行的協議。與我們之前看到的HTTP的伺服器-客戶端模型不同,MQTT使用代理-客戶端模型。維基百科將MQTT代理和客戶端定義為:
MQTT代理是接收來自所有客戶端的所有訊息,然後將訊息路由到相應的目標客戶端的伺服器。MQTT客戶端是任何執行MQTT庫並透過網路連線到MQTT代理的裝置(從微控制器到功能齊全的伺服器)。
將代理想象成類似Medium的服務。主題就是Medium上的出版物,客戶端就是Medium的使用者。使用者(客戶端)可以向出版物釋出內容,訂閱該出版物(主題)的另一個使用者(客戶端)將被告知有新的帖子可供閱讀。到目前為止,您應該已經理解了HTTP和MQTT之間的一個主要區別。在HTTP中,您的訊息直接傳送到目標伺服器,您甚至會以狀態程式碼的形式獲得確認。在MQTT中,您只是將訊息傳送到代理,希望您的目標伺服器能夠從中獲取資訊。如果您資源受限,MQTT的幾個特性將成為一大福音。它們列在下面:
使用MQTT,報頭開銷非常短,吞吐量很高。這有助於節省時間和電池電量。
MQTT將資訊傳送為位元組陣列,而不是文字格式。這使訊息更輕量級。
因為MQTT不依賴於伺服器的響應,客戶端是獨立的,並且可以在傳輸訊息後進入睡眠狀態(節省電池電量)。
這些只是一些導致MQTT流行的原因。您可以在這裡找到MQTT和HTTP之間更詳細的比較這裡。
程式碼演練
通常,測試MQTT需要您在代理商註冊免費/付費帳戶。AWS IoT和Azure IoT是非常流行的提供MQTT代理服務的平臺,但它們需要冗長的註冊和配置過程。幸運的是,有一個來自HiveMQ的免費代理服務,可用於在無需註冊或配置的情況下測試MQTT。它非常適合那些MQTT新手,只想動手實踐的人,並且還可以讓您更專注於ESP32的韌體。因此,我們將在此章節中使用該代理。當然,因為它是一項免費服務,所以會有一些限制。您不能共享敏感資訊,因為所有訊息都是公開的,任何人都可以訂閱您的主題。當然,對於測試目的,這些限制無關緊要。
程式碼可在GitHub上找到
我們將使用PubSubClient庫。您可以從工具->管理庫中安裝它。
安裝庫後,我們包含WiFi和PubSubClient庫。
#include <WiFi.h> #include <PubSubClient.h>
接下來,我們將定義一些常量。請記住替換WiFi憑據。mqttServer和mqttPort是由http://www.mqtt−dashboard.com/強制規定的。mqtt_client_name、mqtt_pub_topic和mqtt_sub_topic可以是您選擇的任何字串。只需確保您更改了它們的值。如果多個使用者從本教程複製相同的程式碼,您將在測試時收到許多來自未知客戶端的訊息。
我們還定義了WiFiClient和mqttClient物件。MQTTClient物件需要網路客戶端作為引數。如果您使用乙太網,則會提供乙太網客戶端作為引數。由於我們使用的是WiFi,因此我們提供了WiFi客戶端作為引數。
const char* ssid = "YOUR_SSID"; const char* password = "YOUR_PASSWORD"; //The broker and port are provided by http://www.mqtt−dashboard.com/ char *mqttServer = "broker.hivemq.com"; int mqttPort = 1883; //Replace these 3 with the strings of your choice const char* mqtt_client_name = "ESPYS2111"; const char* mqtt_pub_topic = "/ys/testpub"; //The topic to which our client will publish const char* mqtt_sub_topic = "/ys/testsub"; //The topic to which our client will subscribe WiFiClient client; PubSubClient mqttClient(client);
接下來,我們定義回撥函式。回撥函式是一箇中斷函式。每當從訂閱的主題接收到新訊息時,都會觸發此函式。它有三個引數:接收訊息的主題、作為位元組陣列的訊息以及訊息的長度。您可以對該訊息執行任何操作(將其儲存在SPIFFS中,傳送到另一個主題等)。在這裡,我們只是列印主題和訊息。
void callback(char* topic, byte* payload, unsigned int length) {
Serial.print("Message received from: "); Serial.println(topic);
for (int i = 0; i < length; i++) {
Serial.print((char)payload[i]);
}
Serial.println();
Serial.println();
}
在setup中,我們像其他每個草圖一樣連線到WiFi。最後兩行與MQTT有關。我們設定MQTT的伺服器和埠,以及回撥函式。
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
WiFi.mode(WIFI_STA); //The WiFi is in station mode
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println(""); Serial.print("WiFi connected to: "); Serial.println(ssid); Serial.println("IP address: "); Serial.println(WiFi.localIP());
delay(2000);
mqttClient.setServer(mqttServer, mqttPort);
mqttClient.setCallback(callback);
}
在迴圈中,我們執行以下操作
如果客戶端未連線到代理,我們使用客戶端名稱連線它。
連線後,我們還將客戶端訂閱到mqtt_sub_topic。
然後,我們將訊息釋出到mqtt_pub_topic
然後我們執行**mqttClient.loop()**。此loop()函式應定期呼叫。它維護客戶端與代理的連線,並幫助客戶端處理傳入的訊息。如果您沒有這行**mqttClient.loop()**程式碼,您將能夠釋出到mqtt_pub_topic,但不會收到來自mqtt_sub_topic的訊息,因為只有呼叫此行時才會處理傳入的訊息。
最後,我們等待5秒鐘,然後再次啟動此迴圈。
void loop() {
// put your main code here, to run repeatedly:
if (!mqttClient.connected()){
while (!mqttClient.connected()){
if(mqttClient.connect(mqtt_client_name)){
Serial.println("MQTT Connected!");
mqttClient.subscribe(mqtt_sub_topic);
}
else{
Serial.print(".");
}
}
}
mqttClient.publish(mqtt_pub_topic, "TestMsg");
Serial.println("Message published");
mqttClient.loop();
delay(5000);
}
測試程式碼
為了測試上述程式碼,您需要訪問www.hivemq.com
在該網頁上之後,請按照以下步驟操作:
單擊“連線”
單擊“新增新的主題訂閱”,然後輸入ESP32將釋出到的主題名稱(在本例中為/ys/testpub)
重新整理ESP32後,您將每5秒開始接收該主題上的訊息。
- 接下來,要測試ESP32上的訊息接收,請輸入ESP32訂閱的主題名稱(在本例中為ys/testsub),然後在訊息框中鍵入訊息並單擊發布。您應該在序列埠監視器上看到該訊息。
恭喜!!您已在ESP32上使用MQTT測試了釋出和訂閱。