Issues with the Gas sensor on the SEN0629 (BME688)
art.pm 2026-08-05 23:38:07 348 Views10 Replies Hi there!
I try to make the SEN0629 measuring Gas level, but can't make it working. I hope someone here may have a solution…
I use ESP32 to collect data from many sensors and drive some devices in the automated mini greenhouse.
My whole project is written in microPython. Just wanted to add one more sensor, the BME688 (SEN0629).
1. I tried this library for Python: https://github.com/DFRobot/DFRobot_BME68x/blob/master/Python/RaspberryPi/DFRobot_BME68x.py with this demo code: https://github.com/DFRobot/DFRobot_BME68x/blob/master/Python/RaspberryPi/examples/demo_read_all_data.py
I had to remove „future” part and add some lines to handle the I2C communication. My main code looks like this:
from DFRobot_BME68x import DFRobot_BME68x
import time
from machine import I2C, Pin
class MicroPythonSMBus:
"""Wrapper that translates SMBus method calls to MicroPython machine.I2C calls."""
def __init__(self, i2c_bus):
self.i2c = i2c_bus
def read_byte_data(self, addr, register):
return self.i2c.readfrom_mem(addr, register, 1)[0]
def read_i2c_block_data(self, addr, register, length):
return list(self.i2c.readfrom_mem(addr, register, length))
def write_byte_data(self, addr, register, value):
self.i2c.writeto_mem(addr, register, bytes([value]))
def write_i2c_block_data(self, addr, register, data):
self.i2c.writeto_mem(addr, register, bytes(data))
# Initialize MicroPython I2C
hardware_i2c = I2C(0, scl=Pin(22), sda=Pin(21), freq=100000)
i2c_adapter = MicroPythonSMBus(hardware_i2c)
# Instantiate the sensor using the adapter as i2c_device
sensor = DFRobot_BME68x(i2c_addr=0x76, i2c_device=i2c_adapter)
sensor.set_humidity_oversample(sensor.OS_2X) #Oversampling value: OS_NONE, OS_1X, OS_2X, OS_4X, OS_8X, OS_16X
sensor.set_pressure_oversample(sensor.OS_4X) #Oversampling value: OS_NONE, OS_1X, OS_2X, OS_4X, OS_8X, OS_16X
sensor.set_temperature_oversample(sensor.OS_8X) #Oversampling value: OS_NONE, OS_1X, OS_2X, OS_4X, OS_8X, OS_16X
sensor.set_filter(sensor.FILTER_SIZE_3) #increasing resolution but reducing bandwidth
sensor.set_gas_status(sensor.ENABLE_GAS_MEAS) #1 for enable and 0 for disable
sensor.set_gas_heater_temperature(320) #value:target temperature in degrees celsius, between 200 ~ 400
sensor.set_gas_heater_duration(150) #value:target duration in milliseconds, between 1 and 4032
sensor.select_gas_heater_profile(0) #value:current gas sensor conversion profile: 0 to 9
print("\n\nPolling:")
while True:
if sensor.get_sensor_data():
print("Temperature:", sensor.data.temperature, "°C")
print("Pressure:", sensor.data.pressure, "hPa")
print("Humidity:", sensor.data.humidity, "%")
print("Gas Resistance:", sensor.data.gas_resistance, "Ohms")
time.sleep(5)
In the driver lib I just removed the “import smbus” because it caused issues. The rest remained as it was.
The first readings were around:
Temperature: 28.16 °C
Pressure: 984.41 hPa
Humidity: 50.771 %
Gas Resistance: 12895.426 Ohms
But for every measurement, the Gas Resistance went down.
At some point it reached the 2842.423 Ohms and it’s stuck:
Temperature: 27.41 °C
Pressure: 984.23 hPa
Humidity: 56.042 %
Gas Resistance: 2842.423 Ohms
Similar behavior was when I tried the C library. It was stuck immediately.
2. I tried also the official library in C/C++ from Bosch, so from the: https://github.com/boschsensortec/BME68x_SensorAPI.
Behavior was the same - gas started at some level, then it slowly went down up to 5684.85 Ohm and got stuck on that value. I tried to change the environment, breath on the sensor etc. - nothing happened.
3. I found also a microPython solution from the https://docs.soldered.com/bme688/micropython/examples/ When I run that, the gas changes and it’s not stuck, but it’s totally random, like on the attached screen below. The range is from results like 1870 to 63859684 without any trends and with no signs of stability.

