ESP32: BME680 Environmental Sensor using Arduino IDE (Gas, Pressure, Humidity, Temperature)

The BME680 is an environmental digital sensor that measures gas, pressure, humidity and temperature. In this guide you’ll learn how to use the BME680 sensor module with the ESP32 board using Arduino IDE. The sensor communicates with a microcontroller using I2C or SPI communication protocols.

ESP32 BME680 Gas sensor humidity barometric pressure ambient temperature gas air quality Arduino IDE

You’ll learn how to wire the sensor to the ESP32 board, install the required libraries, use a simple sketch to display the sensor readings in the Serial Monitor and build a web server to monitor your sensor remotely.

Introducing BME680 Environmental Sensor Module

The BME680 is an environmental sensor that combines gas, pressure, humidity and temperature sensors. The gas sensor can detect a broad range of gases like volatile organic compounds (VOC). For this reason, the BME680 can be used in indoor air quality control.

BME680 Gas sensor humidity barometric pressure ambient temperature gas air quality front

BME680 Measurements

The BME680 is a 4-in-1 digital sensor that measures:

  • Temperature
  • Humidity
  • Barometric pressure
  • Gas: Volatile Organic Compounds (VOC) like ethanol and carbon monoxide

Gas Sensor

The BME680 contains a MOX (Metal-oxide) sensor that detects VOCs in the air. This sensor gives you a qualitative idea of the sum of VOCs/contaminants in the surrounding air – it is not specific for a specific gas molecule.

MOX sensors are composed of a metal-oxide surface, a sensing chip to measure changes in conductivity, and a heater. It detects VOCs by adsorption of oxygen molecules on its sensitive layer. The BME680 reacts to most VOCs polluting indoor air (except CO2).

When the sensor comes into contact with the reducing gases, the oxygen molecules react and increase the conductivity across the surface. As a raw signal, the BME680 outputs resistance values. These values change due to variations in VOC concentrations:

BME680 Gas Environmental Air Quality Sensor Resistance How It Works
  • Higher concentration of VOCs » Lower resistance
  • Lower concentration of VOCs » Higher resistance

The reactions that occur on the sensor surface (thus, the resistance) are influenced by parameters other than VOC concentration like temperature and humidity.

Relevant Information Regarding Gas Sensor

The gas sensor gives you a qualitative idea of VOCs gasses in the surrounding air. So, you can get trends, compare your results and see if the air quality is increasing or decreasing. To get precise measurements, you need to calibrate the sensor against knows sources and build a calibration curve.

When you first get the sensor, it is recommended to run it for 48 hours after start collecting “real” data. After that, it is also recommend to run the sensor for 30 minutes before getting a gas reading.

BME680 Accuracy

Here’s the accuracy of the temperature, humidity and pressure sensors of the BME680:

SensorAccuracy
Temperature+/- 1.0ºC
Humidity+/- 3%
Pressure+/- 1 hPa

BME680 Operation Range

The following table shows the operation range for the temperature, humidity and pressure sensors for the BME680.

SensorOperation Range
Temperature-40 to 85 ºC
Humidity0 to 100 %
Pressure300 to 1100 hPa

BME680 Pinout

Here’s the BME680 Pinout:

VCCPowers the sensor
GNDCommon GND
SCLSCL pin for I2C communication
SCK pin for SPI communication
SDASDA pin for I2C communication
SDI (MOSI) pin for SPI communication
SDOSDO (MISO) pin for SPI communication
CSChip select pin for SPI communication

BME680 Interface

The BME680 supports I2C and SPI Interfaces.

BME680 Gas sensor humidity barometric pressure ambient temperature gas air quality back

BME680 I2C

To use I2C communication protocol, use the following pins:

BME680ESP32
SCLGPIO22
SDAGPIO 21

GPIO 22 (SCL) and GPIO 21 (SDA) are the default ESP32 I2C pins. You can use other pins as long as you set them properly on code.

