Read in forced mode
What this example shows
In forced mode the sensor makes one measurement each time you ask. The example sets the oversampling, an IIR filter and one heater step (300 °C for 100 ms), then triggers a measurement every second and prints temperature, pressure, humidity and gas resistance. This is the usual way to read the sensor.
The example creates the sensor with BME690(), so on the esp32 and esp8266
ports it uses I2C(0) with SDA on pin 21 and SCL on pin 22, at address
0x76.
The example code
# FILE: bme690-forcedMode.py
# AUTHOR: Josip Simun Kuci @ Soldered
# BRIEF: Read temperature, pressure, humidity and gas resistance from the
# BME690 in forced mode, one measurement at a time
# WORKS WITH: BME690 breakout board: solde.red/333411
# LAST UPDATED: 2026-09-16
from bme690 import (
BME690,
BME69X_ERROR,
BME69X_FILTER_SIZE_3,
BME69X_FORCED_MODE,
)
import time
# Start the sensor on the default I2C address (0x76). Use
# BME690(address=BME69X_I2C_ADDR_HIGH) if the address jumper is soldered.
sensor = BME690()
# Oversampling for temperature, pressure and humidity.
sensor.set_tph()
# IIR filter for the temperature and pressure readings.
sensor.set_filter(BME69X_FILTER_SIZE_3)
# Heat the gas sensor plate to 300 degrees Celsius for 100 milliseconds.
sensor.set_heater_prof(300, 100)
if sensor.check_status() == BME69X_ERROR:
raise Exception("BME690 setup failed: " + sensor.status_string())
print(
"Timestamp(ms), Temperature(C), Pressure(Pa), Humidity(%), "
"Gas resistance(Ohm), Status"
)
while True:
# Trigger a single measurement.
sensor.set_op_mode(BME69X_FORCED_MODE)
# Wait for the measurement to finish, the heater duration included.
time.sleep_us(sensor.get_meas_dur())
if sensor.fetch_data():
data, _ = sensor.get_data()
print(
"{}, {:.2f}, {:.2f}, {:.2f}, {:.2f}, 0x{:02x}".format(
time.ticks_ms(),
data.temperature,
data.pressure,
data.humidity,
data.gas_resistance,
data.status,
)
)
time.sleep(1)
🔗Open the complete example
Examples/bme690-forcedMode.py at commit 91a07b5
Expected result:
Timestamp(ms), Temperature(C), Pressure(Pa), Humidity(%), Gas resistance(Ohm), Status
Each new measurement then prints one row in that order: the millisecond
counter, temperature in °C, pressure in Pa, humidity in % r.H. and gas
resistance in Ω (each to two decimals), and the status byte in hex. 0xb0 means
new data, a valid gas measurement and a stable heater.
Functions used
BME690(i2c=None, address=BME69X_I2C_ADDR_LOW, amb_temp=25)returns BME690Creates the sensor object. It soft-resets the sensor, checks its chip ID (0x61) and reads the calibration data. It raises an exception when the sensor does not answer or another chip is at the address; every other function records its result in the status instead of raising.
ReturnsThe sensor object.
Parameters
| Type | Name | Description |
|---|---|---|
I2C | i2c | A ready machine.I2C object. Left out, the module opens I2C(0) with SCL on pin 22 and SDA on pin 21 on the esp32 and esp8266 ports and one Soldered board firmware, and raises an exception on any other port. |
int | address | The I2C address: BME69X_I2C_ADDR_LOW (0x76, the default) or BME69X_I2C_ADDR_HIGH (0x77). |
int | amb_temp | Ambient temperature in °C, used to work out the heater setting. 25 by default. |
sensor.set_tph(os_temp=BME69X_OS_2X, os_pres=BME69X_OS_16X, os_hum=BME69X_OS_1X)returns NoneSets the oversampling for temperature, pressure and humidity. Called without arguments, as here, it sets the defaults of the Arduino library.
ReturnsNothing. The result is in the status.
Parameters
| Type | Name | Description |
|---|---|---|
int | os_temp | Temperature oversampling, BME69X_OS_NONE to BME69X_OS_16X. |
int | os_pres | Pressure oversampling, BME69X_OS_NONE to BME69X_OS_16X. |
int | os_hum | Humidity oversampling, BME69X_OS_NONE to BME69X_OS_16X. |
sensor.set_filter(filter_size=BME69X_FILTER_OFF)returns NoneSets the IIR filter that smooths the temperature and pressure readings.
ReturnsNothing. The result is in the status.
Parameters
| Type | Name | Description |
|---|---|---|
int | filter_size | BME69X_FILTER_OFF, or BME69X_FILTER_SIZE_1, _3, _7, _15, _31, _63 or _127. The example uses BME69X_FILTER_SIZE_3. |
sensor.set_heater_prof(temp, dur, shared_heatr_dur=None)returns NoneSets the gas heater profile and switches the heater on. With one temperature and one duration, as here, it writes the single heater step forced mode uses. Temperatures above 400 °C are capped at 400 °C.
ReturnsNothing. The result is in the status.
Parameters
| Type | Name | Description |
|---|---|---|
int | temp | Heater temperature in °C. The example uses 300. |
int | dur | Heating duration in ms. The example uses 100. |
int | shared_heatr_dur | Parallel mode only; leave it out in forced mode. |
sensor.check_status()returns intSums up the status the last function left behind.
ReturnsBME69X_ERROR (-1) after an error, BME69X_WARNING (1) after a warning, BME69X_OK (0) otherwise.
sensor.status_string()returns strDescribes the current status code in a few words, such as Communication failure or No new data.
ReturnsThe description, an empty string when the status is OK.
sensor.set_op_mode(op_mode)returns NonePuts the sensor to sleep, then sets the requested mode. BME69X_FORCED_MODE triggers one measurement. The mode is remembered for get_meas_dur(), fetch_data() and get_data().
ReturnsNothing. The result is in the status.
Parameters
| Type | Name | Description |
|---|---|---|
int | op_mode | BME69X_SLEEP_MODE, BME69X_FORCED_MODE, BME69X_PARALLEL_MODE or BME69X_SEQUENTIAL_MODE. |
sensor.get_meas_dur(op_mode=BME69X_SLEEP_MODE)returns intWorks out how long one temperature, pressure and humidity measurement takes, from the oversampling set with set_tph(), so call set_tph() first. Outside parallel mode it adds 1 ms for the sensor to wake up. The heater duration is not part of the result.
ReturnsThe measurement duration in microseconds.
Parameters
| Type | Name | Description |
|---|---|---|
int | op_mode | The mode to calculate for. Left out, the last mode set with set_op_mode(). |
sensor.fetch_data()returns intReads the measured data from the sensor into the module's buffer. In forced mode it reads the one result field. When nothing new is there, the status reads No new data.
ReturnsThe number of new data fields, 0 when there are none.
sensor.get_data()returns tupleHands out the next field from the buffer as a BME690Data object with temperature (°C), pressure (Pa), humidity (% r.H.), gas_resistance (Ω), status, gas_index and meas_index. In forced mode it always returns the one field.
Returns(data, fields_left): the BME690Data, and how many new fields are left (0 in forced mode).
Putting it together
BME690() finds the sensor, and set_tph(), set_filter() and
set_heater_prof() set it up. check_status() reads only the status the last
of these calls left, so the script stops with the reason when the heater setup
reports an error; a warning does not stop it. In the loop, set_op_mode(BME69X_FORCED_MODE) starts one
measurement, the script sleeps for get_meas_dur() microseconds, and
fetch_data() with get_data() collect the result. A loop where fetch_data()
returns 0 prints nothing.
The example's comment says the wait includes the heater duration, but
get_meas_dur() does not add it: with the set_tph() defaults it returns
42590 µs, shorter than the 100 ms heater step. fetch_data() then checks for
new data up to five times, 10 ms apart, before it gives up for that loop.
If you moved the ADDR jumper, create the sensor with
BME690(address=BME69X_I2C_ADDR_HIGH) and import BME69X_I2C_ADDR_HIGH from
bme690 as well.