Source: https://mokxi.com/learn/arduino-bme680

Learn

# A BME680 on an Arduino: air quality and the weather

Intermediate

Written by the Mokxi team

Start building free Open the editor

Or see every lesson.

- 455 parts on the bench
- 43 boards running now
- 1.00x real time, on every board

Click to open it in the editor

The Kitchen air example: drag the gas slider on the BME680 below two thirds of its start and the sketch calls out bad air.

The BME680 is four sensors in one tiny Bosch chip: temperature, humidity, air pressure and a gas sensor that reacts to smoke, cooking fumes, paint and other things in the air. It is the sensor in a lot of home-made air quality monitors, and it talks to an Arduino over I2C.

The circuit above is an Uno reading a BME680 with the Adafruit library. It learns the clean air’s gas reading first, then prints the weather once a second and calls out "bad air" when the gas reading falls well below that baseline. Press Run, then drag the gas slider on the board down and watch it react.

## What you need

- An Arduino Uno
- A BME680 breakout board
- Four jumper wires

## Wiring

Part and pin | Goes to | Note

BME680 VIN | 5 V | The breakout runs on 3 to 5 V

BME680 GND | GND |

BME680 SDA | SDA (A4) | Address 0x77; some boards are at 0x76

BME680 SCL | SCL (A5) |

## What the gas sensor really measures

Inside the BME680 is a tiny metal oxide plate with a heater under it. The sketch heats it, here to 320 C for 150 ms, then measures its resistance. Many gases from cooking, cleaning products, solvents and breath make that resistance fall. Clean air gives a high resistance; dirty air a lower one.

What the chip does not give you is a gas name or a ppm number. It gives ohms. And every sensor reads a different number in the same clean air, so the figure means very little on its own. What means something is the change from that same sensor’s clean-air reading.

## The sketch: a baseline, then a comparison

In setup() the sketch sets the heater with bme.setGasHeater(320, 150), takes one reading and keeps its gas resistance as the baseline. Run it and the first line says "Clean air: 150 kohm".

Then once a second it calls bme.performReading() and prints the four values: "22.0 C 45 %RH 1010.0 hPa gas 150 kohm". If the gas resistance falls below two thirds of the baseline, the line ends in "bad air". With a 150 kohm baseline the line is drawn at 100 kohm: drag the slider to 101 and nothing happens, to 99 and it says bad air.

The math is written as baseline / 3 * 2, dividing first so the number stays inside a 32-bit integer. Multiplying first works here too, but it is a good habit with big numbers on an Arduino.

The kitchen air sketch

## The other three readings

The weather part works like a BME280. bme.temperature is in degrees Celsius, bme.humidity in percent relative humidity, and bme.pressure in pascals, which the sketch divides by 100 to print hectopascals. Drag the temperature and humidity sliders and the next line follows.

All four readings come from one performReading(), which runs a full cycle: the weather, then the heater, then the gas. That takes as long as the heater time you set, so it is not instant. Ask for a reading every second or so, not every loop.

## A real BME680 needs time

A brand new BME680 needs a burn-in: run it for a day or two before its gas readings settle. Even after that, give it 20 to 30 minutes after power on before trusting the baseline. Taking the baseline in the first second, as this short sketch does, is fine in a simulation and too soon on a real one.

Humidity also moves the gas reading, which is why Bosch’s own BSEC library blends the two into an "IAQ" index from 0 to 500. It is not open source and is large for an Uno, so most Uno projects do what this one does: watch the change from a baseline.

The simulation leaves out the heater’s real temperature and the effect of humidity on the gas reading. Here the gas reading is simply the slider’s resistance.

## Common mistakes

Reading the gas number as a ppm or an air quality score. It is a resistance. Compare it to the same sensor’s clean-air number.

Comparing two sensors’ gas numbers. They differ even in the same air.

The wrong address. Adafruit’s board is at 0x77, and many clones are at 0x76. If bme.begin() fails, try bme.begin(0x76). With SDA pulled out the sketch here prints "No BME680".

Taking the baseline in dirty air, such as right after cooking. Every later reading then looks clean.

Expecting a gas reading at once. The heater has to run for the time you set first.

## Questions

Does the BME680 measure CO2?

No. It reacts to many gases at once (volatile organic compounds) and gives a resistance. For CO2 you need a different sensor, such as an SCD40 or an MH-Z19.

What is the difference between the BME280 and the BME680?

The BME280 measures temperature, humidity and pressure. The BME680 adds the heated gas sensor. They use different libraries.

What library do I use for the BME680?

The Adafruit BME680 Library: bme.begin(), bme.setGasHeater(320, 150), then bme.performReading() and the four values. Bosch’s own BSEC library gives an IAQ index but is large for an Uno.

What is a good gas resistance?

There is no single answer: it depends on the sensor and the heater settings. Higher than your own clean-air baseline is cleaner, lower is dirtier.

Related

## Keep going

Arduino BMP180: Pressure, Altitude and Code Arduino DHT22 and DHT11: Temperature and Humidity I2C Explained: Addresses, Acknowledges and Pull-Ups Arduino Temperature Data Logger Lab, Step by Step Arduino MQ-2 Gas Sensor: Wiring, Warm-Up and Code How the BME680 is modeled A BME280 and a BMP280 side by side Intermediate The Arduino Uno simulator The project page, with the full sketch Intermediate

## Build this for real

Open the editor, change a value and watch the number move with it. Nothing to install, and no account needed.

Start building free Open the editor