Recommended reading: ESP32 I2C Communication: Set Pins, Multiple Bus Interfaces and Peripherals (Arduino IDE)

BME680 SPI

To use SPI communication protocol, use the following pins:

BME680ESP32
SCL (SCK SPI Clock)GPIO 18
SDA (SDI MOSI)GPIO 23
SDO (MISO)GPIO 19
CS (Chip Select)GPIO 5

These are the default ESP32 SPI pins. You can use other pins as long as you set them properly in the code.

Parts Required

ESP32 Board BME680 Gas sensor circuit wiring diagram schematics

To complete this tutorial you need the following parts:

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 – ESP32 with BME680

The BME680 can communicate using I2C or SPI communication protocols.

ESP32 with BME680 using I2C

Follow the next schematic diagram to wire the BME680 to the ESP32 using the default I2C pins.

ESP32 BME680 Wiring Diagram I2C

ESP32 with BME680 using SPI

Alternatively, you may want to use SPI communication protocol instead. In that case, follow the next schematic diagram to wire the BME680 to the ESP32 using the default SPI pins.

ESP32 BME680 Wiring Diagram SPI

Recommended reading: ESP32 Pinout Reference: Which GPIO pins should you use?

Preparing Arduino IDE

We’ll program the ESP32 board using Arduino IDE. So, make sure you have the ESP32 add-on installed. Follow the next tutorial:

You also need to install the Adafruit BME680 library and the Adafruit Unified Sensor library.

Installing the BME680 Library

To get readings from the BME680 sensor module we’ll use the Adafruit_BME680 library. Follow the next steps to install the library in your Arduino IDE:

Open your Arduino IDE and go to Sketch Include Library > Manage Libraries. The Library Manager should open.

Search for “adafruit bme680 ” on the Search box and install the library.

Install BM6280 Adafruit Library Arduino IDE Library Manager

Installing the Adafruit_Sensor Library

To use the BME680 library, you also need to install the Adafruit_Sensor library. Follow the next steps to install the library in your Arduino IDE:

Go to Sketch Include Library > Manage Libraries and type “Adafruit Unified Sensor” in the search box. Scroll all the way down to find the library and install it.

Installing Adafruit Unified Sensor Driver library

After installing the libraries, restart your Arduino IDE.

Code – Reading BME680 Gas, Pressure, Humidity and Temperature

To read gas, pressure, temperature, and humidity we’ll use a sketch example from the library.

After installing the BME680 library, and the Adafruit_Sensor library, open the Arduino IDE and, go to File > Examples > Adafruit BME680 Library > bme680async.

/***
  Read Our Complete Guide: https://RandomNerdTutorials.com/esp32-bme680-sensor-arduino/
  Designed specifically to work with the Adafruit BME680 Breakout ----> http://www.adafruit.com/products/3660 These sensors use I2C or SPI to communicate, 2 or 4 pins are required to interface. Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! Written by Limor Fried & Kevin Townsend for Adafruit Industries. BSD license, all text above must be included in any redistribution
***/

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"

