ESP32 Arduino開發 MQTT

霍北北發表於2024-04-13

ESP32 Arduino開發 MQTT

目錄
  • ESP32 Arduino開發 MQTT
    • 1. 安裝程式庫
    • 2. 編寫相關程式
      • 2.1. 引入標頭檔案
      • 2.2. 定義MQTT相關引數
      • 2.3. 建立物件
      • 2.4. 連線網路
      • 2.5. 連線MQTT伺服器
      • 2.6. MQTT回撥函式
    • 3. 完整的程式碼例程
    • 4. MQTT連線測試

1. 安裝程式庫

  1. 開啟庫管理工具

工具 -> 管理庫...

  1. 查詢所需要的程式庫
    安裝PubSubClient

2. 編寫相關程式

2.1. 引入標頭檔案

在保證網路連線的前提之下,才可以連線MQTT。
所以需要引入<WiFi.h>的庫。

#include <WiFi.h>
#include <PubSubClient.h>

2.2. 定義MQTT相關引數

MQTT相關引數可以分為3個部分:一是方便開發所設計的宏定義引數,二是網路連線所需要的資訊,三是MQTT連線所需要的資訊。

MQTT連線所需要的資訊包括:

  1. MQTT伺服器(選用EMQX的開源測試伺服器
  2. MQTT主題
  3. 使用者名稱
  4. 密碼
  5. 埠號
  6. 伺服器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伺服器

  1. 透過setServer函式設定伺服器地址及埠號
  2. #if#endif是預處理命令,跟if語句的作用類似,如果宏為真,則執行其中的語句,如果宏為假,則其中的語句不編譯
  3. 先要保證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連線測試

未完待續

相關文章