BME680 with ESP8266 NodeMCU using Arduino IDE (Gas, Pressure, Temperature, Humidity)

In this tutorial, we will learn to interface the BME680 sensor with ESP8266 NodeMCU using Arduino IDE. The BME680 environmental sensor, which is used to measure ambient temperature, barometric pressure, relative humidity, and gas (VOC) or Indoor air quality (IAQ). We will learn how to interface it with ESP8266 NodeMCU using Arduino core programming. For demonstration, firstly, we will a simple Arduino IDE code for reading the BME680 sensor data and displaying it on the serial monitor of Arduino IDE. Furthermore, we will also see an example to display BME680 sensor readings on an OLED display.

BME680 with ESP8266 NodeMCU and OLED Arduino IDE

Prerequisites

Before we start this lesson make sure you are familiar with and have the latest version of Arduino IDE installed and also have ESP8266 NodeMCU add-on installed in Arduino IDE:

Install ESP8266 add-on in Arduino IDE

BME680 Introduction

BME680 is a four in one low power-driven sensor, which has integrated temperature, pressure, humidity and gas detection sensors. It runs on an operating voltage of 1.8-3.8V and communicates with other microcontrollers through I2C and SPI protocol. This sensor is used in areas such as tracking the quality of air, humidity indicators, weather trends, home automation and controlling and GPS enhancements.

Operating Range and Accuracy

Some key features of BME680 include:

  • Temperature measurement: measures the ambient temperature with an accuracy of ±1.0°C and an operating range of -40 to 85 ºC.
  • Relative Humidity measurement: measures relative humidity with a fast response rate and an accuracy of ±3% and an operating range of 0-100%.
  • Pressure measurement: measures barometric pressure with ±1 hPa absolute accuracy and altitude with an accuracy of ±1 meter. The operating range of pressure ranges from 300-1100 hPa.
AccuracyOperating Range
Temperature±1.0°C-40 to 85 ºC
Humidity±3%0-100%
Pressure±1 hPa300-1100 hPa
  • Gas measurement: detects a wide range of gases including volatile organic compounds (VOCs) thus determining the indoor air quality.
  • Due to its compact size and low power operation, it is suitable in mobile applications, smartwatches, and navigation systems.

As compared to BME280, BME680 is a unique and updated sensor in the sense that it contains a small-sized MOX (metal oxide) sensor.

Gas Sensor

BME680 sensor can determine the number of pollutants/VOCs in the environment such as carbon monoxide, Ethane, Isoprene /2-methyl-1,3 Butadiene, Acetone, and Ethanol. The VOCs are detected by the adsorption of oxygen molecules onto the metal oxide layer. Its actual detection is done by the principle of changing the resistance of the MOX sensor. Whenever the MOX gets in contact with a pollutant in the air, the resistance of the sensor changes with the concentration of the pollutants present. This means that the higher number of pollutants in the air leads to significantly lower resistance of the sensor. Likewise, with the lower concentration of VOCs in the air, the resistance of the sensor is significantly higher.

bme680 gas sensor resistance output and working

Note: The BME680 gas sensor is not a CO2 or ethanol measurement sensor. It gets the relative idea of CO2 from VOC in the air But we can not use it for direct measurement of CO2.

Like all other gas sensors, BME680 also gives variable results each time. To ensure greater accuracy, we have to calibrate it against a known source and then plot its curve. As the sensitivity levels are not constant during the initial use of the sensor, it is initially recommended to run it for forty-eight hours which can later be tuned down to thirty minutes before each use.

BME680 Modules

Several types of BME680 sensors with different sizes and numbers of terminals are available in the market. But all modules provide data through SPI and I2C interfaces and we can use the same Arduino sketch to get sensor readings. Some of them are shown below:

different bme680 sensor modules
BME680 Sensor Modules

You can choose the module according to your convenience and the type of microcontroller you want to connect it with. In this article, we will use the BME680 sensor with 6 terminals, which is shown below. It has 4 SPI and two I2C terminals.

Pinout Diagram

The following figure shows the pinout of BME680 sensor:

