Learn how to publish BME680 sensor readings (temperature, humidity, pressure and gas air quality) via MQTT with the ESP32 to any platform that supports MQTT or any MQTT client. As an example, we’ll publish sensor readings to Node-RED Dashboard and the ESP32 will be programmed using Arduino IDE.
Recommended reading: What is MQTT and How It Works
Project Overview
The following diagram shows a high-level overview of the project we’ll build.
- The ESP32 requests sensor readings from the BME680 sensor.
- The temperature readings are published in the esp/bme680/temperature topic;
- Humidity readings are published in the esp/bme680/humiditytopic;
- Pressure readings are published in the esp/bme680/pressure topic;
- Gas readings are published in the esp/bme680/gas topic;
- Node-RED is subscribed to those topics;
- Node-RED receives the sensor readings and then displays them on gauges and text fields;
- You can receive the readings in any other platform that supports MQTT and handle the readings as you want.
Prerequisites
Before proceeding with this tutorial, make sure you check the following prerequisites.
Arduino IDE
We’ll program the ESP32 using Arduino IDE, so make sure you have the ESP32 add-on installed.
MQTT Broker
To use MQTT, you need a broker. We’ll be using Mosquitto broker installed on a Raspberry Pi. Read How to Install Mosquitto Broker on Raspberry Pi.
You can use any other MQTT broker, including a cloud MQTT broker. We’ll show you how to do that in the code later on.
If you’re not familiar with MQTT make sure you read our introductory tutorial: What is MQTT and How It Works.
MQTT Libraries
To use MQTT with the ESP32 we’ll use the Async MQTT Client Library.
Installing the Async MQTT Client Library
- Click here to download the Async MQTT client library. You should have a .zip folder in your Downloads folder
- Unzip the .zip folder and you should get async-mqtt-client-master folder
- Rename your folder from
async-mqtt-client-masterto async_mqtt_client - Move the async_mqtt_client folder to your Arduino IDE installation libraries folder
- Finally, re-open your Arduino IDE
Alternatively, you can go to Sketch > Include Library > Add . ZIP library and select the library you’ve just downloaded.
Installing the Async TCP Library
To use MQTT with the ESP, you also need the Async TCP library.
- Click here to download the Async TCP client library. You should have a .zip folder in your Downloads folder
- Unzip the .zip folder and you should get AsyncTCP-master folder
- Rename your folder from
AsyncTCP-masterto AsyncTCP - Move the AsyncTCP folder to your Arduino IDE installation libraries folder
- Finally, re-open your Arduino IDE
Alternatively, you can go to Sketch > Include Library > Add . ZIP library and select the library you’ve just downloaded.
BME680 Sensor Libraries
To get readings from the BME680 sensor module, we’ll use the Adafruit_BME680 library. You also need to install the Adafruit_Sensor library. Follow the next steps to install the libraries in your Arduino IDE:
1. Open your Arduino IDE and go to Sketch > Include Library > Manage Libraries. The Library Manager should open.
2. Search for “adafruit bme680 ” on the Search box and install the library.
To use the BME680 library, you also need to install the Adafruit Unified Sensor. Follow the next steps to install the library in your Arduino IDE:
3. Search for “Adafruit Unified Sensor“in the search box. Scroll all the way down to find the library and install it.
After installing the libraries, restart your Arduino IDE.
To learn more about the BME680 sensor, read our guide: ESP32 with BME680 Sensor using Arduino IDE (Pressure, Temperature, Humidity).
Parts Required
For this tutorial you need the following parts:
- ESP32 (read Best ESP32 development boards)
- BME680 – BME680 with ESP32 Guide
- Raspberry Pi board (read Best Raspberry Pi Starter Kits)
- MicroSD Card – 16GB Class10
- Raspberry Pi Power Supply (5V 2.5A)
- Jumper wires
- Breadboard
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!
Schematic Diagram
Wire the BME680 to the ESP32 as shown in the following schematic diagram with the SDA pin connected to GPIO 21 and the SCL pin connected to GPIO 22.
Code
Copy the following code to your Arduino IDE. To make it work for you, you need to insert your network credentials as well as the MQTT broker details.
/*
Rui Santos & Sara Santos - Random Nerd Tutorials
Complete project details at https://RandomNerdTutorials.com/esp32-mqtt-publish-bme680-arduino/
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
*/
#include <WiFi.h>
extern "C" {
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
}
#include <AsyncMqttClient.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"
// Raspberry Pi Mosquitto MQTT Broker
#define MQTT_HOST IPAddress(192, 168, 1, XXX)
// For a cloud MQTT broker, type the domain name
//#define MQTT_HOST "example.com"
#define MQTT_PORT 1883
// Temperature MQTT Topics
#define MQTT_PUB_TEMP "esp/bme680/temperature"
#define MQTT_PUB_HUM "esp/bme680/humidity"
#define MQTT_PUB_PRES "esp/bme680/pressure"
#define MQTT_PUB_GAS "esp/bme680/gas"
/*#define BME_SCK 14
#define BME_MISO 12
#define BME_MOSI 13
#define BME_CS 15*/
Adafruit_BME680 bme; // I2C
//Adafruit_BME680 bme(BME_CS); // hardware SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);
// Variables to hold sensor readings
float temperature;
float humidity;
float pressure;
float gasResistance;
AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;
unsigned long previousMillis = 0; // Stores last time temperature was published
const long interval = 10000; // Interval at which to publish sensor readings
void getBME680Readings(){
// Tell BME680 to begin measurement.
unsigned long endTime = bme.beginReading();
if (endTime == 0) {
Serial.println(F("Failed to begin reading :("));
return;
}
if (!bme.endReading()) {
Serial.println(F("Failed to complete reading :("));
return;
}
temperature = bme.temperature;
pressure = bme.pressure / 100.0;
humidity = bme.humidity;
gasResistance = bme.gas_resistance / 1000.0;
}
void connectToWifi() {
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}
void connectToMqtt() {
Serial.println("Connecting to MQTT...");
mqttClient.connect();
}
void WiFiEvent(WiFiEvent_t event) {
Serial.printf("[WiFi-event] event: %d\n", event);
switch(event) {
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
connectToMqtt();
break;
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
xTimerStop(mqttReconnectTimer, 0); // ensure we don't reconnect to MQTT while reconnecting to Wi-Fi
xTimerStart(wifiReconnectTimer, 0);
break;
}
}
void onMqttConnect(bool sessionPresent) {
Serial.println("Connected to MQTT.");
Serial.print("Session present: ");
Serial.println(sessionPresent);
}
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
Serial.println("Disconnected from MQTT.");
if (WiFi.isConnected()) {
xTimerStart(mqttReconnectTimer, 0);
}
}
/*void onMqttSubscribe(uint16_t packetId, uint8_t qos) {
Serial.println("Subscribe acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
Serial.print(" qos: ");
Serial.println(qos);
}
void onMqttUnsubscribe(uint16_t packetId) {
Serial.println("Unsubscribe acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}*/
void onMqttPublish(uint16_t packetId) {
Serial.print("Publish acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}
void setup() {
Serial.begin(115200);
Serial.println();
if (!bme.begin()) {
Serial.println(F("Could not find a valid BME680 sensor, check wiring!"));
while (1);
}
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));
WiFi.onEvent(WiFiEvent);
mqttClient.onConnect(onMqttConnect);
mqttClient.onDisconnect(onMqttDisconnect);
//mqttClient.onSubscribe(onMqttSubscribe);
//mqttClient.onUnsubscribe(onMqttUnsubscribe);
mqttClient.onPublish(onMqttPublish);
mqttClient.setServer(MQTT_HOST, MQTT_PORT);
// If your broker requires authentication (username and password), set them below
//mqttClient.setCredentials("REPlACE_WITH_YOUR_USER", "REPLACE_WITH_YOUR_PASSWORD");
connectToWifi();
// Set up oversampling and filter initialization
bme.setTemperatureOversampling(BME680_OS_8X);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150); // 320*C for 150 ms
}
void loop() {
unsigned long currentMillis = millis();
// Every X number of seconds (interval = 10 seconds)
// it publishes a new MQTT message
if (currentMillis - previousMillis >= interval) {
// Save the last time a new reading was published
previousMillis = currentMillis;
getBME680Readings();
Serial.println();
Serial.printf("Temperature = %.2f ºC \n", temperature);
Serial.printf("Humidity = %.2f % \n", humidity);
Serial.printf("Pressure = %.2f hPa \n", pressure);
Serial.printf("Gas Resistance = %.2f KOhm \n", gasResistance);
// Publish an MQTT message on topic esp/bme680/temperature
uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, String(temperature).c_str());
Serial.printf("Publishing on topic %s at QoS 1, packetId: %i", MQTT_PUB_TEMP, packetIdPub1);
Serial.printf("Message: %.2f \n", temperature);
// Publish an MQTT message on topic esp/bme680/humidity
uint16_t packetIdPub2 = mqttClient.publish(MQTT_PUB_HUM, 1, true, String(humidity).c_str());
Serial.printf("Publishing on topic %s at QoS 1, packetId %i: ", MQTT_PUB_HUM, packetIdPub2);
Serial.printf("Message: %.2f \n", humidity);
// Publish an MQTT message on topic esp/bme680/pressure
uint16_t packetIdPub3 = mqttClient.publish(MQTT_PUB_PRES, 1, true, String(pressure).c_str());
Serial.printf("Publishing on topic %s at QoS 1, packetId %i: ", MQTT_PUB_PRES, packetIdPub3);
Serial.printf("Message: %.2f \n", pressure);
// Publish an MQTT message on topic esp/bme680/gas
uint16_t packetIdPub4 = mqttClient.publish(MQTT_PUB_GAS, 1, true, String(gasResistance).c_str());
Serial.printf("Publishing on topic %s at QoS 1, packetId %i: ", MQTT_PUB_GAS, packetIdPub4);
Serial.printf("Message: %.2f \n", gasResistance);
}
}
How the Code Works
The following section imports all the required libraries.
#include <WiFi.h>
extern "C" {
#include "freertos/FreeRTOS.h"
#include "freertos/timers.h"
}
#include <AsyncMqttClient.h>
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
Include your network credentials on the following lines.
#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"
Insert the Raspberry Pi IP address, so that the ESP32 connects to your broker.
#define MQTT_HOST IPAddress(192, 168, 1, 106)
If you’re using a cloud MQTT broker, insert the broker domain name, for example:
#define MQTT_HOST "example.com"
Define the MQTT port.
#define MQTT_PORT 1883
The temperature, humidity and pressure will be published on the following topics:
#define MQTT_PUB_TEMP "esp/bme680/temperature"
#define MQTT_PUB_HUM "esp/bme680/humidity"
#define MQTT_PUB_PRES "esp/bme680/pressure"
#define MQTT_PUB_GAS "esp/bme680/gas"
Initialize a Adafruit_BME680 object called bme.
Adafruit_BME680 bme;
The temperature, humidity, pressure, and gasResistance variables will hold all sensor readings from the BME680 sensor.
float temperature;
float humidity;
float pressure;
float gasResistance;
Create an AsyncMqttClient object called mqttClient to handle the MQTT client and timers to reconnect to your MQTT broker and router when it disconnects.
AsyncMqttClient mqttClient;
TimerHandle_t mqttReconnectTimer;
TimerHandle_t wifiReconnectTimer;
Then, create some auxiliary timer variables to publish the readings every 10 seconds. You can change the delay time on the interval variable.
unsigned long previousMillis = 0;
const long interval = 10000;
MQTT functions: connect to Wi-Fi, connect to MQTT, and Wi-Fi events
We haven’t added any comments to the functions defined in the next code section. Those functions come with the Async Mqtt Client library. The function’s names are pretty self-explanatory.
For example, the connectToWifi() connects your ESP32 to your router:
void connectToWifi() {
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
}
The connectToMqtt() connects your ESP32 to your MQTT broker:
void connectToMqtt() {
Serial.println("Connecting to MQTT…");
mqttClient.connect();
}
The WiFiEvent() function is responsible for handling the Wi-Fi events. For example, after a successful connection with the router and MQTT broker, it prints the ESP32 IP address. On the other hand, if the connection is lost, it starts a timer and tries to reconnect.
void WiFiEvent(WiFiEvent_t event) {
Serial.printf("[WiFi-event] event: %d\n", event);
switch(event) {
case ARDUINO_EVENT_WIFI_STA_GOT_IP:
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
connectToMqtt();
break;
case ARDUINO_EVENT_WIFI_STA_DISCONNECTED:
Serial.println("WiFi lost connection");
xTimerStop(mqttReconnectTimer, 0);
xTimerStart(wifiReconnectTimer, 0);
break;
}
}
The onMqttConnect() function runs after starting a session with the broker.
void onMqttConnect(bool sessionPresent) {
Serial.println("Connected to MQTT.");
Serial.print("Session present: ");
Serial.println(sessionPresent);
}
MQTT functions: disconnect and publish
If the ESP32 loses connection with the MQTT broker, it calls the onMqttDisconnect function that prints that message in the serial monitor.
void onMqttDisconnect(AsyncMqttClientDisconnectReason reason) {
Serial.println("Disconnected from MQTT.");
if (WiFi.isConnected()) {
xTimerStart(mqttReconnectTimer, 0);
}
}
When you publish a message to an MQTT topic, the onMqttPublish() function is called. It prints the packet id in the Serial Monitor.
void onMqttPublish(uint16_t packetId) {
Serial.println("Publish acknowledged.");
Serial.print(" packetId: ");
Serial.println(packetId);
}
Basically, all these functions that we’ve just mentioned are callback functions. So, they are executed asynchronously.
setup()
Now, let’s proceed to the setup(). Initialize the BME680 sensor.
if (!bme.begin()) {
Serial.println(F("Could not find a valid BME680 sensor, check wiring!"));
while (1);
}
The next two lines create timers that will allow both the MQTT broker and Wi-Fi connection to reconnect, in case the connection is lost.
mqttReconnectTimer = xTimerCreate("mqttTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToMqtt));
wifiReconnectTimer = xTimerCreate("wifiTimer", pdMS_TO_TICKS(2000), pdFALSE, (void*)0, reinterpret_cast<TimerCallbackFunction_t>(connectToWifi));
The following line assigns a callback function, so when the ESP32 connects to your Wi-Fi, it will execute the WiFiEvent() function to print the details described earlier.
WiFi.onEvent(WiFiEvent);
Finally, assign all the callbacks functions. This means that these functions will be executed automatically when needed. For example, when the ESP32 connects to the broker, it automatically calls the onMqttConnect() function, and so on.
mqttClient.onConnect(onMqttConnect);
mqttClient.onDisconnect(onMqttDisconnect);
//mqttClient.onSubscribe(onMqttSubscribe);
//mqttClient.onUnsubscribe(onMqttUnsubscribe);
mqttClient.onPublish(onMqttPublish);
mqttClient.setServer(MQTT_HOST, MQTT_PORT);
Broker Authentication
If your broker requires authentication, uncomment the following line and insert your credentials (username and password).
mqttClient.setCredentials("REPlACE_WITH_YOUR_USER", "REPLACE_WITH_YOUR_PASSWORD");
Connect to Wi-Fi.
connectToWifi();
Finally, set up the following parameters (oversampling, filter and gas heater) for the sensor.
bme.setTemperatureOversampling(BME680_OS_8X);
bme.setHumidityOversampling(BME680_OS_2X);
bme.setPressureOversampling(BME680_OS_4X);
bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme.setGasHeater(320, 150);
loop()
In the loop(), you create a timer that allows you to get new readings from the BME680 sensor and publishing them on the corresponding topic every 10 seconds.
unsigned long currentMillis = millis();
// Every X number of seconds (interval = 10 seconds)
// it publishes a new MQTT message
if (currentMillis - previousMillis >= interval) {
// Save the last time a new reading was published
previousMillis = currentMillis;
getBME680Readings();
Serial.println();
Serial.printf("Temperature = %.2f ºC \n", temperature);
Serial.printf("Humidity = %.2f % \n", humidity);
Serial.printf("Pressure = %.2f hPa \n", pressure);
Serial.printf("Gas Resistance = %.2f KOhm \n", gasResistance);
Learn more about getting readings from the BME680 sensor: ESP32 with BME680 Temperature, Humidity and Pressure Sensor Guide.
Publishing to topics
To publish the readings on the corresponding MQTT topics, use the next lines:
uint16_t packetIdPub1 = mqttClient.publish(MQTT_PUB_TEMP, 1, true, String(temperature).c_str());
uint16_t packetIdPub2 = mqttClient.publish(MQTT_PUB_HUM, 1, true, String(humidity).c_str());
uint16_t packetIdPub3 = mqttClient.publish(MQTT_PUB_PRES, 1, true, String(pressure).c_str());
uint16_t packetIdPub4 = mqttClient.publish(MQTT_PUB_GAS, 1, true, String(gasResistance).c_str());
Basically, use the publish() method on the mqttClient object to publish data on a topic. The publish() method accepts the following arguments, in order:
- MQTT topic (const char*)
- QoS (uint8_t): quality of service – it can be 0, 1 or 2
- retain flag (bool): retain flag
- payload (const char*) – in this case, the payload corresponds to the sensor reading
The QoS (quality of service) is a way to guarantee that the message is delivered. It can be one of the following levels:
- 0: the message will be delivered once or not at all. The message is not acknowledged. There is no possibility of duplicated messages;
- 1: the message will be delivered at least once, but may be delivered more than once;
- 2: the message is always delivered exactly once;
- Learn about MQTT QoS.
Uploading the code
With your Raspberry Pi powered on and running the Mosquitto MQTT broker, upload the code to your ESP32.
Open the Serial Monitor at a baud rate of 115200 and you’ll see that the ESP32 starts publishing messages on the topics we’ve defined previously.
Preparing Node-RED Dashboard
The ESP32 is publishing sensor readings every 10 seconds on four MQTT topics. Now, you can use any dashboard that supports MQTT or any other device that supports MQTT to subscribe to those topics and receive the readings.
As an example, we’ll create a simple flow using Node-RED to subscribe to those topics and display the readings on gauges.
If you don’t have Node-RED installed, follow the next tutorials:
- Getting Started with Node-RED on Raspberry Pi
- Installing and Getting Started with Node-RED Dashboard
Having Node-RED running on your Raspberry Pi, go to your Raspberry Pi IP address followed by :1880.
http://raspberry-pi-ip-address:1880
The Node-RED interface should open. Drag four MQTT in nodes, two gauge nodes, and two text field nodes to the flow.
Click the MQTT node and edit its properties.
The Server field refers to the MQTT broker. In our case, the MQTT broker is the Raspberry Pi, so it is set to localhost:1883. If you’re using a Cloud MQTT broker, you should change that field.
Insert the topic you want to be subscribed to and the QoS. This previous MQTT node is subscribed to the esp/bme680/temperature topic.
Click on the other MQTT in nodes and edit its properties with the same server, but for the other topics: esp/bme680/humidity, esp/bme680/pressure, and esp/bme680/gas.
Click on the gauge nodes and edit its properties for each reading. The following node is set for the temperature readings. Edit the other chart nodes for the humidity readings.
Wire your nodes as shown below:
Finally, deploy your flow (press the button on the upper right corner).
Alternatively, you can go to Menu > Import and copy the following to your Clipboard to create your Node-RED flow.
[{"id":"3b7f947c.9759ec","type":"mqtt in","z":"254c9c97.f85b34","name":"","topic":"esp/bme680/temperature","qos":"1","datatype":"auto","broker":"8db3fac0.99dd48","x":470,"y":2640,"wires":[["b87b21c3.96672"]]},{"id":"b87b21c3.96672","type":"ui_gauge","z":"254c9c97.f85b34","name":"","group":"37de8fe8.46846","order":2,"width":0,"height":0,"gtype":"gage","title":"Temperature","label":"ºC","format":"{{value}}","min":0,"max":"40","colors":["#00b500","#f7df09","#ca3838"],"seg1":"","seg2":"","x":690,"y":2640,"wires":[]},{"id":"f92248f4.545778","type":"mqtt in","z":"254c9c97.f85b34","name":"","topic":"esp/bme680/humidity","qos":"1","datatype":"auto","broker":"8db3fac0.99dd48","x":460,"y":2700,"wires":[["4114a401.5ac69c"]]},{"id":"4114a401.5ac69c","type":"ui_gauge","z":"254c9c97.f85b34","name":"","group":"37de8fe8.46846","order":2,"width":0,"height":0,"gtype":"gage","title":"Humidity","label":"%","format":"{{value}}","min":"30","max":"100","colors":["#53a4e6","#1d78a9","#4e38c9"],"seg1":"","seg2":"","x":680,"y":2700,"wires":[]},{"id":"ad51f895.2c2848","type":"mqtt in","z":"254c9c97.f85b34","name":"","topic":"esp/bme680/pressure","qos":"1","datatype":"auto","broker":"8db3fac0.99dd48","x":460,"y":2760,"wires":[["3a95123b.66405e"]]},{"id":"c074e688.198b78","type":"mqtt in","z":"254c9c97.f85b34","name":"","topic":"esp/bme680/gas","qos":"1","datatype":"auto","broker":"8db3fac0.99dd48","x":440,"y":2820,"wires":[["d3539c06.00a17"]]},{"id":"3a95123b.66405e","type":"ui_text","z":"254c9c97.f85b34","group":"37de8fe8.46846","order":2,"width":0,"height":0,"name":"","label":"Pressure","format":"{{msg.payload}} hPa","layout":"row-spread","x":680,"y":2760,"wires":[]},{"id":"d3539c06.00a17","type":"ui_text","z":"254c9c97.f85b34","group":"37de8fe8.46846","order":3,"width":0,"height":0,"name":"","label":"Gas","format":"{{msg.payload}} KOhm","layout":"row-spread","x":670,"y":2820,"wires":[]},{"id":"8db3fac0.99dd48","type":"mqtt-broker","z":"","name":"","broker":"localhost","port":"1883","clientid":"","usetls":false,"compatmode":false,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""},{"id":"37de8fe8.46846","type":"ui_group","z":"","name":"BME680","tab":"53b8c8f9.cfbe48","order":1,"disp":true,"width":"6","collapse":false},{"id":"53b8c8f9.cfbe48","type":"ui_tab","z":"","name":"Home","icon":"dashboard","order":5,"disabled":false,"hidden":false}]
Demonstration
Go to your Raspberry Pi IP address followed by :1880/ui.
http://raspberry-pi-ip-address:1880/ui
You should get access to the current BME680 sensor readings on the Dashboard. You can use other dashboard-type nodes to display the readings on different ways.
That’s it! You have your ESP32 board publishing BME680 temperature, humidity, pressure and gas resistance readings to Node-RED via MQTT.
Wrapping Up
MQTT is a great communication protocol to exchange small amounts of data between devices. In this tutorial you’ve learned how to publish temperature, humidity, pressure and gas resistance readings from a BME680 environmental sensor with the ESP32 to different MQTT topics. Then, you can use any device or home automation platform to subscribe to those topics and receive the readings.
Instead of a BME680 sensor, you can use any other sensor like a DS18B20 temperature sensor, a DHT22 temperature and humidity sensor or a BME280 temperature, humidity and pressure sensor:
- ESP32 MQTT – Publish DS18B20 Temperature Readings
- ESP32 MQTT – Publish DHT22/DHT11 Sensor Readings
- ESP32 MQTT – Publish BME280 Sensor Readings
We hope you’ve found this tutorial useful. If you want to learn more about the ESP32, take a look at our resources:
- Learn ESP32 with Arduino IDE
- MicroPython Programming with ESP32 and ESP8266
- More ESP32 Projects and Tutorials…
Thanks for reading.
What would be a wind sensor?
Cool! I think I’ll have to get one of those sensors and add this to my dashboard.
Bob
Just completed this project using a local raspberry PI3 host. Worked beautifully without any issues. Excellent tutorial. I now have a platform for all my home automation projects. Thanks Rui and Sara, much appreciated !
That’s great! 🙂
A great tutorial (like all others there). I love tghe step to step explanation…
BUT: This time i am lost in space…. 🙁
extern “C” {
#include “freertos/FreeRTOS.h”
#include “freertos/timers.h”
}
Thoose libs are not there – and when searching I found some RTOS Libs. Most of them for other Controler – and as I remember RTOS is near the HW.
So would be nice to get a little bit help – Google and a lot of Try&Error didnt help
Hi.
You don’t need to include any of those libraries.
Regards,
Sara
Hi sara thanks for your useful tutorials, if we have many bme680 sensors for example 4 sensor how can we add them to the mqtt topics without collision, thanks
Hi, I did all the procedure, but I get the follow message from node-red :
/18/2022, 1:18:01 PMnode: 97475046264e45c3
PR : msg : Object
object
topic: “PR”
payload: “”
qos: 1
retain: false
_topic: “PR”
_msgid: “03f9c199882f566e
The payload without value just payload: “”
It seems the message from mqtt comes in a different position!
Its necessary to do something on node-red do read the correct payload.
Obs. I modified the entrance sensor for others.
14:06:53.123 -> Publishing on topic PR at QoS 1, packetId: 0Message: 65.13
14:06:53.123 -> Publishing on topic PA at QoS 1, packetId 0: Message: 65.17
14:06:53.123 -> Publishing on topic FP at QoS 1, packetId 0: Message: 1.00
14:06:53.123 -> Publishing on topic V at QoS 1, packetId 0: Message: 55.95
14:06:53.123 -> Publishing on topic C at QoS 1, packetId 0: Message: 1.16
Hi.
I’m sorry, but I’m not sure I understand your issue.
Can you provide more details?
If you change your topics, you also need to change them on the MQTT In nodes.
Regards,
Sara
Hi! Thank you for this tutorial! I would like to use an ESP32-S2-Saola-1 with BME680.
However, there is no GPIO22 on the ESP32-S2-Saola-1 and also GPIO21 seems to have a different function than SDA. Is there somewhere to define whether I use I2C or SPI and which pins I connect? In the ESP32-S2-Saola-1 pinout plan, SDA is specified on GPIO8 and SCL on GPIO9. This ESP even has 2x I2C, where do you define which one to use?
I would appreciate any hints on where to connect the BME680 on the ESP32-S2-Saola-1.
Hi.
Check this guide that shows how to use I2C custom pins: https://randomnerdtutorials.com/esp32-i2c-communication-arduino-ide/
I hope this helps.
Regards,
Sara
High Sara,
by now I have to include
#include <AsyncMqttClient_Generic.hpp>
instead of
#include <AsyncMqttClient.h>
maybe they changed only the foilename
Yours Klaus
Hi Guys! I’m about to start this project but I’m confused about the RaspberryPi would I have to use the board or how? Suggestions required.
Hi.
To use MQTT, you need an MQTT broker.
In this specific project, we’re using the MQTT mosquito broker installed on a Raspberry Pi.
You can check the following guides to learn how to get started with Raspberry Pi, MQTT, and how to install the MQTT mosquito broker on the Pi.
– Getting Started with Raspberry Pi
What is MQTT and How It Works
Install Mosquitto MQTT Broker on Raspberry Pi
If you don’t want to use a Raspberry Pi, you can install the broker on your computer, for example, or use a cloud broker.
I hope this helps.
Regards,
Sara
Hello I’m making this project but my sensor is BME688 so can I use the same libraries as mentioned in the project or is it different? If it’s different can you please tell me what libraries I can use for my BME688 sensor.
hi, guys
great tutorial. just wondering if you can add subscribes example using this mqtt asynchrony library to turn on led or something? if it’s possible.
thanks a lot guys
regards
Hi.
You can see the code example in this tutorial. It subscribes to an MQTT topic to control the outputs: https://randomnerdtutorials.com/esp32-big-timer-node-red/
I hope this helps.
Regards,
Sara
Good morning Rui and Sara I’m using esp32 with bme280 which also gives me altitude, but when I go to write the altitude field the value corresponds to this:
MQTT Topic: esp32/altitudine
Data: b”\xf0\xaa\xfc?\xac:\xfc?’\xe3\xc8\xa5\x807\xfc?|<\xfc?\x847\xfc?\x01″
Could you kindly help me decode the altitude field correctly so that I can insert it correctly into the MYSQL db.
Thanks for existing
Best regards
Hi.
How do you get the altitude?
Regards,
Sara
All of my systems using esp32 & mqtt have crashed. Node red mqtt nodes showing connected, all esp32 connected to wifi. Both systems transmitting but not receiving. Also esp now system crashed.
Any solutions or experiencing same problem ?