BME680 – An All-Inclusive Guide on the Environmental Sensor

Posted by

Introduction to the BME680 Sensor

The BME680 is a highly integrated environmental sensor from Bosch Sensortec that combines gas, pressure, humidity and temperature sensing capabilities in a compact package. It is designed for a wide range of applications, including indoor air quality monitoring, weather forecasting, and personal health monitoring devices.

Key features of the BME680 include:

  • Gas sensor for air quality measurement (VOC detection)
  • High-accuracy pressure, temperature and humidity sensors
  • Compact 3.0 x 3.0 mm package
  • Low power consumption
  • I2C and SPI interfaces

BME680 Technical Specifications

Parameter Value
Package dimensions 3.0 x 3.0 x 0.93 mm
Operating range -40 to 85 °C
VDD supply voltage 1.71 to 3.6 V
VDDIO supply voltage 1.2 to 3.6 V
Average current consumption 2.1 μA at 1 Hz humidity and temperature
Humidity sensor response time 8 s
Gas sensor response time 1 s
Interfaces I2C, SPI
Temperature sensor resolution 0.01 °C
Humidity sensor resolution 0.008 % RH
Pressure sensor resolution 0.18 Pa

Gas Sensor Specifications

The BME680 features a metal-oxide gas sensor for detecting a wide range of Volatile Organic Compounds (VOCs) and other gases. It operates by heating a sensing layer and measuring its resistivity, which changes in the presence of reducing or oxidizing gases.

Parameter Specification
Gas types Volatile Organic Compounds (VOCs)
Sensing material Metal-oxide
Sensing range 0 to 500 kΩ
Measurement time 1 to 4 s
Sensor current consumption 0.09 to 12 mA

Pressure Sensor Specifications

The BME680 includes a piezo-resistive pressure sensor with high accuracy over a wide temperature range. It is well-suited for measuring barometric pressure for weather forecasting and altitude tracking applications.

Parameter Value
Operating range 300 to 1100 hPa
Absolute accuracy ± 0.6 hPa (0 to 65 °C)
Temperature coefficient offset ± 1.0 Pa/K
RMS Noise 0.12 Pa (typ.)

Humidity Sensor Specifications

The integrated humidity sensor in the BME680 is a capacitive type sensor that offers fast response time, high accuracy, and excellent long-term stability.

Parameter Value
Operating range 0 to 100 % RH
Accuracy tolerance ± 3 % RH
Hysteresis ± 1.5 % RH
Response time 8 s (tau63%)
Long-term stability <0.5 % RH/year

Temperature Sensor Specifications

Bosch’s BME680 environmental sensor integrates a high-precision temperature sensor for accurate compensation of the pressure and humidity readings. It also provides a standalone temperature measurement.

Parameter Value
Operating range -40 to 85 °C
Accuracy tolerance ± 0.5 °C (0 to 65 °C)
Resolution 0.01 °C
Temperature coefficient 1.5 m°C (typ.)

Interfacing with the BME680

The BME680 sensor supports both I2C and SPI digital interfaces for communicating with a host microcontroller.

I2C Interface

The sensor operates as a slave device on the I2C bus. It supports standard (100 kHz), fast (400 kHz) and high-speed (3.4 MHz) I2C modes. The 7-bit slave address is 0x76 (or 0x77 if the SDO pin is pulled high).

I2C Pinout

Pin Name Description
1 VDD Power supply
2 GND Ground
3 VDDIO I/O power supply
4 SCL Serial clock input
5 SDA Serial data input/output
6 SDO I2C slave address LSB

SPI Interface

In SPI mode, the BME680 acts as a slave device. It uses 4-wire SPI with mode ’00’ (CPOL = 0, CPHA = 0) and a clock frequency of up to 10 MHz.

SPI Pinout

Pin Name Description
1 VDD Power supply
2 GND Ground
3 VDDIO I/O power supply
4 CSB Chip select
5 SCK Serial clock input
6 SDI Serial data input
7 SDO Serial data output

