This guide covers how to develop an ESP32 MQTT client to publish MQTT messages and to subscribe to MQTT topics. To understand better how to use an ESP32 MQTT client, we will connect to HiveMQ MQTT broker and the client will send BME280 sensor readings such as temperature, humidity and pressure using MQTT topics. Moreover, we are going to discover how to subscribe to a MQTT topics so that the ESP32 can receive data.

Recommended: MQTT Protocol Tutorial: Technical description, MQTT security and Mosquitto

What we will learn..

During this tutorial, you will learn:

  • How to publish data from the ESP32 to MQTT topics (using BME280 sensor reading)
  • How to subscribe to a MQTT topic using ESP32 to receive data
  • How to use HiveMQ to check published messages
  • How to use HiveMQ to send messages to the ESP32

What do you need to follow this tutorial?

This guide is based on ESP32 so to follow the instructions on ths guide you need an EspressIf ESP32 or a compatible device.

How to develop an ESP32 MQTT client

Our ESP32 MQTT client has to do two different tasks:

  • publish data to MQTT topic
    • read data from BME280 sensor
  • subscribe to MQTT topic to receive data

To implement a MQTT client using ESP32 we have to follow this steps:

  1. Connect the ESP32 to the Wifi
  2. Set up and configure the MQTT client
  3. Set up and configure the BME280 sensor
  4. Connect the ESP32 to the MQTT broker
  5. publish sensor readings to MQTT topics periodically
  6. listen to incoming message subscribing to an MQTT topic

To test the client we will use the HiveMQ public MQTT broker, even if you can connect the client to another MQTT broker. You can check this guide if you want to use Raspberry Pi as MQTT broker.

Step 1: Connect the ESP32 to Wifi

Let’s begin. The first step is a common step. To develop the client we will use PlatforIO even if you can use another IDE if you prefer.

#include <Arduino.h>
#include <WiFi.h>

const char *SSID = "your_wifi_ssid";
const char *PWD = "your_wifi_password";

void connectToWiFi() {
  Serial.print("Connectiog to ");
 
  WiFi.begin(SSID, PWD);
  Serial.println(SSID);

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

  Serial.print("Connected.");
  
}

The code is really simply.

Step 2: Set up and configure the ESP32 Client

After the Wifi connection is implemented, we can focus on how to configure the ESP32 MQTT client. To simplify the client development, we will use the PubnSub Library that is suggested by HiveMQ. You have to import the library using your IDE. It depends on the IDE you are using but the process is almost the same: you have to look for the library and import it. The code to setup the ESP32 client is:

#include <PubSubClient.h>

// MQTT client
WiFiClient wifiClient;
PubSubClient mqttClient(wifiClient); 

char *mqttServer = "broker.hivemq.com";
int mqttPort = 1883;

void setupMQTT() {
  mqttClient.setServer(mqttServer, mqttPort);
  // set the callback function
  mqttClient.setCallback(callback);
}

This code has to be added to the code shown in the previous step. The code is:

  • Line 1: Import the PubSubClient header
  • Line 4,5: define the mqttClient passing the WiFiClient
  • Line 7,8: define the MQTT broker address and the port. In this example, we are using HiveMQ but you can use another MQTT broker
  • Line 11: configure the mqttClient setting the MQTT broker

Step 3: Set up and configure BME280 sensor

To send data to the MQTT topics, we have supposed to acquire temperature, humidity and pressure using BME280 sensor. Of course, you can send other kind of data. The schmeatic to connect the ESP32 to BME280 is shown below:

ESP32 BME280 connections

The code is simple. Again, you have to import the Adafruit BME280 sensor library before using it:

#include <Adafruit_BME280.h>
#include <Adafruit_Sensor.h>

Adafruit_BME280 bme;

void setup() {
  Serial.begin(9600);
  connectToWiFi();
  if (!bme.begin(0x76)) {
    Serial.println("Problem connecting to BME280");
  }
  setupMQTT();
}
  • Line 4: we define the Adafruit BME280 sensor
  • Line 9: we connect to it. Notice that the I2C address used is 0x76. If your sensor uses a different address replace it with the value in the code

4. Connect the ESP32 to the MQTT broker

During this step, we wil connect the ESP32 MQTT client to the MQTT broker so that the ESP32 client can send data. To do it add the following code:

