ESP32: Publishing messages to MQTT topic

The objective of this post is to explain how to publish a message to a MQTT topic, using the ESP32 and the Arduino IDE libraries.


Introduction

The objective of this post is to explain how to publish a message to a MQTT topic, using the ESP32 and the Arduino IDE libraries.

We will assume that the broker will be hosted on CloudMQTT, which is the host we’ve been using in previous tutorials about MQTT. Since CloudMQTT has a free plan, we can just create an account and test it. Setting an account is really simple. You can check here how to do it and how to create a broker instance.

After completing the procedure, check the instance information page, which should be similar to the one shown in figure 1. The important credentials that we will be using on the ESP32 code are the server, the user, the password and the port.

ESP8266 CloudMQTT Credentials

Figure 1 – CloudMQTT instance information.

For the ESP32 side, we are going to use a MQTT library, called PubSubClient. This was the same library used in the previous tutorial on how to connect the ESP8266 to a MQTT broker. Although at the time of writing there is no support mentioned for the ESP32, as can be seen here, the library works fine.

As usual, the easiest way to install the library is via Arduino IDE library manager, as can be seen in figure 2.

Arduino MQTT Pub Sub library

Figure 2 – PubSub library installation, via Arduino IDE library manager.


The code

The code needed for us to connect to the MQTT broker and publish a message to a topic will be very similar to the one used on the ESP8266 post. These are good news since the code can be reused for the ESP32, making it easier to port applications.

As usual, we need to include some libraries in our code. We need the WiFi library, in order to be able to connect the ESP32 to a WiFi network, and the PubSubClient library, which will allow us to connect to a MQTT broker. For a more detailed explanation on how to connect the ESP32 to a WiFi network, check here.

In order to have an easy to modify and readable code, we will declare the credentials and information needed to connect to both the WiFi network and the MQTT broker in global variables. For the connection to the MQTT broker, we will need the server address, the port, the username and the password, which can be obtained in the instance information page, as shown in figure 1 of the introduction section.

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

const char* ssid = "yourNetworkName";
const char* password = "yourNetworkPassword";
const char* mqttServer = "m11.cloudmqtt.com";
const int mqttPort = 12948;
const char* mqttUser = "yourMQTTuser";
const char* mqttPassword = "yourMQTTpassword";

After that, we will declare an object of class WiFiClient, which allows to establish a connection to a defined IP and port. Nevertheless, we will not explicitly use this object because it will be used by the MQTT library under the hood.

We will also declare an object of class PubSubClient and pass as input of the constructor the previously defined WiFiClient.

WiFiClient espClient;
PubSubClient client(espClient);

As usual, in the setup function, we open a serial connection, since this is the easiest way to output the results of our program. We will also connect to WiFi network, so we can reach the MQTT broker and publish messages to topics.

Serial.begin(115200);
WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi..");
}

Serial.println("Connected to the WiFi network");

Next, we need to specify the address and the port of the MQTT server, which were previously declared in our global variables.  To do so, we call the setServer method on the PubSubClient object, which receives as parameters both the address and the port.

After that, we will connect to the MQTT server. To do the actual connection, we call the connect method, passing as input parameters a unique identifier for our client, the authentication username and password. We will use as identifier “ESP32Client”.

This method call will return true on connection success and false otherwise.

client.setServer(mqttServer, mqttPort);

while (!client.connected()) {
    Serial.println("Connecting to MQTT...");

    if (client.connect("ESP32Client", mqttUser, mqttPassword )) {

      Serial.println("connected");  

    } else {

      Serial.print("failed with state ");
      Serial.print(client.state());
      delay(2000);

    }
}

Note that in the previous code we used two auxiliary methods. The connected method returns true if the connection is established or false otherwise. The state method will return a code with information about why the connection failed. Check here the possible returning values.

Finally, we will publish a message to a topic. To do so, we call the publish method, passing as input parameters the topic name and the message to publish. We will just publish a “Hello from ESP32” message on the “esp/test” topic.

client.publish("esp/test", "Hello from ESP32");

Check bellow the full source code, which already includes the main loop function. There, we will call the loop method of the PubSubClient. This method needs to be called regularly in order to allow the receiving of messages and maintaining the connection to the broker. Naturally, in our case, since we only want to publish a message to the topic and we will not do anything more, we are including it just as an example.

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

const char* ssid = "yourNetworkName";
const char* password =  "yourNetworkPassword";
const char* mqttServer = "m11.cloudmqtt.com";
const int mqttPort = 12948;
const char* mqttUser = "yourMQTTuser";
const char* mqttPassword = "yourMQTTpassword";

WiFiClient espClient;
PubSubClient client(espClient);

void setup() {

  Serial.begin(115200);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi..");
  }

  Serial.println("Connected to the WiFi network");

  client.setServer(mqttServer, mqttPort);

  while (!client.connected()) {
    Serial.println("Connecting to MQTT...");

    if (client.connect("ESP32Client", mqttUser, mqttPassword )) {

      Serial.println("connected");

    } else {

      Serial.print("failed with state ");
      Serial.print(client.state());
      delay(2000);

    }
  }

  client.publish("esp/test", "Hello from ESP32");

}

void loop() {
  client.loop();
}


Testing the code

To test the code, we are going to use an application called MQTTLens, which will allow us to subscribe to a MQTT topic and receive published messages. So, open the application and subscribe to the “esp/test” topic, which was the one we specified in the ESP32 code.

After that, just upload and run the code on the ESP32. On the Arduino IDE serial monitor, you should get a result similar to figure 3.

ESP32 connection to MQTT broker

Figure 3 – Connection to MQTT broker on the ESP32.

On the MQTTLens side, you should receive the message published on the topic, as shown in figure 4.

MQTTLens receiving MQTT ESP32 message

Figure 4 – Receiving the message on MQTTLens.


Related Content


Related Posts

 

Technical details

  • PubSubClient library: v2.6.0

17 thoughts on “ESP32: Publishing messages to MQTT topic”

  1. Pingback: ESP32: Subscribing to MQTT topic | techtutorialsx

  2. Pingback: ESP32: Subscribing to MQTT topic | techtutorialsx

  3. Pingback: LinkIt Smart 7688 Duo: Subscribing to MQTT topic | techtutorialsx

  4. Pingback: LinkIt Smart 7688 Duo: Subscribing to MQTT topic | techtutorialsx

  5. Pingback: LinkIt Smart 7688 Duo: Publishing messages to MQTT topic | techtutorialsx

  6. Pingback: LinkIt Smart 7688 Duo: Publishing messages to MQTT topic | techtutorialsx

  7. Pingback: ESP32: Sending JSON messages over MQTT | techtutorialsx

  8. Pingback: ESP32: Sending JSON messages over MQTT | techtutorialsx

Leave a Reply