/*#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme; // I2C
//Adafruit_BME680 bme(BME_CS); // hardware SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);

void setup() {
  Serial.begin(115200);
  while (!Serial);
  Serial.println(F("BME680 async test"));

  if (!bme.begin()) {
    Serial.println(F("Could not find a valid BME680 sensor, check wiring!"));
    while (1);
  }

  // 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() {
  // Tell BME680 to begin measurement.
  unsigned long endTime = bme.beginReading();
  if (endTime == 0) {
    Serial.println(F("Failed to begin reading :("));
    return;
  }
  Serial.print(F("Reading started at "));
  Serial.print(millis());
  Serial.print(F(" and will finish at "));
  Serial.println(endTime);

  Serial.println(F("You can do other work during BME680 measurement."));
  delay(50); // This represents parallel work.
  // There's no need to delay() until millis() >= endTime: bme.endReading()
  // takes care of that. It's okay for parallel work to take longer than
  // BME680's measurement time.

  // Obtain measurement results from BME680. Note that this operation isn't
  // instantaneous even if milli() >= endTime due to I2C/SPI latency.
  if (!bme.endReading()) {
    Serial.println(F("Failed to complete reading :("));
    return;
  }
  Serial.print(F("Reading completed at "));
  Serial.println(millis());

  Serial.print(F("Temperature = "));
  Serial.print(bme.temperature);
  Serial.println(F(" *C"));

  Serial.print(F("Pressure = "));
  Serial.print(bme.pressure / 100.0);
  Serial.println(F(" hPa"));

  Serial.print(F("Humidity = "));
  Serial.print(bme.humidity);
  Serial.println(F(" %"));

  Serial.print(F("Gas = "));
  Serial.print(bme.gas_resistance / 1000.0);
  Serial.println(F(" KOhms"));

  Serial.print(F("Approx. Altitude = "));
  Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
  Serial.println(F(" m"));

  Serial.println();
  delay(2000);
}

View raw code

We’ve made a few changes to the sketch to make it fully compatible with the ESP32.

How the Code Works

Continue reading this section to learn how the code works, or skip to the Demonstration section.

Libraries

The code starts by including the needed libraries: the wire library to use I2C, the SPI library (if you want to use SPI instead of I2C), the Adafruit_Sensor and Adafruit_BME680 libraries to interface with the BME680 sensor.

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"

SPI communication

We prefer to use I2C communication protocol with the sensor. However, the code is prepared if you want to use SPI. You just need to uncomment the following lines of code that define the SPI pins.

/*#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 15*/

Sea level pressure

A variable called SEALEVELPRESSURE_HPA is created.

#define SEALEVELPRESSURE_HPA (1013.25)

This variable saves the pressure at the sea level in hectopascal (is equivalent to milibar). This variable is used to estimate the altitude for a given pressure by comparing it with the sea level pressure. This example uses the default value, but for accurate results, replace the value with the current sea level pressure at your location.

I2C

This example uses I2C communication protocol by default. The following line creates an Adafruit_BME680 object called bme on the default ESP32 I2C pins: GPIO 22 (SCL), GPIO 21 (SDA).

Adafruit_BME680 bme; // I2C

To use SPI, you need to comment this previous line and uncomment the following line.

//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK); // software SPI

setup()

In the setup() start a serial communication.

Serial.begin(115200);

Init BME680 Sensor

Initialize the BME680 sensor:

if (!bme.begin()) {
  Serial.println(F("Could not find a valid BME680 sensor, check wiring!"));
  while (1);
}

Set up the following parameters (oversampling, filter and gas heater) for the sensor.

// 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

To increase the resolution of the raw sensor data, it supports oversampling. We’ll use the default oversampling parameters, but you can change them.

  • setTemperatureOversampling(): set temperature oversampling.
  • setHumidityOversampling(): set humidity oversampling.
  • setPressureOversampling(): set pressure oversampling.

These methods can accepts one of the following parameters:

  • BME680_OS_NONE: turn off reading;
  • BME680_OS_1X
  • BME680_OS_2X
  • BME680_OS_4X
  • BME680_OS_8X
  • BME680_OS_16X

The BME680 sensor integrates an internal IIR filter to reduce short-term changes in sensor output values caused by external disturbances. The setIIRFilterSize() method sets the IIR filter. It accepts the filter size as a parameter:

  • BME680_FILTER_SIZE_0 (no filtering)
  • BME680_FILTER_SIZE_1
  • BME680_FILTER_SIZE_3
  • BME680_FILTER_SIZE_7
  • BME680_FILTER_SIZE_15
  • BME680_FILTER_SIZE_31
  • BME680_FILTER_SIZE_63
  • BME680_FILTER_SIZE_127

The gas sensor integrates a heater. Set the heater profile using the setGasHeater() method that accepts as arguments:

  • the heater temperature (in degrees Centigrade)
  • the time the heater should be on (in milliseconds)

