ESPHome  2022.12.8
bmp085.cpp
Go to the documentation of this file.
1 #include "bmp085.h"
2 #include "esphome/core/log.h"
3 
4 namespace esphome {
5 namespace bmp085 {
6 
7 static const char *const TAG = "bmp085.sensor";
8 
9 static const uint8_t BMP085_ADDRESS = 0x77;
10 static const uint8_t BMP085_REGISTER_AC1_H = 0xAA;
11 static const uint8_t BMP085_REGISTER_CONTROL = 0xF4;
12 static const uint8_t BMP085_REGISTER_DATA_MSB = 0xF6;
13 static const uint8_t BMP085_CONTROL_MODE_TEMPERATURE = 0x2E;
14 static const uint8_t BMP085_CONTROL_MODE_PRESSURE_3 = 0xF4;
15 
17  if (!this->set_mode_(BMP085_CONTROL_MODE_TEMPERATURE))
18  return;
19 
20  this->set_timeout("temperature", 5, [this]() { this->read_temperature_(); });
21 }
23  ESP_LOGCONFIG(TAG, "Setting up BMP085...");
24  uint8_t data[22];
25  if (!this->read_bytes(BMP085_REGISTER_AC1_H, data, 22)) {
26  this->mark_failed();
27  return;
28  }
29 
30  // Load calibration
31  this->calibration_.ac1 = ((data[0] & 0xFF) << 8) | (data[1] & 0xFF);
32  this->calibration_.ac2 = ((data[2] & 0xFF) << 8) | (data[3] & 0xFF);
33  this->calibration_.ac3 = ((data[4] & 0xFF) << 8) | (data[5] & 0xFF);
34  this->calibration_.ac4 = ((data[6] & 0xFF) << 8) | (data[7] & 0xFF);
35  this->calibration_.ac5 = ((data[8] & 0xFF) << 8) | (data[9] & 0xFF);
36  this->calibration_.ac6 = ((data[10] & 0xFF) << 8) | (data[11] & 0xFF);
37  this->calibration_.b1 = ((data[12] & 0xFF) << 8) | (data[13] & 0xFF);
38  this->calibration_.b2 = ((data[14] & 0xFF) << 8) | (data[15] & 0xFF);
39  this->calibration_.mb = ((data[16] & 0xFF) << 8) | (data[17] & 0xFF);
40  this->calibration_.mc = ((data[18] & 0xFF) << 8) | (data[19] & 0xFF);
41  this->calibration_.md = ((data[20] & 0xFF) << 8) | (data[21] & 0xFF);
42 }
44  ESP_LOGCONFIG(TAG, "BMP085:");
45  LOG_I2C_DEVICE(this);
46  if (this->is_failed()) {
47  ESP_LOGE(TAG, "Connection with BMP085 failed!");
48  }
49  LOG_UPDATE_INTERVAL(this);
50 
51  LOG_SENSOR(" ", "Temperature", this->temperature_);
52  LOG_SENSOR(" ", "Pressure", this->pressure_);
53 }
54 
56  uint8_t buffer[2];
57  // 0xF6
58  if (!this->read_bytes(BMP085_REGISTER_DATA_MSB, buffer, 2)) {
59  this->status_set_warning();
60  return;
61  }
62 
63  int32_t ut = ((buffer[0] & 0xFF) << 8) | (buffer[1] & 0xFF);
64  if (ut == 0) {
65  ESP_LOGW(TAG, "Invalid temperature!");
66  this->status_set_warning();
67  return;
68  }
69 
70  double c5 = (pow(2, -15) / 160) * this->calibration_.ac5;
71  double c6 = this->calibration_.ac6;
72  double mc = (2048.0 / 25600.0) * this->calibration_.mc;
73  double md = this->calibration_.md / 160.0;
74 
75  double a = c5 * (ut - c6);
76  float temp = a + (mc / (a + md));
77 
78  this->calibration_.temp = temp;
79  ESP_LOGD(TAG, "Got Temperature=%.1f °C", temp);
80  if (this->temperature_ != nullptr)
81  this->temperature_->publish_state(temp);
82  this->status_clear_warning();
83 
84  if (!this->set_mode_(BMP085_CONTROL_MODE_PRESSURE_3)) {
85  this->status_set_warning();
86  return;
87  }
88 
89  this->set_timeout("pressure", 26, [this]() { this->read_pressure_(); });
90 }
92  uint8_t buffer[3];
93  if (!this->read_bytes(BMP085_REGISTER_DATA_MSB, buffer, 3)) {
94  this->status_set_warning();
95  return;
96  }
97 
98  uint32_t value = (uint32_t(buffer[0]) << 16) | (uint32_t(buffer[1]) << 8) | uint32_t(buffer[0]);
99  if ((value >> 5) == 0) {
100  ESP_LOGW(TAG, "Invalid pressure!");
101  this->status_set_warning();
102  return;
103  }
104 
105  double c3 = 160.0 * pow(2.0, -15.0) * this->calibration_.ac3;
106  double c4 = pow(10.0, -3) * pow(2.0, -15.0) * this->calibration_.ac4;
107  double b1 = pow(160.0, 2.0) * pow(2.0, -30.0) * this->calibration_.b1;
108  double x0 = this->calibration_.ac1;
109  double x1 = 160.0 * pow(2.0, -13.0) * this->calibration_.ac2;
110  double x2 = pow(160.0, 2.0) * pow(2.0, -25.0) * this->calibration_.b2;
111  double y0 = c4 * pow(2.0, 15.0);
112  double y1 = c4 * c3;
113  double y2 = c4 * b1;
114  double p0 = (3791.0 - 8.0) / 1600.0;
115  double p1 = 1.0 - 7357.0 * pow(2, -20);
116  double p2 = 3038.0 * 100.0 * pow(2, -36);
117 
118  double p = value / 256.0;
119  double s = this->calibration_.temp - 25.0;
120  double x = (x2 * s * s) + (x1 * s) + x0;
121  double y = (y2 * s * s) + (y1 * s) + y0;
122  double z = (p - x) / y;
123  float pressure = (p2 * z * z) + (p1 * z) + p0;
124 
125  ESP_LOGD(TAG, "Got Pressure=%.1f hPa", pressure);
126 
127  if (this->pressure_ != nullptr)
128  this->pressure_->publish_state(pressure);
129  this->status_clear_warning();
130 }
132  ESP_LOGV(TAG, "Setting mode to 0x%02X...", mode);
133  return this->write_byte(BMP085_REGISTER_CONTROL, mode);
134 }
136 
137 } // namespace bmp085
138 } // namespace esphome
float pressure
Definition: qmp6988.h:72
const float DATA
For components that import data from directly connected sensors like DHT.
Definition: component.cpp:18
sensor::Sensor * temperature_
Definition: bmp085.h:39
void setup() override
Setup the sensor and test for a connection.
Definition: bmp085.cpp:22
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:68
bool read_bytes(uint8_t a_register, uint8_t *data, uint8_t len)
Definition: i2c.h:68
CalibrationData calibration_
Definition: bmp085.h:41
void update() override
Schedule temperature+pressure readings.
Definition: bmp085.cpp:16
sensor::Sensor * pressure_
Definition: bmp085.h:40
void status_clear_warning()
Definition: component.cpp:149
void dump_config() override
Definition: bmp085.cpp:43
BedjetMode mode
BedJet operating mode.
Definition: bedjet_codec.h:151
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:72
void status_set_warning()
Definition: component.cpp:141
bool set_mode_(uint8_t mode)
Definition: bmp085.cpp:131
bool write_byte(uint8_t a_register, uint8_t data, bool stop=true)
Definition: i2c.h:123
float get_setup_priority() const override
Definition: bmp085.cpp:135
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:112
Definition: a4988.cpp:4
void read_pressure_()
Internal method to read the pressure from the component after it has been scheduled.
Definition: bmp085.cpp:91
void read_temperature_()
Internal method to read the temperature from the component after it has been scheduled.
Definition: bmp085.cpp:55