Running MQTT Client on ESP32 for Publishing and Subscribing to Topics

Running MQTT Client on ESP32 for Publishing and Subscribing to Topics

There are many libraries available for ESP32 MQTT, this time Lingshun Lab mainly uses AsyncMQTT_ESP32, and in the future, we will explore more methods for using other MQTT libraries.

Prerequisites

  • Deploy a local MQTT server on Raspberry Pi, for specific installation please check the following link: https://lingshunlab.com/book/raspberry-pi/raspberry-pi-install-mosquitto-mqtt-server-and-test-mqtt

  • ESP32 and Raspberry Pi are on the same WIFI network

Effect Implementation

Lingshun Lab demonstrates in this example the use of two ESP32s, one for publishing MQTT topic messages and the other for subscribing and outputting the MQTT topic content. Of course, one might ask if one ESP32 can act as both publisher and subscriber at the same time? The answer is yes, because as clients, they exchange information through intermediaries.

BOM

Prepare 2 ESP32s, one for publishing and one for subscribing.

Library Installation

You can search and install it in the Arduino IDE library manager: click on the menu bar “Tools” —> “Library Manager”, then enter “AsyncMQTT_ESP32” in the search box, and click install.

The following image shows that I have already installed it locally:

Running MQTT Client on ESP32 for Publishing and Subscribing to Topics

Alternatively, you can download it from GitHub and install it into the Arduino “libraries” folder.

GitHub Address: https://github.com/khoih-prog/AsyncMQTT_ESP32

Program Tips

1. First, load the AsyncMQTT_ESP32 library

#include <AsyncMQTT_ESP32.h>

2. Configure the MQTT server information, which can be in the form of IP or domain name

//#define MQTT_HOST         IPAddress(192, 168, 100, 100)
#define MQTT_HOST         "broker.emqx.io"        // Broker address
#define MQTT_PORT         1883

3. Set the topic, both publishing and subscribing require a topic

const char *Topic  = "lingshunlab/ESP32";               // Topic

4. Create an instance of the MQTT client

// Create an instance of the MQTT client named mqttClient
AsyncMqttClient mqttClient;

5. Understand the available callback functions of mqttClient

When MQTT triggers specific events, you can configure custom functions.

  mqttClient.onConnect(onMqttConnect);  // Set the callback function when MQTT connects
  mqttClient.onDisconnect(onMqttDisconnect); // Set the callback function when MQTT disconnects
  mqttClient.onSubscribe(onMqttSubscribe); // Set the callback function when subscribing to an MQTT topic
  mqttClient.onUnsubscribe(onMqttUnsubscribe); // Set the callback function when unsubscribing from an MQTT topic
  mqttClient.onMessage(onMqttMessage); // Set the callback function when subscribing to an MQTT topic
  mqttClient.onPublish(onMqttPublish); // Set the callback function when publishing to an MQTT topic
  mqttClient.setServer(MQTT_HOST, MQTT_PORT); // Set MQTT server information

6. Connect to the MQTT server

  mqttClient.setServer(MQTT_HOST, MQTT_PORT); // Connect to the MQTT server

7. Publish a topic

By using the following code, you can publish messages to the configured topic.

// Publish topic message
  uint16_t packetIdPub = mqttClient.publish(PubTopic, 2, true, "welcome to Lingshunlab.com");
  Serial.print("Publishing at QoS 2, packetId: ");
  Serial.println(packetIdPub);
  delay(2000);

8. Subscribe to a topic

By using the following code, you can subscribe to the configured topic.

// Subscribe to the MQTT topic, with QoS set to 2
  uint16_t packetIdSub = mqttClient.subscribe(SubTopic, 2);
  Serial.print("Subscribing at QoS 2, packetId: ");
  Serial.println(packetIdSub);

9. Callback function when topic message changes

mqttClient has many callback functions, please study the examples carefully for other callback functions. Here, I would like to specifically mention the onMessage callback function onMqttMessage (you can define this function name yourself), which has many parameters, such as topic, payload, etc., where payload is the content of the message that can be displayed through output.