We’ll use the default settings: 320 ºC for 150 ms.

loop()

In the loop(), we’ll get measurements from the BME680 sensor.

First, tell the sensor to start an asynchronous reading with bme.beginReading(). This returns the time when the reading would be ready.

// Tell BME680 to begin measurement.
unsigned long endTime = bme.beginReading();
if (endTime == 0) {
  Serial.println(F("Failed to begin reading :("));
  return;
}
Serial.print(F("Reading started at "));
Serial.print(millis());
Serial.print(F(" and will finish at "));
Serial.println(endTime);

Then, call the endReading() method to end an asynchronous reading. If the asynchronous reading is still in progress, block until it ends.

if (!bme.endReading()) {
  Serial.println(F("Failed to complete reading :("));
  return;
}

After this, we can get the readings as follows:

  • bme.temperature: returns temperature reading
  • bme.pressure: returns pressure reading
  • bme.humidity: returns humidity reading
  • bme.gas_resistance: returns gas resistance
Serial.print(F("Temperature = "));
Serial.print(bme.temperature);
Serial.println(F(" *C"));

Serial.print(F("Pressure = "));
Serial.print(bme.pressure / 100.0);
Serial.println(F(" hPa"));

Serial.print(F("Humidity = "));
Serial.print(bme.humidity);
Serial.println(F(" %"));

Serial.print(F("Gas = "));
Serial.print(bme.gas_resistance / 1000.0);
Serial.println(F(" KOhms"));

Serial.print(F("Approx. Altitude = "));
Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
Serial.println(F(" m"));

For more information about the library methods, take a look at the Adafruit_BME680 Class Reference.

Demonstration

Upload the code to your ESP32 board. Go to Tools > Board and select the ESP32 board you’re using. Go to Tools > Port and select the port your board is connected to. Then, click the upload button.

Open the Serial Monitor at a baud rate of 115200, press the on-board RST button. The sensor measurements will be displayed.

BME680 Arduino IDE Example Display Gas Temperature Humidity and Pressure Readings Serial Monitor

Code – ESP32 Web Server with BME680

In this section, we provide an example of web server that you can build with the ESP32 to display BME680 readings.

ESP32 BME680 Gas sensor Web Server Demonstration

Installing Libraries – Async Web Server

To build the web server you need to install the following libraries. Click the links below to download the libraries.

These libraries aren’t available to install through the Arduino Library Manager, so you need to copy the library files to the Arduino Installation Libraries folder. Alternatively, in your Arduino IDE, you can go to Sketch Include Library > Add .zip Library and select the libraries you’ve just downloaded.

Code

Then, upload the following code to your board (type your SSID and password).

/*********
  Rui Santos
  Complete project details at https://RandomNerdTutorials.com/esp32-bme680-sensor-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 <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#include <WiFi.h>
#include "ESPAsyncWebServer.h"

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

//Uncomment if using SPI
/*#define BME_SCK 18
#define BME_MISO 19
#define BME_MOSI 23
#define BME_CS 5*/

Adafruit_BME680 bme; // I2C
//Adafruit_BME680 bme(BME_CS); // hardware SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO, BME_SCK);

float temperature;
float humidity;
float pressure;
float gasResistance;

AsyncWebServer server(80);
AsyncEventSource events("/events");

unsigned long lastTime = 0;  
unsigned long timerDelay = 30000;  // send readings timer

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;
}