bme680 pinout
BME680 Pinout
Pin NameDescription
VCCThis pin powers up the sensor.
GNDThis is the common ground pin for power and logic.
SCLWhen using I2C protocol this pin acts as SCL or serial clock pin and when using SPI protocol this pin acts as SCK or the serial pin for SPI. It is the input to the chip.
SDAWhen using I2C protocol this pin acts as SDA or Serial Data pin and when using SPI protocol this pin acts as SDI or Serial Data In also known as MOSI (‘Master out Slave in’). This is used as the I2C/SPI input to the sensor.
SDOThis is the SDO (Slave data out) /MISO (Master in slave out) pin for SPI communication. This pin is used as the SPI output from the sensor.
CSThis is the Chip Select pin used in SPI communication. Acts as an input to the sensor.

BME680 I2C and SPI Interface

In this section, we will see how to interface the BME680 sensor module with ESP8266 NodeMCU. As discussed earlier, the BME680 offers two interfaces such as I2C and SPI. We can use either the SPI or I2C interface to connect a sensor with the ESP8266 NodeMCU. We will show the connections for both scenarios in the next section.

I2C Interface with ESP8266 NodeMCU

If you want to interface the BME680 sensor with ESP8266 NodeMCU using the I2C interface, you should make the connections of the ESP8266 NodeMCU board according to these SCL and SDA pins.

BME680ESP8266 NodeMCU
VCC VCC=3.3V
GNDGND
SCLGPIO5
SDAGPIO4

Connect the VCC pin of ESP8266 NodeMCU with the 3.3V VCC pin of the module to power up. Both grounds of the two devices will be connected in common. The SCL pin of BME680 will be connected with the default SCL pin of ESP8266 NodeMCU. Likewise, the SDA pin will be connected with the default SDA pin of ESP8266 NodeMCU.

Note: If we use other GPIO pins of ESP8266 NodeMCU for I2C communication, we can define other pins inside our Arduino sketch. We don’t have to use default I2C pins.

ESP8266 NodeMCU I2C Pins

The I2C pins stated above are set in default. If we want to change the GPIO pins we have to set them in code. The diagrams below show the pinout for the ESP8266 NodeMCU.

ESP8266 I2C Pins
ESP8266 NodeMCU I2C Pins

More information on ESP8266 NodeMCU pins is available here:

ESP8266 GPIO Pins

SPI Interface with ESP8266 NodeMCU

If you want to interface the BME680 sensor with ESP8266 NodeMCU using the SPI interface, you should make the connections of ESP8266 NodeMCU with the sensor according to these MOSI, MISO, and SCK pins. Because SPI protocol uses MOSI/SDI, MISO/SDO, and SCK pins.

BME680ESP8266 NodeMCU
VCCVCC=3.3V
GNDGND
SCL (SCK for SPI)GPIO14 (D5)
SDA (SDI / MOSI for SPI)GPIO13 (D7)
SDO / MISOGPIO12 (D6)
CSAny GPIO pin or GND

The VCC pin will be connected with the 3.3V from the ESP8266 NodeMCU module to power up. Both the grounds of the two devices will be connected in common. The SCL pin of BME680 will be connected with the default SCK/CLK pin of ESP8266 NodeMCU. Likewise, the SDA pin will be connected with the default MOSI pin of ESP8266 NodeMCU.  The SDO pin will be connected with the default MISO pin of ESP8266 NodeMCU and the CS pin of the sensor will also be connected with the default CS pin of ESP8266 NodeMCU.

Note: The above table lists the default SPI pins of ESP8266 NodeMCU. But if you want to use any other pins, you need to define them inside Arduino sketch

As you can see, we will use the default I2C and default SPI pins of the ESP8266 NodeMCU module to connect with the respective pins of the sensor. If you want to change the pins according to your preference that can be handled in the program code.

Which Interface to use? 

So far we have discussed SPI and I2C interfaces of BME680 and learned to interface the sensor with ESP8266 NodeMCU using both interfaces. But the question is which communication protocol should we use to get reading from BME680. As we have seen SPI requires four pins to communicate. On the contrary, I2C requires two pins. However, SPI is generally faster in speed as compared to I2C. Hence, it’s a tradeoff between speed and the number of pins. In short, it depends on your choice and application. We will use the I2C interface to get sensor readings with the default I2C pins of ESP8266 NodeMCU. 