I kept the sensor running for burn-in for around 2 days now.
I'm not sure if that's the:
- sensor issue- software issue- wiring or other electrical issue
Just wanted to ask:
1. Which library is 100% reliable and I should use it for the SEN0629 connected to the ESP32 devkit v1? It can be either C or microPython. I prefer microPython, but if there is no choice, I can use the C/C++ code.
2. Should I still wait a few days for the burn-in?
3. Did anyone face issues like that with the SEN0629 / BME688?
You caught it — Bosch docs are right, bit 5 is run_gas on the BME688. I mixed it up with the BME680 map where it's bit 4 in a different register. Bosch's own forum confirmed the datasheet had a typo on this, so your read is correct.
Since 0x20 has bit 5 set and heater stable is reporting YES, the gas conversion path is genuinely running. You already forced both bits and checked power — at this point the MOX layer is dead. 5600 ohms with a cycling heater and no response to breath ,it mabey means the sensing element itself has failed, not the configuration.
Genius Mensa Einstein Hi, thank you for all the hints and asnwers!
Hi Jason, I connected it to the 5V, directly from the step-down converter, which I use for powering the ESP32. It's capable of providing a few Amperes if necessary.
It didn't help.
I checked bytes and they look fine:
Heater Bit Status (0x71): 0x20 -> Heater ENABLED (OK)
Status Reg (0x2D): 0xFD | Gas Valid: YES | Heater Stable: YES
Gas Resistance: 5600 Ohm (still)
So, if I understand you correctly, there are no other options, and the sensor might be damaged, right?
art.pm 0x71 = 0x20 means bit 4 (run_gas) is 0 — the BME688 isn't actually running gas conversions, which explains the flat 5600 ohms. Check that setGasStatus(ENABLE_GAS_MEAS) is being called after begin() and that the write isn't being clobbered by a later config call. The DFRobot library sets this bit in setGasStatus() but some init sequences overwrite ctrl_gas_1 afterward.
If you force run_gas = 1 and the heater is truly cycling but the resistance still doesn't budge when you breathe on it, the MOX layer is dead — 5600 ohms is way below the typical clean-air baseline (usually 10k–100k) and a stuck value that low usually means the sensing element has degraded.
What I found in the Bosch documentation is that bit 5 in 0x71 indicates the run_gas:
That's why I treated 0x20 as a valid result.
Is that a mistake in the docs?
Anyway, I tried both cases to force the 4th and 5th bits, and it didn't help.
Hi Jason, thank you for the prompt answer.
I tried to run the official DFRobot library in C++.
So, I run that exemplary code from git: https://github.com/DFRobot/DFRobot_BME68x/blob/master/examples/DFRobot_BME68x_I2C/DFRobot_BME68x_I2C.ino
with only one slight change, that address should be 0x76 in my case (not 0x77).
As a result, TPH parameters change, but gas is stuck on the 5600, like:
temperature(C) :27.45
pressure(Pa) :98621.00
humidity(%rh) :62.31
gas resistance(ohm) :5600.00
altitude(m) :241.22
calibrated altitude(m) :523.33
temperature(C) :27.44
pressure(Pa) :98617.00
humidity(%rh) :62.30
gas resistance(ohm) :5600.00
altitude(m) :241.56
calibrated altitude(m) :523.66
temperature(C) :27.43
pressure(Pa) :98617.00
humidity(%rh) :62.30
gas resistance(ohm) :5600.00
altitude(m) :241.56
calibrated altitude(m) :523.66
I tried to change the environment, breath etc. - nothing changes. Even slightly.
Should I still wait more hours for burn-in? Or maybe something is not working?
And one more question - should this board be powered from the 5V, as presented here: https://wiki.dfrobot.com/sen0629/docs/21045
art.pm If the gas resistance is locked at exactly 5600 ohms and doesn't twitch when you breathe on it, the heater isn't firing — not a burn-in issue. The TPH readings work because they draw microamps, but the gas heater pulls 12 mA typical and peaks at 18 mA during the first millisecond of switching on. If your ESP32 devkit's 3.3V rail can't source that spike, the hot plate never reaches 320°C and the resistance stays flat. The DFRobot Wiki wiring diagram shows VCC to 5V for I2C mode — try that instead of 3.3V. The module has an onboard regulator, so the BME688 itself still sees 3.3V, but the 5V input gives the regulator more headroom to handle the heater current spike. Also check that `set_gas_status(ENABLE_GAS_MEAS)` actually took. Some libraries don't verify the write, and if the heater-enable bit didn't stick, the sensor skips the heating phase and returns the same stale resistance value every cycle. The Bosch BME68x API sets `run_gas_h` (bit 4 of ctrl_gas_1, register 0x71) — you can read that register back to confirm it's 1. If you're already on 5V and the bit is set, the sensor itself might be damaged — the MOX layer can degrade if the heater was previously starved or overdriven. But power is the most likely culprit.
The gas resistance dropping and then flattening out is normal MOX behavior — the sensor surface stabilizes during burn-in and the baseline resistance settles. Bosch recommends 48 hours minimum for first use, so your 2 days is right on the edge. The fact that it stabilized around 2800–5700 ohms across different libraries suggests the hardware is fine, not stuck. The wildly random readings from the Soldered MicroPython library (jumping from 1k to 63M) are a software issue — that library isn't handling the BME688's gas heater timing or status flags correctly. Raw gas resistance without proper heater cycle management is meaningless. For a reliable MicroPython setup, the Pimoroni bme680-python library works with the BME688 and handles the heater profiles properly. For IAQ values you'll need Bosch's BSEC algorithm though — raw resistance alone won't give you air quality scores. The DFRobot Arduino library has IAQ support built in if you can switch to C++. If you want to stick with MicroPython, run the sensor for another 24 hours in clean air, then use the Pimoroni library with a fixed heater profile (320°C / 150ms is the default) and track the resistance trend rather than absolute values.
Jason.Miao 