String processor(const String& var){
  getBME680Readings();
  //Serial.println(var);
  if(var == "TEMPERATURE"){
    return String(temperature);
  }
  else if(var == "HUMIDITY"){
    return String(humidity);
  }
  else if(var == "PRESSURE"){
    return String(pressure);
  }
 else if(var == "GAS"){
    return String(gasResistance);
  }
}

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <title>BME680 Web Server</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
  <link rel="icon" href="data:,">
  <style>
    html {font-family: Arial; display: inline-block; text-align: center;}
    p {  font-size: 1.2rem;}
    body {  margin: 0;}
    .topnav { overflow: hidden; background-color: #4B1D3F; color: white; font-size: 1.7rem; }
    .content { padding: 20px; }
    .card { background-color: white; box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5); }
    .cards { max-width: 700px; margin: 0 auto; display: grid; grid-gap: 2rem; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr)); }
    .reading { font-size: 2.8rem; }
    .card.temperature { color: #0e7c7b; }
    .card.humidity { color: #17bebb; }
    .card.pressure { color: #3fca6b; }
    .card.gas { color: #d62246; }
  </style>
</head>
<body>
  <div class="topnav">
    <h3>BME680 WEB SERVER</h3>
  </div>
  <div class="content">
    <div class="cards">
      <div class="card temperature">
        <h4><i class="fas fa-thermometer-half"></i> TEMPERATURE</h4><p><span class="reading"><span id="temp">%TEMPERATURE%</span> &deg;C</span></p>
      </div>
      <div class="card humidity">
        <h4><i class="fas fa-tint"></i> HUMIDITY</h4><p><span class="reading"><span id="hum">%HUMIDITY%</span> &percnt;</span></p>
      </div>
      <div class="card pressure">
        <h4><i class="fas fa-angle-double-down"></i> PRESSURE</h4><p><span class="reading"><span id="pres">%PRESSURE%</span> hPa</span></p>
      </div>
      <div class="card gas">
        <h4><i class="fas fa-wind"></i> GAS</h4><p><span class="reading"><span id="gas">%GAS%</span> K&ohm;</span></p>
      </div>
    </div>
  </div>
<script>
if (!!window.EventSource) {
 var source = new EventSource('/events');
 
 source.addEventListener('open', function(e) {
  console.log("Events Connected");
 }, false);
 source.addEventListener('error', function(e) {
  if (e.target.readyState != EventSource.OPEN) {
    console.log("Events Disconnected");
  }
 }, false);
 
 source.addEventListener('message', function(e) {
  console.log("message", e.data);
 }, false);
 
 source.addEventListener('temperature', function(e) {
  console.log("temperature", e.data);
  document.getElementById("temp").innerHTML = e.data;
 }, false);
 
 source.addEventListener('humidity', function(e) {
  console.log("humidity", e.data);
  document.getElementById("hum").innerHTML = e.data;
 }, false);
 
 source.addEventListener('pressure', function(e) {
  console.log("pressure", e.data);
  document.getElementById("pres").innerHTML = e.data;
 }, false);
 
 source.addEventListener('gas', function(e) {
  console.log("gas", e.data);
  document.getElementById("gas").innerHTML = e.data;
 }, false);
}
</script>
</body>
</html>)rawliteral";

void setup() {
  Serial.begin(115200);

  // Set the device as a Station and Soft Access Point simultaneously
  WiFi.mode(WIFI_AP_STA);
  
  // Set device as a Wi-Fi Station
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Setting as a Wi-Fi Station..");
  }
  Serial.print("Station IP Address: ");
  Serial.println(WiFi.localIP());
  Serial.println();

  // Init BME680 sensor
  if (!bme.begin()) {
    Serial.println(F("Could not find a valid BME680 sensor, check wiring!"));
    while (1);
  }
  // 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

  // Handle Web Server
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });

  // Handle Web Server Events
  events.onConnect([](AsyncEventSourceClient *client){
    if(client->lastId()){
      Serial.printf("Client reconnected! Last message ID that it got is: %u\n", client->lastId());
    }
    // send event with message "hello!", id current millis
    // and set reconnect delay to 1 second
    client->send("hello!", NULL, millis(), 10000);
  });
  server.addHandler(&events);
  server.begin();
}

