8000 Merge pull request #40 from pimoroni/patch-high-gas-support · pimoroni/bme680-python@3772b5c · GitHub
[go: up one dir, main page]

Skip to content

Commit 3772b5c

Browse files
authored
Merge pull request #40 from pimoroni/patch-high-gas-support
Support for low/high gas variants
2 parents f1d671e + b79558c commit 3772b5c

File tree

3 files changed

+74
-11
lines changed

3 files changed

+74
-11
lines changed

library/bme680/__init__.py

Lines changed: 56 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ def __init__(self, i2c_addr=constants.I2C_ADDR_PRIMARY, i2c_device=None):
4949
except IOError:
5050
raise RuntimeError("Unable to identify BME680 at 0x{:02x} (IOError)".format(self.i2c_addr))
5151

52+
self._variant = self._get_regs(constants.CHIP_VARIANT_ADDR, 1)
53+
5254
self.soft_reset()
5355
self.set_power_mode(constants.SLEEP_MODE)
5456

@@ -58,7 +60,10 @@ def __init__(self, i2c_addr=constants.I2C_ADDR_PRIMARY, i2c_device=None):
5860
self.set_pressure_oversample(constants.OS_4X)
5961
self.set_temperature_oversample(constants.OS_8X)
6062
self.set_filter(constants.FILTER_SIZE_3)
61-
self.set_gas_status(constants.ENABLE_GAS_MEAS)
63+
if self._variant == constants.VARIANT_HIGH:
64+
self.set_gas_status(constants.ENABLE_GAS_MEAS_HIGH)
65+
else:
66+
self.set_gas_status(constants.ENABLE_GAS_MEAS_LOW)
6267
self.set_temp_offset(0)
6368
self.get_sensor_data()
6469

@@ -197,6 +202,11 @@ def get_gas_heater_status(self):
197202

198203
def set_gas_status(self, value):
199204
"""Enable/disable gas sensor."""
205+
if value == -1:
206+
if self._variant == constants.VARIANT_HIGH:
207+
value = constants.ENABLE_GAS_MEAS_HIGH
208+
else:
209+
value = constants.ENABLE_GAS_MEAS_LOW
200210
self.gas_settings.run_gas = value
201211
self._set_bits(constants.CONF_ODR_RUN_GAS_NBC_ADDR, constants.RUN_GAS_MSK, constants.RUN_GAS_POS, value)
202212

@@ -292,11 +302,17 @@ def get_sensor_data(self):
292302
adc_pres = (regs[2] << 12) | (regs[3] << 4) | (regs[4] >> 4)
293303
adc_temp = (regs[5] << 12) | (regs[6] << 4) | (regs[7] >> 4)
294304
adc_hum = (regs[8] << 8) | regs[9]
295-
adc_gas_res = (regs[13] << 2) | (regs[14] >> 6)
296-
gas_range = regs[14] & constants.GAS_RANGE_MSK
297-
298-
self.data.status |= regs[14] & constants.GASM_VALID_MSK
299-
self.data.status |= regs[14] & constants.HEAT_STAB_MSK
305+
adc_gas_res_low = (regs[13] << 2) | (regs[14] >> 6)
306+
adc_gas_res_high = (regs[15] << 2) | (regs[16] >> 6)
307+
gas_range_l = regs[14] & constants.GAS_RANGE_MSK
308+
gas_range_h = regs[16] & constants.GAS_RANGE_MSK
309+
310+
if self._variant == constants.VARIANT_HIGH:
311+
self.data.status |= regs[16] & constants.GASM_VALID_MSK
312+
self.data.status |= regs[16] & constants.HEAT_STAB_MSK
313+
else:
314+
self.data.status |= regs[14] & constants.GASM_VALID_MSK
315+
self.data.status |= regs[14] & constants.HEAT_STAB_MSK
300316

301317
self.data.heat_stable = (self.data.status & constants.HEAT_STAB_MSK) > 0
302318

@@ -306,7 +322,12 @@ def get_sensor_data(self):
306322

307323
self.data.pressure = self._calc_pressure(adc_pres) / 100.0
308324
self.data.humidity = self._calc_humidity(adc_hum) / 1000.0
309-
self.data.gas_resistance = self._calc_gas_resistance(adc_gas_res, gas_range)
325+
326+
if self._variant == constants.VARIANT_HIGH:
327+
self.data.gas_resistance = self._calc_gas_resistance_high(adc_gas_res_high, gas_range_h)
328+
else:
329+
self.data.gas_resistance = self._calc_gas_resistance_low(adc_gas_res_low, gas_range_l)
330+
310331
return True
311332

