Random Nerd Tutorials
Shares

ESP32 MQTT – Publish and Subscribe with Arduino IDE

Shares

This project shows how to use MQTT communication protocol with the ESP32 to publish messages and subscribe to topics. As an example, we’ll publish BME280 sensor readings to the Node-RED Dashboard, and control an ESP32 output. The ESP32 we’ll be programmed using Arduino IDE.

Project Overview

In this example, there’s a Node-RED application that controls ESP32 outputs and receives sensor readings from the ESP32 using MQTT communication protocol. The Node-RED application is running on a Raspberry Pi.

We’ll use the Mosquitto broker installed on the same Raspberry Pi. The broker is responsible for receiving all messages, filtering the messages, decide who is interested in them and publishing the messages to all subscribed clients.

The following figure shows an overview of what we’re going to do in this tutorial.

  • The Node-RED application publishes messages (“on” or “off“) in the topic esp32/output. The ESP32 is subscribed to that topic. So, it receives the message with “on” or “off” to turn the LED on or off.
  • The ESP32 publishes temperature on the esp32/temperature topic and the humidity on the esp32/humidity topic. The Node-RED application is subscribed to those topics. So, it receives temperature and humidity readings that can be displayed on a chart or gauge, for example.

Note: there’s also a similar tutorial on how to use the ESP8266 and Node-RED with MQTT.

Prerequisites

If you like home automation and you want to learn more about Node-RED, Raspberry Pi, ESP8266 and Arduino, we recommend trying our course: Build a Home Automation System with Node-RED, ESP8266 and Arduino. We also have a course dedicated to the ESP32: Enroll in Learn ESP32 with Arduino IDE course.

Parts Required

These are the parts required to build the circuit (click the links below to find the best price at Maker Advisor):

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

Introducing the BME280 Sensor Module

The BME280 sensor module reads temperature, humidity, and pressure. Because pressure changes with altitude, you can also estimate altitude. However, in this tutorial we’ll just read temperature and humidity. There are several versions of this sensor module, but we’re using the one shown in the figure below.

cloud-download

The sensor can communicate using either SPI or I2C communication protocols (there are modules of this sensor that just communicate with I2C, these just come with four pins).

To use SPI communication protocol, use the following pins:

  • SCK – this is the SPI Clock pin
  • SDO – MISO
  • SDI – MOSI
  • CS – Chip Select

To use I2C communication protocol, the sensor uses the following pins:

  • SCK – SCL pin
  • SDI – SDA pin

Schematic

We’re going to use I2C communication with the BME280 sensor module. For that, wire the sensor to the ESP32 SDA and SCL pins, as shown in the following schematic diagram.

We’ll also control an ESP32 output, an LED connected to GPIO 4.

Here’s how your circuit should look:

Preparing the Arduino IDE

There’s an add-on for the Arduino IDE that allows you to program the ESP32 using the Arduino IDE and its programming language. Follow one of the next tutorials to prepare your Arduino IDE to work with the ESP32, if you haven’t already.

After making sure you have the ESP32 add-on installed, you can continue with this tutorial.

Installing the PubSubClient Library

The PubSubClient library provides a client for doing simple publish/subscribe messaging with a server that supports MQTT (basically allows your ESP32 to talk with Node-RED).

  1. Click here to download the PubSubClient library. You should have a .zip folder in your Downloads folder
  2. Unzip the .zip folder and you should get pubsubclient-master folder
  3. Rename your folder from pubsubclient-master to pubsubclient
  4. Move the pubsubclient folder to your Arduino IDE installation libraries folder
  5. Then, re-open your Arduino IDE

The library comes with a number of example sketches. See File >Examples > PubSubClient within the Arduino IDE software.

Important: PubSubClient is not fully compatible with the ESP32, but the example provided in this tutorial is working very reliably during our tests.

Installing the BME280 library

To take readings from the BME280 sensor module we’ll use the Adafruit_BME280 library. Follow the next steps to install the library in your Arduino IDE:

  1. Click here to download the Adafruit-BME280 library. You should have a .zip folder in your Downloads folder
  2. Unzip the .zip folder and you should get Adafruit-BME280-Library-master folder
  3. Rename your folder from Adafruit-BME280-Library-master to Adafruit_BME280_Library
  4. Move the Adafruit_BMPE280_Library folder to your Arduino IDE installation libraries folder
  5. Finally, re-open your Arduino IDE