void reconnect() {
  Serial.println("Connecting to MQTT Broker...");
  while (!mqttClient.connected()) {
      Serial.println("Reconnecting to MQTT Broker..");
      String clientId = "ESP32Client-";
      clientId += String(random(0xffff), HEX);
      
      if (mqttClient.connect(clientId.c_str())) {
        Serial.println("Connected.");
        // subscribe to topic
        mqttClient.subscribe("/swa/commands");
      }
      
  }
}

void loop() {

  if (!mqttClient.connected())
    reconnect();

  mqttClient.loop();
}

The code is simple:

  • Line 3: we try to connect the ESP32 MQTT client to the broker selecting a random id client everytime we connect
  • In the loop method, the code checks if the ESP32 client is connected. If not, reconnect the client to the broker
  • Line 11: the client subscribes to a topic named /swa/commands to receive data (we will see it later)

Step 5: Publishing the sensor readings to MQTT topics

In this step, we publish data to MQTT. To do this, the ESP32 client uses three different topics:

  • /swa/temperature topic used to publish the temperature readings
  • /swa/humidity topic used to publish the humidity readings
  • /swa/pressure topic used to publish the pressure readings

Therefore, the code is:

void loop() {

  if (!mqttClient.connected())
    reconnect();

  mqttClient.loop();

  long now = millis();
  if (now - last_time > 60000) {
    // Send data
    float temp = bme.readTemperature();
    float hum = bme.readHumidity();
    float pres = bme.readPressure() / 100;

    // Publishing data throgh MQTT
    sprintf(data, "%f", temp);
    Serial.println(data);
    mqttClient.publish("/swa/temperature", data);
    sprintf(data, "%f", hum);
    Serial.println(hum);
    mqttClient.publish("/swa/humidity", data);
    sprintf(data, "%f", pres);
    Serial.println(pres);
    mqttClient.publish("/swa/pressure", data);
    last_time = now;
  }
  • Line 11,12,12: the code reads the BME280 sensor values
  • Line 18,21,24: the code publishes the BME280 sensor reading to three different topics

Notice that the code publishes the data every minute. If you want to change the interval, you have to modify the value at line 9.

Step 6: Listen to incoming message subscribing to an MQTT topic

In this step, we listen to the incoming MQTT messages published by another MQTT client subscribing to a topic. It is necessary to implement a callback function where we will handle the incoming message:

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Callback - ");
  Serial.print("Message:");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
}

In this example, we simply write the message payload received. Anyway, you can do other tasks here according to the payload the ESP32 client receives. For example, we can:

  • control LED (turning it on or off)
  • controlling the RGB color
  • Write the result on a display

More resources:
How to connect ESP32 to Amazon AWS IoT Core using AWS MQTT
Cloud IoT Core ESP32: Send data to Google Cloud Platform using MQTT

Test the ESP32 MQTT client using HiveMQ browser client

Run the code on your ESP32. If you have done everything correctly, the code should compile and run. Now you can configure the HiveMQ browser client to visualize the MQTT messages published by the ESP32 MQTT client. Go to this link and click on connect button.

Add the subscription topics one for each topic the ESP32 uses. You should have a the end something like this:

ESP32 MQTT topics

As soon as the ESP32 client publishes data to this topics you should get see the data as shown in the picture below:

MQTT messages published by ESP32 MQTT client

Test the ESP32 MQTT client using MQTT.fx

You can get the same result using MQTT.fx. Run it and connect to HiveMQ MQTT broker adding a new profile. Subscribe to the three topics shown previously and you will get the following result:

Test ESP32 client using MQTT.fx

In this last test we wil publish using the HiveMQ client broswer a message to the topic where the ESP32 client is subscribed:

subscibe to MQTT topic using ESP32

Notice that the topic is the same used in the ESP32 MQTT client code. Write Hello ESP32 in the message box and click on publish. On the ESP32 MQTT client, we will get:

ESP32 MQTT message

Wrapping up

At the end of this ESP32 MQTT clien tutorial, we learned how to publish MQTT messages to channels and how to use BME280 to read temperature, humidity and pressure to publish on three different MQTT channels.

Moreover, you have learned how to subscribe the ESP32 MQTT client to a topic to receive MQTT messages. At the end, we have tested the ESP32 client using HiveMQ MQTT broker.

LEAVE A REPLY

Please enter your comment!
Please enter your name here