I have been trying for some days to get two BME688 sensors to work together on the same ESP32 device using the BSEC2 library. It’s not obvious (well, to me, at least) how this can be accomplished.
The two devices CAN share the same bus but then they will need different addresses. The BME688 defaults to 0x76. The Pimoroni sensors have a track on the underside that can be cut. The device will then operate at address 0x77.
My aim was different: I wanted to calibrate all my sensors. I have two BME688’s and one SHT45 (The Adafruit Sensiron one using addrress 0x44). The SHT45 is supposed to be accurate to 0.1°C. (However, I have my doubts about this because I believe there are rogue devices out there and no-one knows what happens to the device once it is being soldered onto the breakout board). I’d probably need to buy another SHT45 to be sure… but what then if the two don’t agree? Buy another and go for the “best of three”?
So the BIG CAVEAT is that I am using the SHT45 as a reference sensor against which all the others can be calibrated.
Many of the examples on the web are wrong or misleading at best. Some of the AI generated ones are the worst (as well as being the best).
So I thought I’d share my configuration: it might just help someone trying to do something similar. If you can do better then please add a constructive example for others to try out.
There’s lots of redundant code commented out because this is a work in progress, but it is heavily commented, so should make sense.
Cheers, Ric.
esphome:
name: dht22-bme688x2
friendly_name: DHT22-BME688x2
esp32:
board: esp32dev
framework:
type: esp-idf
# Enable logging
logger:
# Enable Home Assistant API
api:
encryption:
key: "FpbU+Z92yZcre8eFeeLdyUuuVOH0+XAeOyZmf2G6orM="
ota:
- platform: esphome
password: "0ccf2e729daf00d98508c6f6049024e6"
wifi:
ssid: !secret wifi_ssid
password: !secret wifi_password
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Dht22-Bme688X2 Fallback Hotspot"
password: "8zLlrEqOD55a"
captive_portal:
# Configure I2C Buses (required for BME688 Sensor)
i2c:
# ESP32 suppports a maximum of two I2C buses
# Pins are for ESP32-WROOM-32U (38 pin development board + external antenna)
- id: i2c_bus1 # BME688_1 (referenced by and assigned to a specific bsec32 component, below)
sda: GPIO19 # Physical pin 19
scl: GPIO18 # Physical pin 18
scan: true
- id: i2c_bus2 # BME688_2 (referenced by and assigned to a specific bsec32 component, below)
sda: GPIO17 # Physical pin 17
scl: GPIO16 # Physical pin 16
scan: true
# Configure Bosch bsec library components
# Note: the previously defined I2C buses are assigned to each instance of the besc2_i2c component.
bme68x_bsec2_i2c:
- id: bme68x_1 # id of the first component (referenced by and assigned to a particular sensor, below)
i2c_id: i2c_bus1 # first I2C id, defined above - defines which bus and therefore which pins the sensor is attached
address: 0x76
model: bme688
operating_age: 28d
sample_rate: LP
supply_voltage: 3.3V
# Temperature offset (not here because there can be multiple sensors with different offsets)
# ------------------
# Useful if device is in enclosure and reads too high
# Default: 0
#temperature_offset: -0.6
# IAQ calculation mode for BME680 only
# --------------------
# Available options:
# - static (for fixed position devices)
# - mobile (for on person or other moveable devices)
# Default: static
#iaq_mode: static
- id: bme68x_2 # id of the second component (referenced by and assigned to a particular sensor, below)
i2c_id: i2c_bus2 # second I2C id, defined above - defines which bus and therefore which pins the sensor is attached
address: 0x76
model: bme688
operating_age: 28d
sample_rate: LP
supply_voltage: 3.3V
sensor:
- platform: bme68x_bsec2 # BME688_1
# NOTE: No need to specify mode, bus or address, these are all explicit in
# the bsec2 configuration, above
# NOTE: there is NO "update_interval"; see "sample_rate" in bsec2 definition, above
# we must assign one or other of the two BME68xBSEC2 Components, defined above
bme68x_bsec2_id: bme68x_1 # the first component, defined above
temperature:
name: "BME688_1 Temperature"
id: temperature_1
unit_of_measurement: °C
device_class: "temperature"
state_class: "measurement"
accuracy_decimals: 1
#expire_after: 30s
# filters:
# #- offset: -0.6
# #- sliding_window_moving_average:
# # window_size: 15
# # send_every: 15
humidity:
name: "BME688_1 Humidity"
id: humidity_1
unit_of_measurement: "%"
device_class: "humidity"
state_class: "measurement"
accuracy_decimals: 1
pressure:
name: "BME688_1 Raw Pressure"
# Specify the Id to be picked up by the copy
id: pressure_raw_1
unit_of_measurement: hPa
device_class: "pressure"
state_class: "measurement"
accuracy_decimals: 1
iaq:
name: "BME688_1 IAQ"
id: iaq_1
accuracy_decimals: 0
co2_equivalent:
name: "BME688_1 CO2 Equivalent"
id: co2_equivalent_1
accuracy_decimals: 0
breath_voc_equivalent:
name: "BME688_1 Breath VOC Equivalent"
id: breath_voc_equivalent_1
accuracy_decimals: 1
- platform: copy
# altitude adjustment for local pressure
source_id: pressure_raw_1
name: "BME688_1 Adjusted Pressure"
id: pressure_adjusted_1
filters:
- offset: 20.2 # calculated from altitude dfference (40m) to reference weather station at STP
#- lambda: return x ....... etc;
- platform: bme68x_bsec2 # BME688_2
# NOTE: No need to specify mode, bus or address, these are all explicit in
# the bsec2 configuration, above
# NOTE: there is NO "update_interval"; see "sample_rate" in bsec2 definition, above
# we must assign one or other of the two BME68xBSEC2 Components, defined above
bme68x_bsec2_id: bme68x_2 # the second component, defined above
temperature:
name: "BME688_2 Temperature"
id: temperature_2
unit_of_measurement: °C
device_class: "temperature"
state_class: "measurement"
accuracy_decimals: 1
#expire_after: 30s
# filters:
# #- offset: -0.6
# #- sliding_window_moving_average:
# # window_size: 15
# # send_every: 15
humidity:
name: "BME688_2 Humidity"
id: humidity_2
unit_of_measurement: "%"
device_class: "humidity"
state_class: "measurement"
accuracy_decimals: 1
pressure:
name: "BME688_2 Raw Pressure"
# Specify the Id to be picked up by the copy
id: pressure_raw_2
unit_of_measurement: hPa
device_class: "pressure"
state_class: "measurement"
accuracy_decimals: 1
iaq:
name: "BME688_2 IAQ"
id: iaq_2
accuracy_decimals: 0
co2_equivalent:
name: "BME688_2 CO2 Equivalent"
id: co2_equivalent_2
accuracy_decimals: 0
breath_voc_equivalent:
name: "BME688_2 Breath VOC Equivalent"
id: breath_voc_equivalent_2
accuracy_decimals: 1
- platform: copy
# altitude adjustment for local pressure
source_id: pressure_raw_2
name: "BME688_2 Adjusted Pressure"
id: pressure_adjusted_2
filters:
- offset: 20.2 # calculated from altitude dfference (40m) to reference weather station at STP (1013hPA, etc...). THIS IS NOT A CALIBRATION OFFSET.
#- lambda: "return x +
Note: nothing secret about the passwords here. The setup is a throwaway device that will not be used for production.
Spot any errors? Let me know.