ESP32 Arduino開發 MQTT 目錄ESP32 Arduino開發 MQTT1. 安裝程式庫2. 編寫相關程式2.1. 引入頭文件2.2. 定義MQTT相關參數2.3. 創建對象2.4. 連接網路2.5. 連接MQTT伺服器2.6. MQTT回調函數3. 完整的代碼常式4. MQTT連接測 ...
ESP32 Arduino開發 MQTT
目錄1. 安裝程式庫
- 打開庫管理工具
工具 -> 管理庫...
- 查找所需要的程式庫
安裝PubSubClient
2. 編寫相關程式
2.1. 引入頭文件
在保證網路連接的前提之下,才可以連接MQTT。
所以需要引入<WiFi.h>
的庫。
#include <WiFi.h>
#include <PubSubClient.h>
2.2. 定義MQTT相關參數
MQTT相關參數可以分為3個部分:一是方便開發所設計的巨集定義參數,二是網路連接所需要的信息,三是MQTT連接所需要的信息。
MQTT連接所需要的信息包括:
- MQTT伺服器(選用EMQX的開源測試伺服器)
- MQTT主題
- 用戶名
- 密碼
- 埠號
- 伺服器ID
#define MAX_RETRIES 20 // 網路最大連接次數
#define MQTT_CALLBACK 1 // 是否開啟MQTT回調函數
const char* ssid="HTB"; // 網路信息
const char* pass="htb66666666";
// 設置MQTT borker信息
const char *mqtt_broker = "broker-cn.emqx.io";
const char *topic = "mqtt_hbb_example";
const char *mqtt_username = "emqx";
const char *mqtt_password = "public";
const int mqtt_port = 1883;
const char *client_id = "mqtt-client-hbb-example";
2.3. 創建對象
創建MQTT伺服器對象
WiFiClient espClient;
PubSubClient client(espClient);
2.4. 連接網路
網路連接函數是在之前的教程《ESP32 Arduino開發 網路連接》的基礎上進行了小部分的修改,將其封裝成函數,返回值表示網路是否連接成功。
// 網路連接函數
bool connectWifi(){
Serial.println("調用WiFi連接函數");
WiFi.begin(ssid, pass);
for(int i=0; i<MAX_RETRIES; i++){
delay(500);
if(WiFi.status()==WL_CONNECTED){
Serial.println("網路連接成功");
return true;
}
}
if(WiFi.status()!=WL_CONNECTED){
Serial.println("網路連接超時");
return false;
}
}
2.5. 連接MQTT伺服器
- 通過
setServer
函數設置伺服器地址及埠號 #if
、#endif
是預處理命令,跟if語句的作用類似,如果巨集為真,則執行其中的語句,如果巨集為假,則其中的語句不編譯- 先要保證Wi-Fi連接處於正常狀態,再執行MQTT的連接函數。MQTT連接整體的程式設計思路與Wi-Fi連接是一致的。
// MQTT伺服器連接函數
bool connectMqtt(){
Serial.println("調用MQTT連接函數");
client.setServer(mqtt_broker, mqtt_port);
#if MQTT_CALLBACK
Serial.println("調用MQTT回調函數");
client.setCallback(mqttCallback);
#endif
if(WiFi.status()==WL_CONNECTED){
for(int i=0; i<MAX_RETRIES; i++){
delay(1000);
if(client.connect(client_id, mqtt_username, mqtt_password)){
Serial.println("MQTT伺服器連接成功");
return true;
}
}
if(!client.connected()){
Serial.println("MQTT伺服器連接超時");
return false;
}
}else{
Serial.println("網路連接失敗");
return false;
}
}
2.6. MQTT回調函數
未完待續
3. 完整的代碼常式
#include <WiFi.h>
#include <PubSubClient.h>
#define MAX_RETRIES 20 // 網路最大連接次數
#define MQTT_CALLBACK 1 // 是否開啟MQTT回調函數
const char* ssid="HTB"; // 網路信息
const char* pass="htb66666666";
const char *mqtt_broker = "broker-cn.emqx.io"; // 設置MQTT borker信息
const char *topic = "mqtt_hbb_example";
const char *mqtt_username = "emqx";
const char *mqtt_password = "public";
const int mqtt_port = 1883;
const char *client_id = "mqtt-client-hbb-example";
// String client_id = "esp32-client-" + String(WiFi.macAddress()); // 伺服器id設置為wifi的物理地址
WiFiClient espClient;
PubSubClient client(espClient);
// MQTT監聽函數
void mqttCallback(char *topic, byte *payload, unsigned int length) {
Serial.print("Message arrived in topic: ");
Serial.println(topic);
Serial.print("Message:");
String charPayload;
for (int i = 0; i < length; i++) {
charPayload += (char) payload[i];
}
Serial.println(charPayload);
Serial.println("-----------------------");
}
// 網路連接函數
bool connectWifi(){
Serial.println("調用WiFi連接函數");
WiFi.begin(ssid, pass);
for(int i=0; i<MAX_RETRIES; i++){
delay(500);
if(WiFi.status()==WL_CONNECTED){
Serial.println("網路連接成功");
return true;
}
}
if(WiFi.status()!=WL_CONNECTED){
Serial.println("網路連接超時");
return false;
}
}
// MQTT伺服器連接函數
bool connectMqtt(){
Serial.println("調用MQTT連接函數");
client.setServer(mqtt_broker, mqtt_port);
#if MQTT_CALLBACK
Serial.println("調用MQTT回調函數");
client.setCallback(mqttCallback);
#endif
if(WiFi.status()==WL_CONNECTED){
for(int i=0; i<MAX_RETRIES; i++){
delay(1000);
if(client.connect(client_id, mqtt_username, mqtt_password)){
Serial.println("MQTT伺服器連接成功");
return true;
}
}
if(!client.connected()){
Serial.println("MQTT伺服器連接超時");
return false;
}
}else{
Serial.println("網路連接失敗");
return false;
}
}
void setup() {
Serial.begin(115200);
if(connectWifi()){
connectMqtt();
};
}
void loop() {
// put your main code here, to run repeatedly:
}
4. MQTT連接測試
未完待續