We will learn about the BME680 sensor module and how to use it with Arduino Nano.
Tag: Project 124a BME680 Barometric Pressure, Humidity, Temperature & Gas Sensor. Acoptex.lt
Project resources
- Sketch: sketch;
- Libraries: Adafruit_BME680 Library. You can read more about it here; Adafruit_Sensor Library. You can read more about it here; Wire library. Built in inside the Arduino IDE; SPI library. Built in inside the Arduino IDE.
- Other attachments: None.
Parts required
In this project, you needed these parts (Dear visitors. You can support our project buy clicking on the links of parts and buying them or donate us to keep this website alive. Thank you):
1. BME680 sensor module 1 pc

2. Jumper cables F-F 6 pcs

3. Arduino Nano and Mini-B USB cable 1 pc

Understanding the BME680 sensor module
The long awaited BME680 from Bosch gives you all the environmental sensing you want in one small package. This little sensor contains temperature, humidity, barometric pressure, and VOC gas sensing capabilities. All over SPI or I2C at a great price.
Like the BME280 & BMP280, this precision sensor from Bosch can measure humidity with ±3% accuracy, barometric pressure with ±1 hPa absolute accuracy, and temperature with ±1.0°C accuracy. Because pressure changes with altitude, and the pressure measurements are so good, you can also use it as an altimeter with ±1 meter or better accuracy.
The BME680 takes those sensors to the next step in that it contains a small MOX sensor. The heated metal oxide changes resistance based on the volatile organic compounds (VOC) in the air, so it can be used to detect gasses & alcohols such as Ethanol, Alcohol and Carbon Monoxide, and perform air quality measurements. Note it will give you one resistance value, with overall VOC content, but it cannot differentiate gasses or alcohols.
Please note this sensor, like all VOC/gas sensors, has variability and to get precise measurements you will want to calibrate it against known sources! That said, for general environmental sensors, it will give you a good idea of trends and comparisons. We recommend that you run this sensor for 48 hours when you first receive it to “burn it in”, and then 30 minutes in the desired mode every time the sensor is in use. This is because the sensitivity levels of the sensor will change during early use, and the resistance will slowly rise over time as the MOX warms up to its baseline reading.
For your convenience, Adafruit pick-and-placed the sensor on a PCB with a 3.3V regulator and some level shifting, so it can be easily used with your favorite 3.3V or 5V microcontroller.
The BME280, BME680, and BMP280 breakouts all share the same I2C addresses, so if you’re using two together then you’ll need to change the I2C address on one of them using the solder bridge/pads.
If you want to connect multiple BME680’s to one microcontroller, have them share the SDI, SDO and SCK pins. Then assign each one a unique CS pin.
Typical applications:
- Indoor air quality
- Home automation and control
- Internet of things
- Weather forecast
- GPS enhancement (e.g. time-to-first-fix improvement, dead reckoning, slope detection)
- Indoor navigation (change of floor detection, elevator detection)
- Outdoor navigation, leisure and sports applications
- Vertical velocity indication (rise/sink speed)
Applications:
- Handsets such as mobile phones, tablet PCs, GPS devices
- Wearables
- Home weather stations
- Smart watches
- Navigation systems
- Gaming, e.g. flying toys
- IOT devices
Specifications:
- Power requirements: +3.3 VDC to +5 VDC; maximum 20 mA
- Typical current consumption:3.7 µA at 1 Hz humidity, pressure and temperature: 0.09‒12 mA for p/h/T/gas depending on operation mode; 0.15 µA in sleep mode
- Absolute barometric pressure: range 300–1100 hPa; ±0.12 hPa
- Relative humidity: range, 0–100%; ±3%
- Temperature: range -40 to +85 °C; resolution 0.01°C, ±0.5°C typical
- Gas sensor resolution: 0.08% typical
- Communication: I2C (100 or 400 kHz) or SPI (3 and 4 wire, up to 10 MHz)
- Operating temperature: -40 to +185 °F (-40 to +85 °C),
- Operating environment: 0‒100% r.H., 300‒1100 hPa
- Form factor: 6-pin male header with 0.1″ spacing
- PCB dimensions: 20 x 18 mm
- Mounting holes: Two holes suitable for #3 UNC (M2.5) hardwar
- Default I2C address is 0x77. If you add a jumper from SDO to GND, the address will change to 0x76. (can be different on your BME680 sensor module)
You can read more about it here.
Remember:
- The BME680 needs access to ambient air to measure its pressure, so don’t put it in a sealed case. Providing a small vent hole should be adequate.
- On the other hand, exposure to fast-moving air or wind can cause momentary pressure variations that will affect your readings. Shield the device from strong air currents.
- Because an accurate temperature reading is needed to measure the pressure, try not to expose the device to rapid temperature changes, and keep it away from nearby hot parts and other heat sources.
- The BME680 is sensitive to moisture. Don’t submerge it or allow it to contact liquid water.
- Surprisingly, the silicon within the BME680 is sensitive to light, which can enter the device through the hole on the top of the chip. For maximum accuracy, shield the chip from ambient light.
How does it work?
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:

