10#define BME280_ERROR_WRONG_CHIP_ID "Wrong chip ID"
13namespace bme280_base {
15static const char *
const TAG =
"bme280.sensor";
17static const uint8_t BME280_REGISTER_DIG_T1 = 0x88;
18static const uint8_t BME280_REGISTER_DIG_T2 = 0x8A;
19static const uint8_t BME280_REGISTER_DIG_T3 = 0x8C;
21static const uint8_t BME280_REGISTER_DIG_P1 = 0x8E;
22static const uint8_t BME280_REGISTER_DIG_P2 = 0x90;
23static const uint8_t BME280_REGISTER_DIG_P3 = 0x92;
24static const uint8_t BME280_REGISTER_DIG_P4 = 0x94;
25static const uint8_t BME280_REGISTER_DIG_P5 = 0x96;
26static const uint8_t BME280_REGISTER_DIG_P6 = 0x98;
27static const uint8_t BME280_REGISTER_DIG_P7 = 0x9A;
28static const uint8_t BME280_REGISTER_DIG_P8 = 0x9C;
29static const uint8_t BME280_REGISTER_DIG_P9 = 0x9E;
31static const uint8_t BME280_REGISTER_DIG_H1 = 0xA1;
32static const uint8_t BME280_REGISTER_DIG_H2 = 0xE1;
33static const uint8_t BME280_REGISTER_DIG_H3 = 0xE3;
34static const uint8_t BME280_REGISTER_DIG_H4 = 0xE4;
35static const uint8_t BME280_REGISTER_DIG_H5 = 0xE5;
36static const uint8_t BME280_REGISTER_DIG_H6 = 0xE7;
38static const uint8_t BME280_REGISTER_CHIPID = 0xD0;
39static const uint8_t BME280_REGISTER_RESET = 0xE0;
41static const uint8_t BME280_REGISTER_CONTROLHUMID = 0xF2;
42static const uint8_t BME280_REGISTER_STATUS = 0xF3;
43static const uint8_t BME280_REGISTER_CONTROL = 0xF4;
44static const uint8_t BME280_REGISTER_CONFIG = 0xF5;
45static const uint8_t BME280_REGISTER_MEASUREMENTS = 0xF7;
46static const uint8_t BME280_REGISTER_PRESSUREDATA = 0xF7;
47static const uint8_t BME280_REGISTER_TEMPDATA = 0xFA;
48static const uint8_t BME280_REGISTER_HUMIDDATA = 0xFD;
50static const uint8_t BME280_MODE_FORCED = 0b01;
51static const uint8_t BME280_SOFT_RESET = 0xB6;
52static const uint8_t BME280_STATUS_IM_UPDATE = 0b01;
54inline uint16_t
combine_bytes(uint8_t msb, uint8_t lsb) {
return ((msb & 0xFF) << 8) | (lsb & 0xFF); }
74 switch (oversampling) {
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 this->
mark_failed(
"Error reading status register");
126 }
while ((status & BME280_STATUS_IM_UPDATE) && (--retry));
127 if (
status & BME280_STATUS_IM_UPDATE) {
154 uint8_t humid_control_val = 0;
155 if (!this->
read_byte(BME280_REGISTER_CONTROLHUMID, &humid_control_val)) {
159 humid_control_val &= ~0b00000111;
161 if (!this->
write_byte(BME280_REGISTER_CONTROLHUMID, humid_control_val)) {
166 uint8_t config_register = 0;
167 if (!this->
read_byte(BME280_REGISTER_CONFIG, &config_register)) {
171 config_register &= ~0b11111100;
172 config_register |= 0b101 << 5;
173 config_register |= (this->
iir_filter_ & 0b111) << 2;
174 if (!this->
write_byte(BME280_REGISTER_CONFIG, config_register)) {
180 ESP_LOGCONFIG(TAG,
"BME280:");
181 switch (this->error_code_) {
183 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
186 ESP_LOGE(TAG, BME280_ERROR_WRONG_CHIP_ID);
193 LOG_UPDATE_INTERVAL(
this);
208 ESP_LOGV(TAG,
"Sending conversion request");
209 uint8_t meas_value = 0;
212 meas_value |= BME280_MODE_FORCED;
213 if (!this->
write_byte(BME280_REGISTER_CONTROL, meas_value)) {
218 float meas_time = 1.5f;
223 this->
set_timeout(
"data", uint32_t(ceilf(meas_time)), [
this]() {
225 if (!this->
read_bytes(BME280_REGISTER_MEASUREMENTS, data, 8)) {
226 ESP_LOGW(TAG,
"Error reading registers");
233 ESP_LOGW(TAG,
"Invalid temperature");
240 ESP_LOGV(TAG,
"Temperature=%.1f°C Pressure=%.1fhPa Humidity=%.1f%%",
temperature,
pressure, humidity);
251 int32_t adc = ((data[3] & 0xFF) << 16) | ((data[4] & 0xFF) << 8) | (data[5] & 0xFF);
253 if (adc == 0x80000) {
262 int32_t
const var1 = (((adc >> 3) - (t1 << 1)) * t2) >> 11;
263 int32_t
const var2 = (((((adc >> 4) - t1) * ((adc >> 4) - t1)) >> 12) * t3) >> 14;
264 *t_fine = var1 + var2;
271 int32_t adc = ((data[0] & 0xFF) << 16) | ((data[1] & 0xFF) << 8) | (data[2] & 0xFF);
273 if (adc == 0x80000) {
287 int64_t var1, var2, p;
288 var1 = int64_t(t_fine) - 128000;
289 var2 = var1 * var1 * p6;
290 var2 = var2 + ((var1 * p5) << 17);
291 var2 = var2 + (p4 << 35);
292 var1 = ((var1 * var1 * p3) >> 8) + ((var1 * p2) << 12);
293 var1 = ((int64_t(1) << 47) + var1) * p1 >> 33;
299 p = (((p << 31) - var2) * 3125) / var1;
300 var1 = (p9 * (p >> 13) * (p >> 13)) >> 25;
301 var2 = (p8 * p) >> 19;
303 p = ((p + var1 + var2) >> 8) + (p7 << 4);
304 return (p / 256.0f) / 100.0f;
308 uint16_t
const raw_adc = ((data[6] & 0xFF) << 8) | (data[7] & 0xFF);
309 if (raw_adc == 0x8000)
312 int32_t
const adc = raw_adc;
321 int32_t v_x1_u32r = t_fine - 76800;
323 v_x1_u32r = ((((adc << 14) - (h4 << 20) - (h5 * v_x1_u32r)) + 16384) >> 15) *
324 (((((((v_x1_u32r * h6) >> 10) * (((v_x1_u32r * h3) >> 11) + 32768)) >> 10) + 2097152) * h2 + 8192) >> 14);
326 v_x1_u32r = v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * h1) >> 4);
328 v_x1_u32r = v_x1_u32r < 0 ? 0 : v_x1_u32r;
329 v_x1_u32r = v_x1_u32r > 419430400 ? 419430400 : v_x1_u32r;
330 float const h = v_x1_u32r >> 12;
352 return (data >> 8) | (data << 8);
virtual void mark_failed()
Mark this component as failed.
void status_set_warning(const char *message=nullptr)
void reset_to_construction_state()
Reset this component back to the construction state to allow setup to run again.
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.
void IRAM_ATTR HOT delay(uint32_t ms)