Configuring the BME680

The BME680 has a rich set of configuration options that allow you to optimize its operation for your specific application needs. The main configuration parameters include:

Oversampling Settings

The oversampling settings control the resolution and noise levels of the pressure, temperature and humidity measurements. Higher oversampling ratios improve resolution but increase power consumption and measurement time.

Oversampling Setting Pressure Temperature Humidity
Skipped (output set to 0x8000) 0 0 0
Oversampling ×1 1 1 1
Oversampling ×2 2 2 2
Oversampling ×4 3 3 3
Oversampling ×8 4 4 4
Oversampling ×16 5 5 5

IIR Filter Coefficient

The IIR (Infinite Impulse Response) filter is used to reduce short-term fluctuations in the sensor outputs caused by external disturbances. The filter coefficient ranges from 0 (off) to 7 (maximum filtering).

IIR Filter Coefficient Samples to reach 75% of step response
0 1
1 2
2 4
3 8
4 16
5 32
6 64
7 128

Gas Sensor Heating Profile

The gas sensor in the BME680 requires heating to different temperature setpoints to measure the VOC resistance. The heating profile consists of up to 10 temperature steps, each with a configurable target temperature and heating duration.

Performing Measurements with the BME680

To perform a measurement with the BME680:

  1. Configure the oversampling settings, IIR filter coefficient, and gas sensor heating profile according to your application requirements.
  2. Trigger a measurement by setting the appropriate bit in the CTRL_MEAS register.
  3. Wait for the measurement to complete by polling the measuring status register or using the data ready interrupt.
  4. Read out the raw pressure, temperature, humidity and gas resistance values from the data registers.
  5. Compensate the raw values using the calibration parameters to obtain the actual environmental readings.

Here is an example sequence for triggering a measurement with oversampling settings of 16x for pressure, 2x for temperature, 1x for humidity, and no gas measurement:

  1. Write 0b10110101 to the CTRL_HUM register to set the humidity oversampling.
  2. Write 0b10110100 to the CTRL_MEAS register to start the pressure and temperature measurement.
  3. Poll the measuring bit in the MEAS_STATUS_0 register until it reads 0.
  4. Read the raw pressure and temperature data from the PRESS_MSB, PRESS_LSB, PRESS_XLSB, TEMP_MSB, TEMP_LSB, and TEMP_XLSB registers.
  5. Read the raw humidity data from the HUM_MSB and HUM_LSB registers.
  6. Use the compensation functions with the calibration parameters to calculate the compensated pressure, temperature and humidity values.

Calculating the Compensated Sensor Values

The raw sensor data from the BME680 must be compensated using a set of calibration parameters to obtain the actual pressure, temperature, humidity and gas resistance values. Bosch Sensortec provides an API with compensation functions in C code to simplify this process.

Pressure Compensation

The pressure compensation formula uses a set of temperature-dependent calibration parameters to convert the raw pressure data into the compensated pressure value in Pascals.

// Compensate pressure
float compensate_pressure(int32_t raw_pressure, int32_t t_fine)
{
  float var1, var2, var3, pressure_comp;

  var1 = (float)t_fine / 2.0f - 64000.0f;
  var2 = var1 * var1 * calib_data.par_p6 / 131072.0f;
  var2 = var2 + var1 * calib_data.par_p5 * 2.0f;
  var2 = var2 / 4.0f + calib_data.par_p4 * 65536.0f;
  var1 = (calib_data.par_p3 * var1 * var1 / 16384.0f + calib_data.par_p2 * var1) / 524288.0f;
  var1 = (1.0f + var1 / 32768.0f) * calib_data.par_p1;

  pressure_comp = 1048576.0f - (float)raw_pressure;
  pressure_comp = ((pressure_comp - var2 / 4096.0f) * 6250.0f) / var1;
  var1 = calib_data.par_p9 * pressure_comp * pressure_comp / 2147483648.0f;
  var2 = pressure_comp * calib_data.par_p8 / 32768.0f;
  var3 = pressure_comp / 256.0f;
  pressure_comp = pressure_comp + (var1 + var2 + calib_data.par_p7) / 16.0f;

  return pressure_comp;
}

