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:
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.
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.