312333
return False
@@ -399,6 +420,34 @@ def _calc_humidity(self, humidity_adc):
399420

400421
def _calc_gas_resistance(self, gas_res_adc, gas_range):
401422
"""Convert the raw gas resistance using calibration data."""
423+
if self._variant == constants.VARIANT_HIGH:
424+
return self._calc_gas_resistance_high(gas_res_adc, gas_range)
425+
else:
426+
return self._calc_gas_resistance_low(gas_res_adc, gas_range)
427+
428+
def _calc_gas_resistance_high(self, gas_res_adc, gas_range):
429+
"""Convert the raw gas resistance using calibration data.
430+
431+
Applies to Variant ID == 0x01 only.
432+
433+
"""
434+
var1 = 262144 >> gas_range
435+
var2 = gas_res_adc - 512
436+
437+
var2 *= 3
438+
var2 = 4096 + var2
439+
440+
calc_gas_res = (10000 * var1) / var2
441+
calc_gas_res *= 100
442+
443+
return calc_gas_res
444+
445+
def _calc_gas_resistance_low(self, gas_res_adc, gas_range):
446+
"""Convert the raw gas resistance using calibration data.
447+
448+
Applies to Variant ID == 0x00 only.
449+
450+
"""
402451
var1 = ((1340 + (5 * self.calibration_data.range_sw_err)) * (lookupTable1[gas_range])) >> 16
403452
var2 = (((gas_res_adc << 15) - (16777216)) + var1)
404453
var3 = ((lookupTable2[gas_range] * var1) >> 9)

library/bme680/constants.py

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
COEFF_ADDR2_LEN = 16
1717

1818
# BME680 field_x related defines
19-
FIELD_LENGTH = 15
19+
FIELD_LENGTH = 17
2020
FIELD_ADDR_OFFSET = 17
2121

2222
# Soft reset command
@@ -67,6 +67,10 @@
6767

6868
# Chip identifier
6969
CHIP_ID_ADDR = 0xd0
70+
CHIP_VARIANT_ADDR = 0xf0
71+
72+
VARIANT_LOW = 0x00
73+
VARIANT_HIGH = 0x01
7074

7175
# Soft reset register
7276
SOFT_RESET_ADDR = 0xe0
@@ -77,7 +81,9 @@
7781

7882
# Gas measurement settings
7983
DISABLE_GAS_MEAS = 0x00
80-
ENABLE_GAS_MEAS = 0x01
84+
ENABLE_GAS_MEAS = -1 # Now used as auto-select
85+
ENABLE_GAS_MEAS_LOW = 0x01
86+
ENABLE_GAS_MEAS_HIGH = 0x02
8187

8288
# Over-sampling settings
8389
OS_NONE = 0
@@ -145,7 +151,7 @@
145151
OSP_MSK = 0X1C
146152
OSH_MSK = 0X07
147153
HCTRL_MSK = 0x08
148-
RUN_GAS_MSK = 0x10
154+
RUN_GAS_MSK = 0x30
149155
MODE_MSK = 0x03
150156
RHRANGE_MSK = 0x30
151157
RSERROR_MSK = 0xf0

library/tests/test_compensation.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,21 @@ def test_calc_humidity(smbus, calibration):
2525
assert sensor._calc_humidity(19019) == 42402
2626

2727

28-
def test_calc_gas_resistance(smbus, calibration):
28+
def test_calc_gas_resistance_low(smbus, calibration):
2929
"""Validate gas calculation against mock calibration data."""
3030
sensor = bme680.BME680()
3131
sensor.calibration_data = calibration
3232
assert int(sensor._calc_gas_resistance(0, 0)) == 12946860
3333

3434

35+
def test_calc_gas_resistance_high(smbus, calibration):
36+
"""Validate gas calculation against mock calibration data."""
37+
sensor = bme680.BME680()
38+
sensor.calibration_data = calibration
39+
sensor._variant = 1
40+
assert int(sensor._calc_gas_resistance(0, 0)) == 102400000
41+
42+
3543
def test_temp_offset(smbus, calibration):
3644
"""Validate temperature calculation with offset against mock calibration data."""
3745
sensor = bme680.BME680()

0 commit comments

Comments
 (0)
0