Required Hardware

We will need the following components to connect our ESP8266 NodeMCU board with the BME680 sensor.

  1. ESP8266 NodeMCU
  2. BME680 Module
  3. Connecting Wires
  4. Breadboard
  5. 0.96 inch OLED Display

BME680 Connection Diagram with ESP8266 NodeMCU

In this tutorial, we will use the I2C pins of the BME680 sensor to interface with ESP8266. Therefore, follow the schematic diagram given below to make connections of ESP8266 NodeMCU with BME680 to interface through I2C communication.

bme680 with esp8266 nodemcu schematic diagram

Installing BME680 Library in Arduino

We will use Arduino IDE to program our ESP8266 NodeMCU board with BME680. Make sure you have the ESP8266 NodeMCU add on already installed before proceeding further.

Arduino comes up with an in-built library for BME680 which we will initiate. To use the functions of the BME680 library we will also be installing the ‘Adafruit_Sensor Library.’ Follow the steps to ensure the successful installation of the libraries.

  • In your Arduino IDE, click on Sketch > Include Library > Manage Library

The Library manager window will open up. In the search bar type ‘adafruit bme680.’ Click on the install button as shown.

Installing BME680 library in Arduino IDE

Now, we will install Adafruit_Sensor Library. Again, click on Sketch > Include Library > Manage Library.

Type ‘adafruit unified sensor’in the search bar and install the library which is shown in the blue box below.

Adafruit unified sensor library install

Arduino Code – Getting BME680 with ESP8266 NodeMCU on Arduino Serial Monitor

Let us look at a sketch example to display temperature, pressure, humidity and gas readings from the sensor module. After you have installed the libraries discussed above, restart your IDE and click on File > Examples > Adafruit BME680 Library > bme680async.

This will open up a new file titled bme680async which reads the sensor data and displays it on the serial monitor. You can view the code below:

#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 15*/

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

How the Code Works?

The code starts with including all the necessary libraries which are needed for the proper functionality of the code. Wire.h will allow us to communicate through the I2C protocol and SPI.h allows us to communicate through the SPI protocol. Both communication protocols are included. The Adafruit_Sensor and the Adafruit_BME680 libraries which we installed in Arduino IDE earlier are also included as they are necessary to interface with the sensor.

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

This code is using I2C protocol to communicate with ESP8266 NodeMCU and BME680. If you want to use SPI protocol instead, just uncomment the following block of code which defines the default pins:

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

Next, the code defines the SEALEVELPRESSURE_HPA by creating a variable by the set name. It takes into account the sea level pressure of your current location and compares it with a given pressure to estimate the altitude. You have to pass your sea-level pressure in hPa according to your location. 1013.25 is the value that is set in default.

#define SEALEVELPRESSURE_HPA (1013.25)

Then, it defines the Adafruit_BME680 object named ‘bme’ by setting it on the default I2C GPIO pins. If using SPI protocol instead, make sure to comment on this line and uncomment the lines which are initializing the SPI pins.

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

The setup() function is created. This initiates the serial communication at a baud rate of 115200 by using the begin() function.

Serial.begin(115200);

Then, the BME680 sensor gets initialized and in case of failure, an error message is printed on the serial monitor.

Serial.println(F("BME680 async test"));

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

The code then initializes some parameters including oversampling, gas heater and filter. It uses setTemperatureOversampling(), setHumidityOversampling() and setPressureOversampling() to initialize the oversampling for temperature, humidity and pressure respectively. This is being done so that a better resolution of the data could be obtained. Inside these methods, a single default argument is being passed which can be changed according to your preference.

All of these methods accept one of the following arguments. These indicate the different extents of oversampling which could be performed.

  1. BME680_OS_NONE: no reading
  2. BME680_OS_1X: default
  3. BME680_OS_2X: double oversampling
  4. BME680_OS_4X
  5. BME680_OS_8X
  6. ME680_OS_16X