void loop() {
  if ((millis() - lastTime) > timerDelay) {
    getBME680Readings();
    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);
    Serial.println();

    // Send Events to the Web Server with the Sensor Readings
    events.send("ping",NULL,millis());
    events.send(String(temperature).c_str(),"temperature",millis());
    events.send(String(humidity).c_str(),"humidity",millis());
    events.send(String(pressure).c_str(),"pressure",millis());
    events.send(String(gasResistance).c_str(),"gas",millis());
    
    lastTime = millis();
  }
}

View raw code

Demonstration

After uploading, open the Serial Monitor at a baud rate of 115200 to get the ESP32 IP address.

Open a browser and type the IP address. You should get access to the web server with the latest sensor readings. You can access the web server on your computer, tablet or smartphone in your local network.

ESP32 or ESP8266 NodeMCU Board Web Server Demonstration with BME680 Gas sensor

The readings are updated automatically on the web server using Server-Sent Events.

We won’t explain how the web server works in this tutorial. We wrote this guide dedicated to the BME680 web server with the ESP32 board.

Wrapping Up

The BME680 sensor module is a 4-in-1 digital sensor that combines gas, pressure, temperature and humidity sensors. The BME680 contains a MOX sensor that senses the presence of most VOC gases. This sensor gives you a qualitative idea of the sum of VOCs/contaminants in the surrounding air. For this reason, the BME680 can be used to monitor indoor air quality.

If you’re using an ESP8266, read ESP8266 NodeMCU: BME680 Environmental Sensor using Arduino IDE (Gas, Pressure, Humidity, Temperature).

We hope you’ve found this getting started guide useful. We have guides for other popular sensors:

Learn more about the ESP32 with our resources:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Recommended Resources

Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

12 thoughts on “ESP32: BME680 Environmental Sensor using Arduino IDE (Gas, Pressure, Humidity, Temperature)”

  1. Hi,
    it seems that there is a conflict according description of SDA and SDO respectively MISO and MOSI in the table “BME680 Pinout”
    I think SDA must be MOSI and SDO must be MISO.

    Reply
  2. Hint For Others… I’ve been proposing to use a BMP280 to measure Supply Air Temperature and Duct (Air) Pressure in a ceiling mounted split air conditioning unit. Worked great on the bench BUT after using 6 meters of screened cable to the BMP280 & using I2C it would not work. Further research revealed a limit of maybe less than 1 meter of cable else I2C has lots of problems with SCA / SCL crosstalk. Fortunately I installed at the same time DS18B20 to measure air conditioning temperatures into and out of system and that works fine.
    I’m using this ESP8266-E12 as a sender for ESP-NOW and this works fine including a Bluetooth module to my smart phone etc… ENJOY

    Reply
  3. Hi guys,

    I’m using the AsyncEventSource to update automatically the readings form 12 sensors, but looks like only 8 of those values are updated automatically. Do you know if there’s any limit in the number of events that the handler can manage?

    Thanks!

    Reply
  4. Hi Sara.
    I made this project everything works but comparing whith several weather stations including my father weather station and all values are lower in esp32, i only cant get values for gas is there any way to change, there is a part of your explication where you speak abought altitude but not in code can this be a problem ? I made two projects of BME680 one for me other for my father and both with difeferent lectures and both low values.
    Thanks for your great projects and for your usual disponibility.

    Reply
  5. Do I need to do anything different to get this working with ESP32 Wroom and a PImoroni brand BME-688? I’ve tried the above as is but it can’t find the sensor

    Reply
      • Hi Sara,

        I realised there was a jumper on the back of the BME688 that changes the i2c address. I cut this jumper, and the module works with this code now!

        Reply
  6. Hello, very nice work.I did this and it works great.But I want to know if you can still make me a library from BME680 with : BME 680, CCU-811 , MH-Z19 , SPS30 , SHT3x.
    With ESP32-S3.
    As it is with the web interface, plus a TFT SPI Display, would it be a lot of work?
    I would pay for the code, as long as it is not so expensive.
    It’s a hobby for me.
    Thank You.

    Reply

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.