- 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.
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.
Understanding the Arduino Nano
You can read more about it here.
Signals and connections of the BME680 sensor module

Power Pins:
- 2-6V – power supply pin. Supplies power for the module. Connect it to 3.3V pin or 5V pin of your Arduino board.
- VCC, Vin – power supply pin. Supplies power for the module. Connect it to 5V pin of your Arduino board.
- GND – ground pin. Connected to GND pin on Arduino board.
- 3Vo, 3V3 – power supply pin. Supplies power for the module. You can use it instead of VCC pin of BME680 sensor module. Connect it to 3.3V pin of your Arduino board.
SPI Logic pins:
- SDO – Serial Data Out / Microcontroller In Sensor Out pin, for data sent from the BME680 to your processor.
- CS – Chip Select pin, drop it low to start an SPI transaction. Its an input to the chip.
- SDI – Serial Data In / Microcontroller Out Sensor In pin, for data sent from your processor to the BME680.
- SCK – SPI Clock pin, its an input to the chip
If you want to connect multiple BME680’s to one microcontroller, have them share the SDI, SDO and SCK pins. Then assign each one a unique CS pin.
I2C Logic pins:
- ADDR – The solder pads (marked ADDR) can be bridged to change the I2C address from the default of 0x76 to 0x77, meaning that you can use up to two sensors on the same Raspberry Pi or Arduino
- SDA, SDI – serial data pin for I2C interface (SDA pin or Analog input pin A4 of Arduino board).
- SCL, SCK -serial clock pin for I2C interface (SCL pin or Analog input pin A5 of Arduino board).
Signals and connections of the Arduino Nano
You can read more about it here.
Wiring
1.I2C Wiring


BME680 sensor module | Arduino Nano |
Vin | 5V |
GND | GND |
SCK | SCL (A5) |
SDI | SDA (A4) |
Note that each Arduino Board has different I2C pins which should be connected accordingly. On the Arduino boards with the R3 layout, the SDA (data line) and SCL (clock line) are on the pin headers close to the AREF pin. Refer below table for quick understanding.
Boards | SCL | SDA |
Arduino Uno | A5 | A4 |
Arduino Nano | A5 | A4 |
Arduino Mega | 21 | 20 |
Leonardo/Micro | 3 | 2 |
2.SPI Wiring
Since this is a SPI-capable sensor, we can use hardware or ‘software’ SPI. To make wiring identical on all microcontrollers, we’ll begin with ‘software’ SPI.


BME680 sensor module | Arduino Nano |
Vin | 5V |
GND | GND |
SCK | D13 |
SDO | D12 |
SDI | D11 |
CS | D10 |
Step by Step instruction
- Do wiring.
- Open Arduino IDE.
- Plug your Arduino Nano board into your PC and select the correct board and com port.
- Install the Adafruit_BME680 Library. You can download it here or install it directly in Arduino IDE. Go to Sketch->Include Library->Manage libraries…->search for Adafruit BME680 and click on Install.
- Install the Adafruit_Sensor Library. You can download it here or install it directly in Arduino IDE. Go to Sketch->Include Library->Manage libraries…->search for Adafruit Unified Sensor and click on Install.
- After installing the libraries, restart your Arduino IDE.
- Verify and upload sketch to your Arduino Nano.
- Open up Arduino IDE Serial Monitor and set your baud to 115200 baud and select Newline.Press the on-board RST button. The sensor measurements will be displayed in Serial Monitor:

Code
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"
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 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10*/
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 Arduino I2C pins: D5 (SCL), D4 (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"));
Wrapping up
We have learnt about the BME680 sensor module and how to use it with Arduino Nano. 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.
Check for more DIY projects here.
Thank you for reading and supporting us.
Check for more DIY projects on Acoptex.lt and Acoptex.com!
If you are looking for high quality PCBs PCBWay is the best choice:

RELATED POSTS
Arduino guide for microphone sound sensor
Arduino Guide for WTV020-SD-16P voice module
How to convert MP3 and WAV files to AD4 format