Temperature Compensation

The BME680 outputs a raw temperature value that must be compensated to calculate the actual temperature in degrees Celsius. The temperature compensation uses a set of calibration parameters stored in the device’s non-volatile memory.

// Compensate temperature 
float compensate_temperature(int32_t raw_temperature)
{
  float var1, var2, temperature;

  var1 = (((float)raw_temperature) / 16384.0f - ((float)calib_data.par_t1) / 1024.0f) * ((float)calib_data.par_t2);
  var2 = ((((float)raw_temperature) / 131072.0f - ((float)calib_data.par_t1) / 8192.0f) *
          (((float)raw_temperature) / 131072.0f - ((float)calib_data.par_t1) / 8192.0f)) * ((float)calib_data.par_t3);
  calib_data.t_fine = (int32_t)(var1 + var2);
  temperature = (var1 + var2) / 5120.0f;

  return temperature;
}

Humidity Compensation

The raw humidity value from the BME680 is compensated using the calibration data to provide the relative humidity in percent.

// Compensate humidity
float compensate_humidity(int32_t raw_humidity, int32_t t_fine)
{
  float var1, var2, var3, var4, var5, var6, humidity;

  var1 = (float)t_fine - 76800.0f;
  var2 = (float)raw_humidity * 16384.0f + ((float)calib_data.par_h4) * 1048576.0f;
  var3 = calib_data.par_h5 * var1;
  var4 = calib_data.par_h2 + (var3 + (var2 * calib_data.par_h6) / 67108864.0f) / 16384.0f;
  var5 = var1 * calib_data.par_h3 / 2097152.0f;
  var6 = var1 * (var4 * (1.0f - calib_data.par_h1 * var5));
  humidity = var2 * var6 / 524288.0f;

  if (humidity > 100.0f)
    humidity = 100.0f;
  else if (humidity < 0.0f)
    humidity = 0.0f;

  return humidity;
}

Gas Resistance Compensation

The gas sensor resistance is calculated using the raw gas value and a set of heating profile-dependent parameters.

// Compensate gas resistance
float compensate_gas_resistance(int32_t raw_gas, int32_t gas_range)
{
  float var1, var2, var3;

  var1 = 262144.0f / (float)raw_gas;
  var2 = var1 * calib_data.par_gh3;
  var3 = 1.0f + (calib_data.par_gh1 * var1) + (calib_data.par_gh2 * var2);
  var2 = 1.0f / var3;
  var1 = (calib_data.par_gh3 * var2) + (calib_data.par_gh1 * var2 * var2);
  gas_resistance = 1.0f / (calib_data.par_gh2 + var1);

  if (gas_range >= BME68X_RANGE_SW_ERR_VAL)
    return 0;

  var1 = (1340.0f + 5.0f * calib_data.range_sw_err) * lookupTable1[gas_range];
  gas_resistance /= var1;

  return gas_resistance;
}

Example BME680 Arduino Sketch

Here’s a simple Arduino sketch that demonstrates how to read and print the compensated sensor values from the BME680 using the Bosch Sensortec API:

“`c++

include

include “bme680.h”

define I2C_ADDR BME680_I2C_ADDR_PRIMARY // 0x76

// Create a BME680 object
Bme680 bme680(I2C_ADDR);

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

// Initialize the BME680
if (bme680.init() != BME680_OK) {
Serial.println(“Failed to initialize BME680!”);
while (1);
}

// Configure oversampling settings
bme680.setTemperatureOversampling(BME680_OS_8X);
bme680.setPressureOversampling(BME680_OS_4X);
bme680.setHumidityOversampling(BME680_OS_2X);
bme680.setIIRFilterSize(BME680_FILTER_SIZE_3);
bme680.setGasHeater(320, 150); // 320*C for 150

Leave a Reply

Your email address will not be published. Required fields are marked *