ESP32 MQTT client: Publish and Subscribe. HiveMQ and BME280 example

This guide covers how to develop an ESP32 MQTT client to publish MQTT messages and to subscribe to MQTT topics. In this tutorial, we will pubsubclient library to connect the ESP32 to MQTT broker. To understand better how to use an ESP32 MQTT client, we will use an ESP32 MQTT publish example connecting to HiveMQ MQTT broker. 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 MQTT topics so that the ESP32 can receive data.

MQTT is one of the most important IoT protocols, widely used in IoT projects to connect boards such as ESP32 to cloud MQTT broker. Moreover, ESP32 with MQTT is used in home automation too. This tutorial assumes you are familiar with MQTT and know the basic aspects such as MQTT broker, MQTT topics and the publish and subscribe architecture. If you are new to this IoT protocol, it is useful to learn more about MQTT reading this technical description.

What we will learn..

During this tutorial, you will learn: how to

  • Publish MQTT messages from the ESP32 using MQTT topics through Pubsub library
  • Connect to an MQTT broker using ESP32
  • Subscribe to an MQTT topic using ESP32 to receive data
  • Use HiveMQ to check published messages
  • Publish MQTT message from ESP32 to cloud MQTT broker

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 Arduino ESP32 MQTT client

Our ESP32 MQTT client has to do two different tasks:

  • publish data to MQTT topic:
    • read data from a 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 MQTT client for 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 using PubSubClient

After the Wifi connection is implemented, we can focus on how to configure the MQTT client for ESP32. To simplify client development, we will use the PubSubClient Library that is suggested by HiveMQ.

You have to import the PubSubClient 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 set up 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 ESP32 client code has to be added to the code shown in the previous step. The most import lines are:

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

Step 3: Set up and configure BME280 sensor

As ESP32 MQTT publish example, the MQTT client for ESP32 sends temperature, humidity, and pressure using MQTT topics. Of course, you can send different data.

The schematic 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(); }

Describing the code we have at lines:

  • 3: we define the Adafruit BME280 sensor
  • 7: we connect to the sensor. Notice that the I2C address used is 0x76. If your sensor uses a different address replace it with the value in the code

If you want to know more about BME280, you can read how to build a weather station using ESP32.

4. Connect the ESP32 to the MQTT broker

During this step, we wil connect the ESP32 MQTT client to the broker so that the 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 (clientId). The clientId changes every time we connect
  • In the loop method, the code checks if the ESP32 client is connected. If not, reconnect the client to the broker
  • 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 using PubsubClient for ESP32

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 8,9,10: the code reads the BME280 sensor values
  • Line 14,17,20: the code publishes the BME280 sensor reading to three different topics

Notice that the code publishes the data every minute and uses the PubsubClient method named publish that accepts the MQTT topic and the data to publish. If you want to change the interval, you have to modify the value at line 9.

Step 6: Subscribe to MQTT topic to listen to incoming message

In this step, we subscribe to MQTT topics to listen to the incoming MQTT messages published by another MQTT client subscribing to the same topic. Therefore, in the Pubsubclient library, It is necessary to implement a callback function. Here, 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 received message payload. Anyway, you can do other tasks here according to the payload the ESP32 client receives. For example, if we are using ESP32 with MQTT in home automation, 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

ESP32 Publish message example using HiveMQ browser client: Test

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 MQTT client.

  1. Go to this link and click on connect button
  2. Add the subscription topics one for each topic the ESP32 uses

You should have 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:

Using MQTT.fx to test the MQTT client for ESP32

Testing the ESP32 MQTT topic subscription

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

MQTT publishing example using client

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. We will get:

ESP32 MQTT message

Wrapping up

At the end of this ESP32 MQTT client tutorial, we learned how to publish MQTT messages to channels. We have used an ESP32 MQTT message publish example based on the BME280 sensor. The ESP32 publishes temperature, humidity and pressure to publish on three different MQTT channels.

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

    1. Vahe Arakelyan August 28, 2020

    Add Your Comment