void onMqttMessage(char* topic, char* payload, const AsyncMqttClientMessageProperties& properties,
                   const size_t& len, const size_t& index, const size_t& total)
{
  (void) payload;
  Serial.println("=====On MQTT Message=====");
  Serial.println("Publish received.");
  Serial.print("  topic: ");
  Serial.println(topic);
  Serial.print("  qos: ");
  Serial.println(properties.qos);
  Serial.print("  dup: ");
  Serial.println(properties.dup);
  Serial.print("  retain: ");
  Serial.println(properties.retain);
  Serial.print("  len: ");
  Serial.println(len);
  Serial.print("  index: ");
  Serial.println(index);
  Serial.print("  total: ");
  Serial.println(total);
  Serial.print("payload: ");
  Serial.println(payload);   // Output message content
}

10. Please check the official examples of AsyncMQTT_ESP32

You can learn how to apply FreeRTOS multi-threading.

Program Code

Complete Code for Publishing a Topic

#include <WiFi.h>

// Configure WIFI 
#define WIFI_SSID         "***your wifi***"
#define WIFI_PASSWORD     "***your wifi password***"

// Load AsyncMQTT_ESP32 library
#include <AsyncMQTT_ESP32.h> 

// Configure MQTT server address and port
#define MQTT_HOST         IPAddress(192,168,100,100)    // Broker IP
// #define MQTT_HOST         "broker.emqx.io"        // Broker address
#define MQTT_PORT         1883

const char *PubTopic  = "lingshunlab/ESP32";               // Topic for publishing messages

AsyncMqttClient mqttClient; // Create MQTT client instance

void onMqttConnect(bool sessionPresent)   // Write corresponding callback function
{
  Serial.println("=====On MQTT Connect=====");
  Serial.print("Connected to MQTT broker: ");
  Serial.print(MQTT_HOST);
  Serial.print(", port: ");
  Serial.println(MQTT_PORT);
  Serial.print("PubTopic: ");
  Serial.println(PubTopic);
}

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason)
{
  (void) reason;

  Serial.println("Disconnected from MQTT.");
}