The setIIRFilterSize() also takes in a single parameter which is the size of the filter. You can use any one of the following:

  1. BME680_FILTER_SIZE_0: no filter activated
  2. BME680_FILTER_SIZE_1
  3. BME680_FILTER_SIZE_3: this is the default size
  4. BME680_FILTER_SIZE_7
  5. BME680_FILTER_SIZE_15
  6. BME680_FILTER_SIZE_31
  7. BME680_FILTER_SIZE_63
  8. BME680_FILTER_SIZE_127

This internal infinite impulse response (IIR) filter is used to reduce the bandwidth of the sensor readings so that unnecessary changes caused by external disturbances could be significantly diminished. This is mainly used on temperature and pressure readings which fluctuate a lot and need low pass filtering.

The setGasHeater() configures a heater for gas measurement. It takes two parameters to initialize it. The first parameter is the target temperature for the heater which is set up as 32 degrees Celsius and the second parameter is the time duration set as 150ms. These are the default values but you can change them by passing appropriate parameters. You should note that the target temperature of the heater is 200-400 degrees Celsius and it takes approximately 30ms to reach the appropriate temperature. So, all this should be taken into account while setting us the parameters.

All of these five methods are being accessed through the bme object.

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

Inside the loop(), the code measures the sensor readings and displays them. The bme.beginReading() starts the reading process and prints the time when all the readings are acquired.

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

The bme.endReading() stops the reading process. It uses an if statement to print whether the sensor readings have all been read or not.

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

The readings are printed on the serial monitor by using bme.temperature, bme.pressure, bme.humidity and bme.gas_resistance. These measure ambient temperature, barometric pressure, relative humidity and gas respectively. The units are also displayed.

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

Demonstration

In Arduino IDE, click Tools > Board and select ESP8266 NodeMCU.

selecting ESP8266 NodeMCU in Arduino IDE

Now, click Tools > Port and choose the port which you are using. Now, upload the code by clicking on the upload button.

After you have uploaded the following code on your ESP8266 NodeMCU development board, press the ENABLE button as follows:

ESP8266 NodeMCU reset button

You will see the serial monitor displaying all the BME680 sensor readings such as Gas, Pressure, Temperature, Humidity as shown below:

getting BME680 sensor values on Arduino serial monitor ESP32

Displaying BME680 Sensor values on OLED Display with Arduino IDE

In this section, we will see how to display Gas, Pressure, Temperature, Humidity values on a 0.96 SSD1306 OLED display using ESP8266 NodeMCU and Arduino IDE. 

Installing SSD1306 OLED Library in Arduino IDE

To use the OLED display in our project, we have to install the Adafruit SSD 1306 library in Arduino IDE. Follow the steps below to successfully install it.

Open Arduino IDE and click on Sketch > Library > Manage Libraries

MPU-6050 Install library

The following window will open up.

search library Arduino IDE

Type ‘SSD1306’ in the search tab and install the Adafruit SSD1306 OLED library.

Install OLED SSD1306 Library Arduino IDE

Connecton Diagram– OLED with ESP8266 NodeMCU and BME680

The table below shows the terminals of the three devices which would be connected together.

OLED DisplayESP8266 NodeMCUBME680
VCCVCC=3.3VVCC
GNDGNDGND
SCLGPIO5 (D1)SCL
SDAGPIO4 (D2)SDA

Assemble the circuit as shown in the schematic diagram below:

bme680 oled esp8266 nodemcu schematic diagram

As you can see above, we have connected all the VCC terminals with a 3.3V power supply. The SCL terminals are connected with GPIO22 and the SDA terminals are connected with GPIO21. The grounds are also common.

Arduino Code: Displaying BME680 readings on OLED Display

Copy the following code to your Arduino IDE and upload it to the ESP8266 NodeMCU after assembling above circuit diagram.

