11 namespace bme280_base {
13 static const char *
const TAG =
"bme280.sensor";
15 static const uint8_t BME280_REGISTER_DIG_T1 = 0x88;
16 static const uint8_t BME280_REGISTER_DIG_T2 = 0x8A;
17 static const uint8_t BME280_REGISTER_DIG_T3 = 0x8C;
19 static const uint8_t BME280_REGISTER_DIG_P1 = 0x8E;
20 static const uint8_t BME280_REGISTER_DIG_P2 = 0x90;
21 static const uint8_t BME280_REGISTER_DIG_P3 = 0x92;
22 static const uint8_t BME280_REGISTER_DIG_P4 = 0x94;
23 static const uint8_t BME280_REGISTER_DIG_P5 = 0x96;
24 static const uint8_t BME280_REGISTER_DIG_P6 = 0x98;
25 static const uint8_t BME280_REGISTER_DIG_P7 = 0x9A;
26 static const uint8_t BME280_REGISTER_DIG_P8 = 0x9C;
27 static const uint8_t BME280_REGISTER_DIG_P9 = 0x9E;
29 static const uint8_t BME280_REGISTER_DIG_H1 = 0xA1;
30 static const uint8_t BME280_REGISTER_DIG_H2 = 0xE1;
31 static const uint8_t BME280_REGISTER_DIG_H3 = 0xE3;
32 static const uint8_t BME280_REGISTER_DIG_H4 = 0xE4;
33 static const uint8_t BME280_REGISTER_DIG_H5 = 0xE5;
34 static const uint8_t BME280_REGISTER_DIG_H6 = 0xE7;
36 static const uint8_t BME280_REGISTER_CHIPID = 0xD0;
37 static const uint8_t BME280_REGISTER_RESET = 0xE0;
39 static const uint8_t BME280_REGISTER_CONTROLHUMID = 0xF2;
40 static const uint8_t BME280_REGISTER_STATUS = 0xF3;
41 static const uint8_t BME280_REGISTER_CONTROL = 0xF4;
42 static const uint8_t BME280_REGISTER_CONFIG = 0xF5;
43 static const uint8_t BME280_REGISTER_MEASUREMENTS = 0xF7;
44 static const uint8_t BME280_REGISTER_PRESSUREDATA = 0xF7;
45 static const uint8_t BME280_REGISTER_TEMPDATA = 0xFA;
46 static const uint8_t BME280_REGISTER_HUMIDDATA = 0xFD;
48 static const uint8_t BME280_MODE_FORCED = 0b01;
49 static const uint8_t BME280_SOFT_RESET = 0xB6;
50 static const uint8_t BME280_STATUS_IM_UPDATE = 0b01;
52 inline uint16_t
combine_bytes(uint8_t msb, uint8_t lsb) {
return ((msb & 0xFF) << 8) | (lsb & 0xFF); }
72 switch (oversampling) {
91 ESP_LOGCONFIG(TAG,
"Setting up BME280...");
101 if (!this->
read_byte(BME280_REGISTER_CHIPID, &chip_id)) {
106 if (chip_id != 0x60) {
113 if (!this->
write_byte(BME280_REGISTER_RESET, BME280_SOFT_RESET)) {
122 if (!this->
read_byte(BME280_REGISTER_STATUS, &status)) {
123 ESP_LOGW(TAG,
"Error reading status register.");
127 }
while ((status & BME280_STATUS_IM_UPDATE) && (--retry));
128 if (status & BME280_STATUS_IM_UPDATE) {
129 ESP_LOGW(TAG,
"Timeout loading NVM.");
156 uint8_t humid_control_val = 0;
157 if (!this->
read_byte(BME280_REGISTER_CONTROLHUMID, &humid_control_val)) {
161 humid_control_val &= ~0b00000111;
163 if (!this->
write_byte(BME280_REGISTER_CONTROLHUMID, humid_control_val)) {
168 uint8_t config_register = 0;
169 if (!this->
read_byte(BME280_REGISTER_CONFIG, &config_register)) {
173 config_register &= ~0b11111100;
174 config_register |= 0b101 << 5;
175 config_register |= (this->
iir_filter_ & 0b111) << 2;
176 if (!this->
write_byte(BME280_REGISTER_CONFIG, config_register)) {
182 ESP_LOGCONFIG(TAG,
"BME280:");
183 switch (this->error_code_) {
185 ESP_LOGE(TAG,
"Communication with BME280 failed!");
188 ESP_LOGE(TAG,
"BME280 has wrong chip ID! Is it a BME280?");
195 LOG_UPDATE_INTERVAL(
this);
210 ESP_LOGV(TAG,
"Sending conversion request...");
211 uint8_t meas_value = 0;
214 meas_value |= BME280_MODE_FORCED;
215 if (!this->
write_byte(BME280_REGISTER_CONTROL, meas_value)) {
220 float meas_time = 1.5f;
225 this->
set_timeout(
"data", uint32_t(ceilf(meas_time)), [
this]() {
227 if (!this->
read_bytes(BME280_REGISTER_MEASUREMENTS, data, 8)) {
228 ESP_LOGW(TAG,
"Error reading registers.");
234 if (std::isnan(temperature)) {
235 ESP_LOGW(TAG,
"Invalid temperature, cannot read pressure & humidity values.");
242 ESP_LOGV(TAG,
"Got temperature=%.1f°C pressure=%.1fhPa humidity=%.1f%%", temperature, pressure, humidity);
253 int32_t adc = ((data[3] & 0xFF) << 16) | ((data[4] & 0xFF) << 8) | (data[5] & 0xFF);
255 if (adc == 0x80000) {
264 int32_t
const var1 = (((adc >> 3) - (t1 << 1)) * t2) >> 11;
265 int32_t
const var2 = (((((adc >> 4) - t1) * ((adc >> 4) - t1)) >> 12) * t3) >> 14;
266 *t_fine = var1 + var2;
269 return temperature / 25600.0f;
273 int32_t adc = ((data[0] & 0xFF) << 16) | ((data[1] & 0xFF) << 8) | (data[2] & 0xFF);
275 if (adc == 0x80000) {
289 int64_t var1, var2, p;
290 var1 = int64_t(t_fine) - 128000;
291 var2 = var1 * var1 * p6;
292 var2 = var2 + ((var1 * p5) << 17);
293 var2 = var2 + (p4 << 35);
294 var1 = ((var1 * var1 * p3) >> 8) + ((var1 * p2) << 12);
295 var1 = ((int64_t(1) << 47) + var1) * p1 >> 33;
301 p = (((p << 31) - var2) * 3125) / var1;
302 var1 = (p9 * (p >> 13) * (p >> 13)) >> 25;
303 var2 = (p8 * p) >> 19;
305 p = ((p + var1 + var2) >> 8) + (p7 << 4);
306 return (p / 256.0f) / 100.0f;
310 uint16_t
const raw_adc = ((data[6] & 0xFF) << 8) | (data[7] & 0xFF);
311 if (raw_adc == 0x8000)
314 int32_t
const adc = raw_adc;
323 int32_t v_x1_u32r = t_fine - 76800;
325 v_x1_u32r = ((((adc << 14) - (h4 << 20) - (h5 * v_x1_u32r)) + 16384) >> 15) *
326 (((((((v_x1_u32r * h6) >> 10) * (((v_x1_u32r * h3) >> 11) + 32768)) >> 10) + 2097152) * h2 + 8192) >> 14);
328 v_x1_u32r = v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * h1) >> 4);
330 v_x1_u32r = v_x1_u32r < 0 ? 0 : v_x1_u32r;
331 v_x1_u32r = v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r;
332 float const h = v_x1_u32r >> 12;
354 return (data >> 8) | (data << 8);
const uint32_t COMPONENT_STATE_FAILED
virtual bool read_bytes(uint8_t a_register, uint8_t *data, size_t len)=0
const float DATA
For components that import data from directly connected sensors like DHT.
void status_set_warning(const char *message="unspecified")
BME280Oversampling pressure_oversampling_
const char * iir_filter_to_str(BME280IIRFilter filter)
uint16_t read_u16_le_(uint8_t a_register)
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
void set_temperature_oversampling(BME280Oversampling temperature_over_sampling)
Set the oversampling value for the temperature sensor. Default is 16x.
virtual bool write_byte(uint8_t a_register, uint8_t data)=0
sensor::Sensor * temperature_sensor_
float read_temperature_(const uint8_t *data, int32_t *t_fine)
Read the temperature value and store the calculated ambient temperature in t_fine.
BME280Oversampling humidity_oversampling_
BME280IIRFilter iir_filter_
virtual bool read_byte_16(uint8_t a_register, uint16_t *data)=0
BME280IIRFilter
Enum listing all Infinite Impulse Filter values for the BME280.
int16_t read_s16_le_(uint8_t a_register)
uint32_t component_state_
State of this component.
void dump_config() override
BME280CalibrationData calibration_
void status_clear_warning()
const uint32_t COMPONENT_STATE_CONSTRUCTION
float read_humidity_(const uint8_t *data, int32_t t_fine)
Read the humidity value in % using the provided t_fine value.
void publish_state(float state)
Publish a new state to the front-end.
void set_humidity_oversampling(BME280Oversampling humidity_over_sampling)
Set the oversampling value for the humidity sensor. Default is 16x.
sensor::Sensor * humidity_sensor_
const uint32_t COMPONENT_STATE_MASK
sensor::Sensor * pressure_sensor_
BME280Oversampling
Enum listing all Oversampling values for the BME280.
virtual void mark_failed()
Mark this component as failed.
void set_iir_filter(BME280IIRFilter iir_filter)
Set the IIR Filter used to increase accuracy, defaults to no IIR Filter.
Implementation of SPI Controller mode.
BME280Oversampling temperature_oversampling_
float read_pressure_(const uint8_t *data, int32_t t_fine)
Read the pressure value in hPa using the provided t_fine value.
const char * oversampling_to_str(BME280Oversampling oversampling)
uint8_t read_u8_(uint8_t a_register)
uint8_t oversampling_to_time(BME280Oversampling over_sampling)
enum esphome::bme280_base::BME280Component::ErrorCode NONE
virtual bool read_byte(uint8_t a_register, uint8_t *data)=0
void IRAM_ATTR HOT delay(uint32_t ms)
void set_pressure_oversampling(BME280Oversampling pressure_over_sampling)
Set the oversampling value for the pressure sensor. Default is 16x.
uint16_t combine_bytes(uint8_t msb, uint8_t lsb)
float get_setup_priority() const override