void onMqttSubscribe(const uint16_t& packetId, const uint8_t& qos)
{
  Serial.println("Subscribe acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
  Serial.print("  qos: ");
  Serial.println(qos);
}

void onMqttUnsubscribe(const uint16_t& packetId)
{
  Serial.println("Unsubscribe acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
}

void onMqttMessage(char* topic, char* payload, const AsyncMqttClientMessageProperties& properties,
                   const size_t& len, const size_t& index, const size_t& total)
{
  (void) payload;
  Serial.println("=====On MQTT Message=====");
  Serial.println("Publish received.");
  Serial.print("  topic: ");
  Serial.println(topic);
  Serial.print("  qos: ");
  Serial.println(properties.qos);
  Serial.print("  dup: ");
  Serial.println(properties.dup);
  Serial.print("  retain: ");
  Serial.println(properties.retain);
  Serial.print("  len: ");
  Serial.println(len);
  Serial.print("  index: ");
  Serial.println(index);
  Serial.print("  total: ");
  Serial.println(total);
  Serial.print("payload: ");
  Serial.println(payload);   // Output message content
}

void onMqttPublish(const uint16_t& packetId)
{
  Serial.println("Publish acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
}

void setup()
{
  Serial.begin(115200);
  while (!Serial && millis() < 5000);
  delay(500);

  // Connect to WIFI
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.println("Connection Failed! Rebooting...");
        delay(5000);
        ESP.restart(); // Restart ESP32
      }
  delay(500);

  mqttClient.onConnect(onMqttConnect);  // Set the callback function when MQTT connects
  mqttClient.onDisconnect(onMqttDisconnect); // Set the callback function when MQTT disconnects
  mqttClient.onMessage(onMqttMessage); // Set the callback function when subscribing to an MQTT topic
  mqttClient.onPublish(onMqttPublish); // Set the callback function when publishing to an MQTT topic
  mqttClient.setServer(MQTT_HOST, MQTT_PORT); // Set MQTT server information
  mqttClient.connect(); // Connect to MQTT

  delay(500);
}

void loop()
{
  // Publish topic message
  uint16_t packetIdPub = mqttClient.publish(PubTopic, 2, true, "welcome to Lingshunlab.com");
  Serial.print("Publishing at QoS 2, packetId: ");
  Serial.println(packetIdPub);
  delay(2000);
}

After uploading the code, the program will first connect to WIFI, then connect to the MQTT server, and then publish a corresponding topic message every 2 seconds.

Running MQTT Client on ESP32 for Publishing and Subscribing to Topics

Complete Code for Subscribing to a Topic

#include <WiFi.h>

// Configure WIFI 
#define WIFI_SSID         "***your wifi***"
#define WIFI_PASSWORD     "***your wifi password***"

// Load AsyncMQTT_ESP32 library
#include <AsyncMQTT_ESP32.h>

// Configure MQTT server address and port
#define MQTT_HOST         IPAddress(192,168,1,55)    // Broker IP
// #define MQTT_HOST         "broker.emqx.io"        // Broker address
#define MQTT_PORT         1883

const char *SubTopic  = "lingshunlab/ESP32";        // Topic for subscribing

AsyncMqttClient mqttClient;

void onMqttConnect(bool sessionPresent)
{
  Serial.println("=====On MQTT Connect=====");
  Serial.print("Connected to MQTT broker: ");
  Serial.print(MQTT_HOST);
  Serial.print(", port: ");
  Serial.println(MQTT_PORT);
  Serial.print("PubTopic: ");
  Serial.println(SubTopic);

  // Subscribe to the MQTT topic, with QoS set to 2
  uint16_t packetIdSub = mqttClient.subscribe(SubTopic, 2);
  Serial.print("Subscribing at QoS 2, packetId: ");
  Serial.println(packetIdSub);
}

void onMqttDisconnect(AsyncMqttClientDisconnectReason reason)
{
  (void) reason;

  Serial.println("Disconnected from MQTT.");
}

void onMqttSubscribe(const uint16_t& packetId, const uint8_t& qos)
{
  Serial.println("=====On MQTT Subscribe=====");
  Serial.println("Subscribe acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
  Serial.print("  qos: ");
  Serial.println(qos);
}

void onMqttUnsubscribe(const uint16_t& packetId)
{
  Serial.println("Unsubscribe acknowledged.");
  Serial.print("  packetId: ");
  Serial.println(packetId);
}

void onMqttMessage(char* topic, char* payload, const AsyncMqttClientMessageProperties& properties,
                   const size_t& len, const size_t& index, const size_t& total)
{
  (void) payload;
  Serial.println("=====On MQTT Message=====");
  Serial.println("Publish received.");
  Serial.print("  topic: ");
  Serial.println(topic);
  Serial.print("  qos: ");
  Serial.println(properties.qos);
  Serial.print("  dup: ");
  Serial.println(properties.dup);
  Serial.print("  retain: ");
  Serial.println(properties.retain);
  Serial.print("  len: ");
  Serial.println(len);
  Serial.print("  index: ");
  Serial.println(index);
  Serial.print("  total: ");
  Serial.println(total);
  Serial.print("payload: ");
  Serial.println(payload);  
}

void setup()
{
  Serial.begin(115200);
  while (!Serial && millis() < 5000);
  delay(500);

  // Connect to WIFI
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.waitForConnectResult() != WL_CONNECTED) {
        Serial.println("Connection Failed! Rebooting...");
        delay(5000);
        ESP.restart();
      }
  delay(500);

  mqttClient.onConnect(onMqttConnect); // Set the callback function when MQTT connects
  mqttClient.onDisconnect(onMqttDisconnect);  // Set the callback function when MQTT disconnects
  mqttClient.onSubscribe(onMqttSubscribe); // Set the callback function when subscribing to an MQTT topic
  mqttClient.onUnsubscribe(onMqttUnsubscribe); // Set the callback function when unsubscribing from an MQTT topic
  mqttClient.onMessage(onMqttMessage); // Set the callback function when receiving topic messages
  mqttClient.setServer(MQTT_HOST, MQTT_PORT); // Set MQTT server information
  mqttClient.connect(); // Connect to MQTT

  delay(500);
}

void loop()
{

}

After uploading the code, the program will first connect to WIFI, then connect to the MQTT server, and when connected to MQTT, it will subscribe to the topic, and then every 2 seconds, it will receive messages published to the topic.

Running MQTT Client on ESP32 for Publishing and Subscribing to Topics

Leave a Comment

×