Alternatively, you can go to Sketch > Include Library > Manage Libraries and type “adafruit bme280” to search for the library. Then, click install.

Installing the Adafruit_Sensor library

To use the BME280 library, you also need to install the Adafruit_Sensor library. Follow the next steps to install the library:

  1. Click here to download the Adafruit_Sensor library. You should have a .zip folder in your Downloads folder
  2. Unzip the .zip folder and you should get Adafruit_Sensor-master folder
  3. Rename your folder from Adafruit_Sensor-master to Adafruit_Sensor
  4. Move the Adafruit_Sensor folder to your Arduino IDE installation libraries folder
  5. Finally, re-open your Arduino IDE

Uploading code

Now, you can upload the following code to your ESP32. The code is commented on where you need to make changes. You need to edit the code with your own SSID, password and Raspberry Pi IP address.

This code publishes temperature and humidity readings on the esp32/temperature and esp32/humidity topics trough MQTT protocol.

The ESP32 is subscribed to the esp32/output topic to receive the messages published on that topic by the Node-RED application. Then, accordingly to the received message, it turns the LED on or off.

Subscribing to MQTT topics

In the reconnect() function, you can subscribe to MQTT topics. In this case, the ESP32 is only subscribed to the esp32/output:

client.subscribe("esp32/output");

In the callback() function, the ESP32 receives the MQTT messages of the subscribed topics. According to the MQTT topic and message, it turns the LED on or off:

// If a message is received on the topic esp32/output, you check if the message is either "on" or "off". 
// Changes the output state according to the message
if (String(topic) == "esp32/output") {
  Serial.print("Changing output to ");
  if (messageTemp == "on") {
    Serial.println("on");
    digitalWrite(ledPin, HIGH);
  }
  else if (messageTemp == "off") {
    Serial.println("off");
    digitalWrite(ledPin, LOW);
  }
}

Publishing MQTT messages

In the loop(), new readings are being published every 5 seconds:

if (now - lastMsg > 5000) { ... }

By default the ESP32 is sending the temperature in Celsius, but you can uncomment the last line to send the temperature in Fahrenheit:

// Temperature in Celsius
temperature = bme.readTemperature(); 
// Uncomment the next line to set temperature in Fahrenheit 
// (and comment the previous temperature line)
//temperature = 1.8 * bme.readTemperature() + 32; // Temperature in Fahrenheit

You need to convert the temperature float variable to a char array, so that you can publish the temperature reading in the esp32/temperature topic:

// Convert the value to a char array
char tempString[8];
dtostrf(temperature, 1, 2, tempString);
Serial.print("Temperature: ");
Serial.println(tempString);
client.publish("esp32/temperature", tempString);

The same process is repeated to publish the humidity reading in the esp32/humidity topic:

humidity = bme.readHumidity();
// Convert the value to a char array
char humString[8];
dtostrf(humidity, 1, 2, humString);
Serial.print("Humidity: ");
Serial.println(humString);
client.publish("esp32/humidity", humString);

Creating the Node-RED flow

Before creating the flow, you need to have installed in your Raspberry Pi:

After that, import the Node-RED flow provided. Go to the GitHub repository or click the figure below to see the raw file, and copy the code provided.

Next, in the Node-RED window, at the top right corner, select the menu, and go to Import  > Clipboard.

Then, paste the code provided and click Import.

The following nodes should load:

After making any changes, click the Deploy button to save all the changes.

Node-RED UI

Now, your Node-RED application is ready. To access Node-RED UI and see how your application looks, access any browser in your local network and type:

http://Your_RPi_IP_address:1880/ui

Your application should look as shown in the following figure. You can control the LED on and off with the switch or you can view temperature readings in a chart and the humidity values in a gauge.

Demonstration

Watch the next video for a live demonstration:


Open the Arduino IDE serial monitor to take a look at the MQTT messages being received and published.

Wrapping Up

In summary, we’ve shown you the basic concepts that allow you to turn on lights and monitor sensors with your ESP32 using Node-RED and the MQTT communication protocol. You can use this example to integrate in your own home automation system, control more outputs, or monitor other sensors.

You might also like reading:

We hope you’ve found this tutorial useful.

Thanks for reading.


Learn ESP32 with Arduino IDE

This our complete guide to program the ESP32 with Arduino IDE, including projects, tips, and tricks! The registrations are open, so SIGN UP NOW »

Leave a Comment:

Add Your Reply

⏰ Registrations are open ⏰
Sign up for "Learn ESP32 with Arduino IDE" Course