ESPHome  2024.10.2
bme680.cpp
Go to the documentation of this file.
1 #include "bme680.h"
2 #include "esphome/core/hal.h"
3 #include "esphome/core/log.h"
4 
5 namespace esphome {
6 namespace bme680 {
7 
8 static const char *const TAG = "bme680.sensor";
9 
10 static const uint8_t BME680_REGISTER_COEFF1 = 0x89;
11 static const uint8_t BME680_REGISTER_COEFF2 = 0xE1;
12 
13 static const uint8_t BME680_REGISTER_CONFIG = 0x75;
14 static const uint8_t BME680_REGISTER_CONTROL_MEAS = 0x74;
15 static const uint8_t BME680_REGISTER_CONTROL_HUMIDITY = 0x72;
16 static const uint8_t BME680_REGISTER_CONTROL_GAS1 = 0x71;
17 static const uint8_t BME680_REGISTER_CONTROL_GAS0 = 0x70;
18 static const uint8_t BME680_REGISTER_HEATER_HEAT0 = 0x5A;
19 static const uint8_t BME680_REGISTER_HEATER_WAIT0 = 0x64;
20 
21 static const uint8_t BME680_REGISTER_CHIPID = 0xD0;
22 
23 static const uint8_t BME680_REGISTER_FIELD0 = 0x1D;
24 
25 const float BME680_GAS_LOOKUP_TABLE_1[16] PROGMEM = {0.0, 0.0, 0.0, 0.0, 0.0, -1.0, 0.0, -0.8,
26  0.0, 0.0, -0.2, -0.5, 0.0, -1.0, 0.0, 0.0};
27 
28 const float BME680_GAS_LOOKUP_TABLE_2[16] PROGMEM = {0.0, 0.0, 0.0, 0.0, 0.1, 0.7, 0.0, -0.8,
29  -0.1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
30 
31 static const char *oversampling_to_str(BME680Oversampling oversampling) {
32  switch (oversampling) {
34  return "None";
36  return "1x";
38  return "2x";
40  return "4x";
42  return "8x";
44  return "16x";
45  default:
46  return "UNKNOWN";
47  }
48 }
49 
50 static const char *iir_filter_to_str(BME680IIRFilter filter) {
51  switch (filter) {
53  return "OFF";
55  return "1x";
57  return "3x";
59  return "7x";
61  return "15x";
63  return "31x";
65  return "63x";
67  return "127x";
68  default:
69  return "UNKNOWN";
70  }
71 }
72 
74  ESP_LOGCONFIG(TAG, "Setting up BME680...");
75  uint8_t chip_id;
76  if (!this->read_byte(BME680_REGISTER_CHIPID, &chip_id) || chip_id != 0x61) {
77  this->mark_failed();
78  return;
79  }
80 
81  // Read calibration
82  uint8_t cal1[25];
83  if (!this->read_bytes(BME680_REGISTER_COEFF1, cal1, 25)) {
84  this->mark_failed();
85  return;
86  }
87  uint8_t cal2[16];
88  if (!this->read_bytes(BME680_REGISTER_COEFF2, cal2, 16)) {
89  this->mark_failed();
90  return;
91  }
92 
93  this->calibration_.t1 = cal2[9] << 8 | cal2[8];
94  this->calibration_.t2 = cal1[2] << 8 | cal1[1];
95  this->calibration_.t3 = cal1[3];
96 
97  this->calibration_.h1 = cal2[2] << 4 | (cal2[1] & 0x0F);
98  this->calibration_.h2 = cal2[0] << 4 | cal2[1] >> 4;
99  this->calibration_.h3 = cal2[3];
100  this->calibration_.h4 = cal2[4];
101  this->calibration_.h5 = cal2[5];
102  this->calibration_.h6 = cal2[6];
103  this->calibration_.h7 = cal2[7];
104 
105  this->calibration_.p1 = cal1[6] << 8 | cal1[5];
106  this->calibration_.p2 = cal1[8] << 8 | cal1[7];
107  this->calibration_.p3 = cal1[9];
108  this->calibration_.p4 = cal1[12] << 8 | cal1[11];
109  this->calibration_.p5 = cal1[14] << 8 | cal1[13];
110  this->calibration_.p6 = cal1[16];
111  this->calibration_.p7 = cal1[15];
112  this->calibration_.p8 = cal1[20] << 8 | cal1[19];
113  this->calibration_.p9 = cal1[22] << 8 | cal1[21];
114  this->calibration_.p10 = cal1[23];
115 
116  this->calibration_.gh1 = cal2[14];
117  this->calibration_.gh2 = cal2[12] << 8 | cal2[13];
118  this->calibration_.gh3 = cal2[15];
119 
120  uint8_t temp_var = 0;
121  if (!this->read_byte(0x02, &temp_var)) {
122  this->mark_failed();
123  return;
124  }
125  this->calibration_.res_heat_range = ((temp_var & 0x30) / 16);
126 
127  if (!this->read_byte(0x00, &temp_var)) {
128  this->mark_failed();
129  return;
130  }
131  this->calibration_.res_heat_val = (int8_t) temp_var;
132 
133  if (!this->read_byte(0x04, &temp_var)) {
134  this->mark_failed();
135  return;
136  }
137  this->calibration_.range_sw_err = ((int8_t) temp_var & (int8_t) 0xf0) / 16;
138 
139  this->calibration_.ambient_temperature = 25; // prime ambient temperature
140 
141  // Config register
142  uint8_t config_register;
143  if (!this->read_byte(BME680_REGISTER_CONFIG, &config_register)) {
144  this->mark_failed();
145  return;
146  }
147  config_register &= ~0b00011100;
148  config_register |= (this->iir_filter_ & 0b111) << 2;
149  if (!this->write_byte(BME680_REGISTER_CONFIG, config_register)) {
150  this->mark_failed();
151  return;
152  }
153 
154  // Humidity control register
155  uint8_t hum_control;
156  if (!this->read_byte(BME680_REGISTER_CONTROL_HUMIDITY, &hum_control)) {
157  this->mark_failed();
158  return;
159  }
160  hum_control &= ~0b00000111;
161  hum_control |= this->humidity_oversampling_ & 0b111;
162  if (!this->write_byte(BME680_REGISTER_CONTROL_HUMIDITY, hum_control)) {
163  this->mark_failed();
164  return;
165  }
166 
167  // Gas 1 control register
168  uint8_t gas1_control;
169  if (!this->read_byte(BME680_REGISTER_CONTROL_GAS1, &gas1_control)) {
170  this->mark_failed();
171  return;
172  }
173  gas1_control &= ~0b00011111;
174  gas1_control |= 1 << 4;
175  gas1_control |= 0; // profile 0
176  if (!this->write_byte(BME680_REGISTER_CONTROL_GAS1, gas1_control)) {
177  this->mark_failed();
178  return;
179  }
180 
181  const bool heat_off = this->heater_temperature_ == 0 || this->heater_duration_ == 0;
182 
183  // Gas 0 control register
184  uint8_t gas0_control;
185  if (!this->read_byte(BME680_REGISTER_CONTROL_GAS0, &gas0_control)) {
186  this->mark_failed();
187  return;
188  }
189  gas0_control &= ~0b00001000;
190  gas0_control |= heat_off << 3;
191  if (!this->write_byte(BME680_REGISTER_CONTROL_GAS0, gas0_control)) {
192  this->mark_failed();
193  return;
194  }
195 
196  if (!heat_off) {
197  // Gas Heater Temperature
199  if (!this->write_byte(BME680_REGISTER_HEATER_HEAT0, temperature)) {
200  this->mark_failed();
201  return;
202  }
203 
204  // Gas Heater Duration
205  uint8_t duration = this->calc_heater_duration_(this->heater_duration_);
206 
207  if (!this->write_byte(BME680_REGISTER_HEATER_WAIT0, duration)) {
208  this->mark_failed();
209  return;
210  }
211  }
212 }
213 
215  ESP_LOGCONFIG(TAG, "BME680:");
216  LOG_I2C_DEVICE(this);
217  if (this->is_failed()) {
218  ESP_LOGE(TAG, "Communication with BME680 failed!");
219  }
220  ESP_LOGCONFIG(TAG, " IIR Filter: %s", iir_filter_to_str(this->iir_filter_));
221  LOG_UPDATE_INTERVAL(this);
222 
223  LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
224  ESP_LOGCONFIG(TAG, " Oversampling: %s", oversampling_to_str(this->temperature_oversampling_));
225  LOG_SENSOR(" ", "Pressure", this->pressure_sensor_);
226  ESP_LOGCONFIG(TAG, " Oversampling: %s", oversampling_to_str(this->pressure_oversampling_));
227  LOG_SENSOR(" ", "Humidity", this->humidity_sensor_);
228  ESP_LOGCONFIG(TAG, " Oversampling: %s", oversampling_to_str(this->humidity_oversampling_));
229  LOG_SENSOR(" ", "Gas Resistance", this->gas_resistance_sensor_);
230  if (this->heater_duration_ == 0 || this->heater_temperature_ == 0) {
231  ESP_LOGCONFIG(TAG, " Heater OFF");
232  } else {
233  ESP_LOGCONFIG(TAG, " Heater temperature=%u°C duration=%ums", this->heater_temperature_, this->heater_duration_);
234  }
235 }
236 
238 
240  uint8_t meas_control = 0; // No need to fetch, we're setting all fields
241  meas_control |= (this->temperature_oversampling_ & 0b111) << 5;
242  meas_control |= (this->pressure_oversampling_ & 0b111) << 2;
243  meas_control |= 0b01; // forced mode
244  if (!this->write_byte(BME680_REGISTER_CONTROL_MEAS, meas_control)) {
245  this->status_set_warning();
246  return;
247  }
248 
249  this->set_timeout("data", this->calc_meas_duration_(), [this]() { this->read_data_(); });
250 }
251 
253  if (temperature < 200)
254  temperature = 200;
255  if (temperature > 400)
256  temperature = 400;
257 
258  const int8_t ambient_temperature = this->calibration_.ambient_temperature;
259  const int8_t gh1 = this->calibration_.gh1;
260  const int16_t gh2 = this->calibration_.gh2;
261  const int8_t gh3 = this->calibration_.gh3;
262  const uint8_t res_heat_range = this->calibration_.res_heat_range;
263  const int8_t res_heat_val = this->calibration_.res_heat_val;
264 
265  uint8_t heatr_res;
266  int32_t var1;
267  int32_t var2;
268  int32_t var3;
269  int32_t var4;
270  int32_t var5;
271  int32_t heatr_res_x100;
272 
273  var1 = (((int32_t) ambient_temperature * gh3) / 1000) * 256;
274  var2 = (gh1 + 784) * (((((gh2 + 154009) * temperature * 5) / 100) + 3276800) / 10);
275  var3 = var1 + (var2 / 2);
276  var4 = (var3 / (res_heat_range + 4));
277  var5 = (131 * res_heat_val) + 65536;
278  heatr_res_x100 = (int32_t) (((var4 / var5) - 250) * 34);
279  heatr_res = (uint8_t) ((heatr_res_x100 + 50) / 100);
280 
281  return heatr_res;
282 }
283 uint8_t BME680Component::calc_heater_duration_(uint16_t duration) {
284  uint8_t factor = 0;
285  uint8_t duration_value;
286 
287  if (duration >= 0xfc0) {
288  duration_value = 0xff;
289  } else {
290  while (duration > 0x3F) {
291  duration /= 4;
292  factor += 1;
293  }
294  duration_value = duration + (factor * 64);
295  }
296 
297  return duration_value;
298 }
300  uint8_t data[15];
301  if (!this->read_bytes(BME680_REGISTER_FIELD0, data, 15)) {
302  if (this->temperature_sensor_ != nullptr)
304  if (this->pressure_sensor_ != nullptr)
305  this->pressure_sensor_->publish_state(NAN);
306  if (this->humidity_sensor_ != nullptr)
307  this->humidity_sensor_->publish_state(NAN);
308  if (this->gas_resistance_sensor_ != nullptr)
310  ESP_LOGW(TAG, "Communication with BME680 failed!");
311  this->status_set_warning();
312  return;
313  }
314  this->status_clear_warning();
315 
316  uint32_t raw_temperature = (uint32_t(data[5]) << 12) | (uint32_t(data[6]) << 4) | (uint32_t(data[7]) >> 4);
317  uint32_t raw_pressure = (uint32_t(data[2]) << 12) | (uint32_t(data[3]) << 4) | (uint32_t(data[4]) >> 4);
318  uint32_t raw_humidity = (uint32_t(data[8]) << 8) | uint32_t(data[9]);
319  uint16_t raw_gas = (uint16_t) ((uint32_t) data[13] * 4 | (((uint32_t) data[14]) / 64));
320  uint8_t gas_range = data[14] & 0x0F;
321 
322  float temperature = this->calc_temperature_(raw_temperature);
323  float pressure = this->calc_pressure_(raw_pressure);
324  float humidity = this->calc_humidity_(raw_humidity);
325  float gas_resistance = this->calc_gas_resistance_(raw_gas, gas_range);
326 
327  bool gas_valid = (data[14] >> 5) & 1;
328  bool heat_stable = (data[14] >> 4) & 1;
329  if (this->heater_temperature_ == 0 || this->heater_duration_ == 0)
330  heat_stable = true; // Allow reporting gas resistance when heater is disabled
331 
332  ESP_LOGD(TAG, "Got temperature=%.1f°C pressure=%.1fhPa humidity=%.1f%% gas_resistance=%.1fΩ", temperature, pressure,
333  humidity, gas_resistance);
334  if (!gas_valid)
335  ESP_LOGW(TAG, "Gas measurement unsuccessful, reading invalid!");
336  if (!heat_stable)
337  ESP_LOGW(TAG, "Heater unstable, reading invalid! (Normal for a few readings after a power cycle)");
338 
339  if (this->temperature_sensor_ != nullptr)
340  this->temperature_sensor_->publish_state(temperature);
341  if (this->pressure_sensor_ != nullptr)
342  this->pressure_sensor_->publish_state(pressure);
343  if (this->humidity_sensor_ != nullptr)
344  this->humidity_sensor_->publish_state(humidity);
345  if (this->gas_resistance_sensor_ != nullptr) {
346  if (gas_valid && heat_stable) {
347  this->gas_resistance_sensor_->publish_state(gas_resistance);
348  } else {
349  this->status_set_warning();
351  }
352  }
353 }
354 
355 float BME680Component::calc_temperature_(uint32_t raw_temperature) {
356  float var1 = 0;
357  float var2 = 0;
358  float var3 = 0;
359  float calc_temp = 0;
360  float temp_adc = raw_temperature;
361 
362  const float t1 = this->calibration_.t1;
363  const float t2 = this->calibration_.t2;
364  const float t3 = this->calibration_.t3;
365 
366  /* calculate var1 data */
367  var1 = ((temp_adc / 16384.0f) - (t1 / 1024.0f)) * t2;
368 
369  /* calculate var2 data */
370  var3 = (temp_adc / 131072.0f) - (t1 / 8192.0f);
371  var2 = var3 * var3 * t3 * 16.0f;
372 
373  /* t_fine value*/
374  this->calibration_.tfine = (var1 + var2);
375 
376  /* compensated temperature data*/
377  calc_temp = ((this->calibration_.tfine) / 5120.0f);
378 
379  return calc_temp;
380 }
381 float BME680Component::calc_pressure_(uint32_t raw_pressure) {
382  const float tfine = this->calibration_.tfine;
383  const float p1 = this->calibration_.p1;
384  const float p2 = this->calibration_.p2;
385  const float p3 = this->calibration_.p3;
386  const float p4 = this->calibration_.p4;
387  const float p5 = this->calibration_.p5;
388  const float p6 = this->calibration_.p6;
389  const float p7 = this->calibration_.p7;
390  const float p8 = this->calibration_.p8;
391  const float p9 = this->calibration_.p9;
392  const float p10 = this->calibration_.p10;
393 
394  float var1 = 0;
395  float var2 = 0;
396  float var3 = 0;
397  float var4 = 0;
398  float calc_pres = 0;
399 
400  var1 = (tfine / 2.0f) - 64000.0f;
401  var2 = var1 * var1 * (p6 / 131072.0f);
402  var2 = var2 + var1 * p5 * 2.0f;
403  var2 = (var2 / 4.0f) + (p4 * 65536.0f);
404  var1 = (((p3 * var1 * var1) / 16384.0f) + (p2 * var1)) / 524288.0f;
405  var1 = (1.0f + (var1 / 32768.0f)) * p1;
406  calc_pres = 1048576.0f - float(raw_pressure);
407 
408  /* Avoid exception caused by division by zero */
409  if (int(var1) != 0) {
410  calc_pres = ((calc_pres - (var2 / 4096.0f)) * 6250.0f) / var1;
411  var1 = (p9 * calc_pres * calc_pres) / 2147483648.0f;
412  var2 = calc_pres * (p8 / 32768.0f);
413  var4 = calc_pres / 256.0f;
414  var3 = var4 * var4 * var4 * (p10 / 131072.0f);
415  calc_pres = calc_pres + (var1 + var2 + var3 + (p7 * 128.0f)) / 16.0f;
416  } else {
417  calc_pres = 0;
418  }
419 
420  return calc_pres / 100.0f;
421 }
422 
423 float BME680Component::calc_humidity_(uint16_t raw_humidity) {
424  const float tfine = this->calibration_.tfine;
425  const float h1 = this->calibration_.h1;
426  const float h2 = this->calibration_.h2;
427  const float h3 = this->calibration_.h3;
428  const float h4 = this->calibration_.h4;
429  const float h5 = this->calibration_.h5;
430  const float h6 = this->calibration_.h6;
431  const float h7 = this->calibration_.h7;
432 
433  float calc_hum = 0;
434  float var1 = 0;
435  float var2 = 0;
436  float var3 = 0;
437  float var4 = 0;
438  float temp_comp;
439 
440  /* compensated temperature data*/
441  temp_comp = tfine / 5120.0f;
442 
443  var1 = float(raw_humidity) - (h1 * 16.0f + ((h3 / 2.0f) * temp_comp));
444  var2 = var1 *
445  (((h2 / 262144.0f) * (1.0f + ((h4 / 16384.0f) * temp_comp) + ((h5 / 1048576.0f) * temp_comp * temp_comp))));
446  var3 = h6 / 16384.0f;
447  var4 = h7 / 2097152.0f;
448 
449  calc_hum = var2 + (var3 + var4 * temp_comp) * var2 * var2;
450 
451  if (calc_hum > 100.0f) {
452  calc_hum = 100.0f;
453  } else if (calc_hum < 0.0f) {
454  calc_hum = 0.0f;
455  }
456 
457  return calc_hum;
458 }
459 float BME680Component::calc_gas_resistance_(uint16_t raw_gas, uint8_t range) {
460  float calc_gas_res;
461  float var1 = 0;
462  float var2 = 0;
463  float var3 = 0;
464  float raw_gas_f = raw_gas;
465  float range_f = 1U << range;
466  const float range_sw_err = this->calibration_.range_sw_err;
467 
468  var1 = 1340.0f + (5.0f * range_sw_err);
469  var2 = var1 * (1.0f + BME680_GAS_LOOKUP_TABLE_1[range] / 100.0f);
470  var3 = 1.0f + (BME680_GAS_LOOKUP_TABLE_2[range] / 100.0f);
471 
472  calc_gas_res = 1.0f / (var3 * 0.000000125f * range_f * (((raw_gas_f - 512.0f) / var2) + 1.0f));
473 
474  return calc_gas_res;
475 }
477  uint32_t tph_dur; // Calculate in us
478  uint32_t meas_cycles;
479  const uint8_t os_to_meas_cycles[6] = {0, 1, 2, 4, 8, 16};
480 
481  meas_cycles = os_to_meas_cycles[this->temperature_oversampling_];
482  meas_cycles += os_to_meas_cycles[this->pressure_oversampling_];
483  meas_cycles += os_to_meas_cycles[this->humidity_oversampling_];
484 
485  /* TPH measurement duration */
486  tph_dur = meas_cycles * 1963u;
487  tph_dur += 477 * 4; // TPH switching duration
488  tph_dur += 477 * 5; // Gas measurement duration
489  tph_dur += 500; // Get it to the closest whole number.
490  tph_dur /= 1000; // Convert to ms
491 
492  tph_dur += 1; // Wake up duration of 1ms
493 
494  /* The remaining time should be used for heating */
495  tph_dur += this->heater_duration_;
496 
497  return tph_dur;
498 }
500  this->temperature_oversampling_ = temperature_oversampling;
501 }
503  this->pressure_oversampling_ = pressure_oversampling;
504 }
506  this->humidity_oversampling_ = humidity_oversampling;
507 }
508 void BME680Component::set_iir_filter(BME680IIRFilter iir_filter) { this->iir_filter_ = iir_filter; }
509 void BME680Component::set_heater(uint16_t heater_temperature, uint16_t heater_duration) {
510  this->heater_temperature_ = heater_temperature;
511  this->heater_duration_ = heater_duration;
512 }
513 
514 } // namespace bme680
515 } // namespace esphome
BME680Oversampling temperature_oversampling_
Definition: bme680.h:125
bool read_byte(uint8_t a_register, uint8_t *data, bool stop=true)
Definition: i2c.h:235
const float DATA
For components that import data from directly connected sensors like DHT.
Definition: component.cpp:19
float calc_gas_resistance_(uint16_t raw_gas, uint8_t range)
Calculate the gas resistance in Ω using the provided raw ADC value.
Definition: bme680.cpp:459
BME680CalibrationData calibration_
Definition: bme680.h:124
float get_setup_priority() const override
Definition: bme680.cpp:237
void status_set_warning(const char *message="unspecified")
Definition: component.cpp:151
BME680IIRFilter
Enum listing all IIR Filter options for the BME680.
Definition: bme680.h:11
uint8_t pressure
Definition: tt21100.cpp:19
uint8_t calc_heater_duration_(uint16_t duration)
Calculate the heater duration value to send to the BME680 register.
Definition: bme680.cpp:283
bool is_failed() const
Definition: component.cpp:143
void read_data_()
Read data from the BME680 and publish results.
Definition: bme680.cpp:299
void set_pressure_oversampling(BME680Oversampling pressure_oversampling)
Set the pressure oversampling value. Defaults to 16X.
Definition: bme680.cpp:502
float calc_humidity_(uint16_t raw_humidity)
Calculate the relative humidity in % using the provided raw ADC value.
Definition: bme680.cpp:423
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition: component.cpp:69
bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len)
Compat APIs All methods below have been added for compatibility reasons.
Definition: i2c.h:212
BME680IIRFilter iir_filter_
Definition: bme680.h:128
void set_humidity_oversampling(BME680Oversampling humidity_oversampling)
Set the humidity oversampling value. Defaults to 16X.
Definition: bme680.cpp:505
void set_heater(uint16_t heater_temperature, uint16_t heater_duration)
Set how the internal heater should operate.
Definition: bme680.cpp:509
sensor::Sensor * gas_resistance_sensor_
Definition: bme680.h:135
BME680Oversampling humidity_oversampling_
Definition: bme680.h:127
sensor::Sensor * pressure_sensor_
Definition: bme680.h:133
const float BME680_GAS_LOOKUP_TABLE_1 [16] PROGMEM
Definition: bme680.cpp:25
void status_clear_warning()
Definition: component.cpp:166
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
uint16_t temperature
Definition: sun_gtil2.cpp:26
uint32_t calc_meas_duration_()
Calculate how long the sensor will take until we can retrieve data.
Definition: bme680.cpp:476
float calc_pressure_(uint32_t raw_pressure)
Calculate the pressure in hPa using the provided raw ADC value.
Definition: bme680.cpp:381
sensor::Sensor * temperature_sensor_
Definition: bme680.h:132
BME680Oversampling
Enum listing all oversampling options for the BME680.
Definition: bme680.h:23
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
Definition: i2c.h:262
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:118
void set_iir_filter(BME680IIRFilter iir_filter)
Set the IIR Filter value. Defaults to no IIR Filter.
Definition: bme680.cpp:508
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
uint8_t calc_heater_resistance_(uint16_t temperature)
Calculate the heater resistance value to send to the BME680 register.
Definition: bme680.cpp:252
sensor::Sensor * humidity_sensor_
Definition: bme680.h:134
BME680Oversampling pressure_oversampling_
Definition: bme680.h:126
void set_temperature_oversampling(BME680Oversampling temperature_oversampling)
Set the temperature oversampling value. Defaults to 16X.
Definition: bme680.cpp:499
float calc_temperature_(uint32_t raw_temperature)
Calculate the temperature in °C using the provided raw ADC value.
Definition: bme680.cpp:355