11namespace bme280_base {
13static const char *
const TAG =
"bme280.sensor";
15static const uint8_t BME280_REGISTER_DIG_T1 = 0x88;
16static const uint8_t BME280_REGISTER_DIG_T2 = 0x8A;
17static const uint8_t BME280_REGISTER_DIG_T3 = 0x8C;
19static const uint8_t BME280_REGISTER_DIG_P1 = 0x8E;
20static const uint8_t BME280_REGISTER_DIG_P2 = 0x90;
21static const uint8_t BME280_REGISTER_DIG_P3 = 0x92;
22static const uint8_t BME280_REGISTER_DIG_P4 = 0x94;
23static const uint8_t BME280_REGISTER_DIG_P5 = 0x96;
24static const uint8_t BME280_REGISTER_DIG_P6 = 0x98;
25static const uint8_t BME280_REGISTER_DIG_P7 = 0x9A;
26static const uint8_t BME280_REGISTER_DIG_P8 = 0x9C;
27static const uint8_t BME280_REGISTER_DIG_P9 = 0x9E;
29static const uint8_t BME280_REGISTER_DIG_H1 = 0xA1;
30static const uint8_t BME280_REGISTER_DIG_H2 = 0xE1;
31static const uint8_t BME280_REGISTER_DIG_H3 = 0xE3;
32static const uint8_t BME280_REGISTER_DIG_H4 = 0xE4;
33static const uint8_t BME280_REGISTER_DIG_H5 = 0xE5;
34static const uint8_t BME280_REGISTER_DIG_H6 = 0xE7;
36static const uint8_t BME280_REGISTER_CHIPID = 0xD0;
37static const uint8_t BME280_REGISTER_RESET = 0xE0;
39static const uint8_t BME280_REGISTER_CONTROLHUMID = 0xF2;
40static const uint8_t BME280_REGISTER_STATUS = 0xF3;
41static const uint8_t BME280_REGISTER_CONTROL = 0xF4;
42static const uint8_t BME280_REGISTER_CONFIG = 0xF5;
43static const uint8_t BME280_REGISTER_MEASUREMENTS = 0xF7;
44static const uint8_t BME280_REGISTER_PRESSUREDATA = 0xF7;
45static const uint8_t BME280_REGISTER_TEMPDATA = 0xFA;
46static const uint8_t BME280_REGISTER_HUMIDDATA = 0xFD;
48static const uint8_t BME280_MODE_FORCED = 0b01;
49static const uint8_t BME280_SOFT_RESET = 0xB6;
50static const uint8_t BME280_STATUS_IM_UPDATE = 0b01;
52inline 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)) {
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.");
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;
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);
virtual void mark_failed()
Mark this component as failed.
void status_set_warning(const char *message="unspecified")
uint32_t component_state_
State of this component.
void status_clear_warning()
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
uint8_t read_u8_(uint8_t a_register)
int16_t read_s16_le_(uint8_t a_register)
BME280IIRFilter iir_filter_
float read_humidity_(const uint8_t *data, int32_t t_fine)
Read the humidity value in % using the provided t_fine value.
virtual bool read_byte(uint8_t a_register, uint8_t *data)=0
virtual bool read_byte_16(uint8_t a_register, uint16_t *data)=0
sensor::Sensor * pressure_sensor_
BME280CalibrationData calibration_
virtual bool write_byte(uint8_t a_register, uint8_t data)=0
void set_iir_filter(BME280IIRFilter iir_filter)
Set the IIR Filter used to increase accuracy, defaults to no IIR Filter.
void set_humidity_oversampling(BME280Oversampling humidity_over_sampling)
Set the oversampling value for the humidity sensor. Default is 16x.
BME280Oversampling temperature_oversampling_
void set_pressure_oversampling(BME280Oversampling pressure_over_sampling)
Set the oversampling value for the pressure sensor. Default is 16x.
BME280Oversampling humidity_oversampling_
float read_pressure_(const uint8_t *data, int32_t t_fine)
Read the pressure value in hPa using the provided t_fine value.
enum esphome::bme280_base::BME280Component::ErrorCode NONE
void set_temperature_oversampling(BME280Oversampling temperature_over_sampling)
Set the oversampling value for the temperature sensor. Default is 16x.
sensor::Sensor * humidity_sensor_
float get_setup_priority() const override
void dump_config() override
BME280Oversampling pressure_oversampling_
sensor::Sensor * temperature_sensor_
uint16_t read_u16_le_(uint8_t a_register)
virtual bool read_bytes(uint8_t a_register, uint8_t *data, size_t len)=0
float read_temperature_(const uint8_t *data, int32_t *t_fine)
Read the temperature value and store the calculated ambient temperature in t_fine.
void publish_state(float state)
Publish a new state to the front-end.
BME280Oversampling
Enum listing all Oversampling values for the BME280.
@ BME280_OVERSAMPLING_16X
@ BME280_OVERSAMPLING_NONE
const char * oversampling_to_str(BME280Oversampling oversampling)
const char * iir_filter_to_str(BME280IIRFilter filter)
uint16_t combine_bytes(uint8_t msb, uint8_t lsb)
uint8_t oversampling_to_time(BME280Oversampling over_sampling)
BME280IIRFilter
Enum listing all Infinite Impulse Filter values for the BME280.
const float DATA
For components that import data from directly connected sensors like DHT.
Providing packet encoding functions for exchanging data with a remote host.
const uint32_t COMPONENT_STATE_FAILED
const uint32_t COMPONENT_STATE_MASK
const uint32_t COMPONENT_STATE_CONSTRUCTION
void IRAM_ATTR HOT delay(uint32_t ms)