/***************************************************************************
  This is a library for the BME680 gas, humidity, temperature & pressure sensor

  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"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#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);

Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);

void setup() {
  Serial.begin(9600);
  Serial.println(F("BME680 test"));

  // by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)
  // init done
  display.display();
  delay(100);
  display.clearDisplay();
  display.display();
  display.setTextSize(1);
  display.setTextColor(WHITE);

  if (!bme.begin()) {
    Serial.println("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() {
  display.setCursor(0,0);
  display.clearDisplay();

  if (! bme.performReading()) {
    Serial.println("Failed to perform reading :(");
    return;
  }
  Serial.print("Temperature = "); Serial.print(bme.temperature); Serial.println(" *C");
  display.print("Temperature: "); display.print(bme.temperature); display.println(" *C");

  Serial.print("Pressure = "); Serial.print(bme.pressure / 100.0); Serial.println(" hPa");
  display.print("Pressure: "); display.print(bme.pressure / 100); display.println(" hPa");

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

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

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

How Code Works?

The maximum portion of the code is same as we have discussed earlier except the OLED display part. Therefore, we will only explain OLED display part here.

Include Libraries

We will first include all the required libraries for the BME680 sensor as well as the OLED display which we just installed before.

#include <SPI.h>
#include <Adafruit_Sensor.h>
#include "Adafruit_BME680.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Now, we will create another object named display which will be handling the OLED display. Also, define the size of OLED display by passing arguments to Adafruit_SSD1306() function.

Adafruit_SSD1306 display = Adafruit_SSD1306(128, 32, &Wire);

This block of code initializes the OLED display.

// by default, we'll generate the high voltage from the 3.3v line internally! (neat!)
  display.begin(SSD1306_SWITCHCAPVCC, 0x3C);  // initialize with the I2C addr 0x3C (for the 128x32)

We have set the font size as default which is 1. Whenever we increase the size by +1, the pixel resolution of the text increases by 10 in height. Next, we will control the color of the text by using the setTextColor() function and passing WHITE as an argument. If we have a dark background, we will display our text in white and if we have a bright background then we will display the text in black. We do not want to rotate the text, so we are passing 0 as the parameter inside the setRotation() function. The parameter can take in any value from 0,1,2,3 where 0 denotes rotation of 0 degrees, 1 denotes rotation of 90 degrees, 2 denotes rotation of 180 degrees and 3 denotes a rotation of 270 degrees.

// init done
  display.display();
  delay(100);
  display.clearDisplay();
  display.display();
  display.setTextSize(1);
  display.setTextColor(WHITE);

The loop() obtains the readings from the sensors and prints them on the OLED display. We will first create events for the accelerometer (a), gyroscope (g), and temperature (t) and get their new sensor readings.

clearDisplay() function wipes off the previous readings from the display after each loop() so that new ones can be printed.

display.setCursor(0,0);

We will use the setCursor() function to denote the x and the y axis position from where the text should start. We have passed (0,0) as the parameter hence the text starts from the upper left corner.

display.setCursor(0, 0);

Now let’s display the temperature, pressure, humidity, and Gas values on the serial monitor and OLED one by one. This block of code displays BME680 sensor values on OLED and updates the value after every 2 seconds.

if (! bme.performReading()) {
    Serial.println("Failed to perform reading :(");
    return;
  }
  Serial.print("Temperature = "); Serial.print(bme.temperature); Serial.println(" *C");
  display.print("Temperature: "); display.print(bme.temperature); display.println(" *C");

  Serial.print("Pressure = "); Serial.print(bme.pressure / 100.0); Serial.println(" hPa");
  display.print("Pressure: "); display.print(bme.pressure / 100); display.println(" hPa");

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

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

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

Demonstration

To see the demonstration of the above code, upload the code to Arduino. But, before uploading code, make sure to select the ESP8266 NodeMCU board from Tools Board and also select the correct COM port to which the ESP8266 NodeMCU board is connected from Tools Port.

Once the code is uploaded to ESP8266 NodeMCU , open the serial monitor of Arduino IDE and set the baud rate to 115200. Finally, we can see the BME680 readings on Arduino serial monitor and on the OLED display as follows:

BME680 with ESP8266 NodeMCU and OLED Arduino IDE demo

If you found this tutorial useful, we have a similar guide for BME680 using MicroPython:

1 thought on “BME680 with ESP8266 NodeMCU using Arduino IDE (Gas, Pressure, Temperature, Humidity)”

Leave a Comment