ESPHome  2024.3.1
sdp3x.cpp
Go to the documentation of this file.
1 #include "sdp3x.h"
2 #include "esphome/core/log.h"
3 #include "esphome/core/hal.h"
4 #include "esphome/core/helpers.h"
5 
6 namespace esphome {
7 namespace sdp3x {
8 
9 static const char *const TAG = "sdp3x.sensor";
10 static const uint16_t SDP3X_SOFT_RESET = 0x0006;
11 static const uint16_t SDP3X_READ_ID1 = 0x367C;
12 static const uint16_t SDP3X_READ_ID2 = 0xE102;
13 static const uint16_t SDP3X_START_DP_AVG = 0x3615;
14 static const uint16_t SDP3X_START_MASS_FLOW_AVG = 0x3603;
15 static const uint16_t SDP3X_STOP_MEAS = 0x3FF9;
16 
18 
20  ESP_LOGD(TAG, "Setting up SDP3X...");
21 
22  if (!this->write_command(SDP3X_STOP_MEAS)) {
23  ESP_LOGW(TAG, "Stop SDP3X failed!"); // This sometimes fails for no good reason
24  }
25 
26  if (!this->write_command(SDP3X_SOFT_RESET)) {
27  ESP_LOGW(TAG, "Soft Reset SDP3X failed!"); // This sometimes fails for no good reason
28  }
29 
30  this->set_timeout(20, [this] {
31  if (!this->write_command(SDP3X_READ_ID1)) {
32  ESP_LOGE(TAG, "Read ID1 SDP3X failed!");
33  this->mark_failed();
34  return;
35  }
36  if (!this->write_command(SDP3X_READ_ID2)) {
37  ESP_LOGE(TAG, "Read ID2 SDP3X failed!");
38  this->mark_failed();
39  return;
40  }
41 
42  uint16_t data[6];
43  if (!this->read_data(data, 6)) {
44  ESP_LOGE(TAG, "Read ID SDP3X failed!");
45  this->mark_failed();
46  return;
47  }
48 
49  // SDP8xx
50  // ref:
51  // https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/8_Differential_Pressure/Datasheets/Sensirion_Differential_Pressure_Datasheet_SDP8xx_Digital.pdf
52  if (data[1] >> 8 == 0x02) {
53  switch (data[1] & 0xFF) {
54  case 0x01: // SDP800-500Pa
55  ESP_LOGCONFIG(TAG, "Sensor is SDP800-500Pa");
56  break;
57  case 0x0A: // SDP810-500Pa
58  ESP_LOGCONFIG(TAG, "Sensor is SDP810-500Pa");
59  break;
60  case 0x04: // SDP801-500Pa
61  ESP_LOGCONFIG(TAG, "Sensor is SDP801-500Pa");
62  break;
63  case 0x0D: // SDP811-500Pa
64  ESP_LOGCONFIG(TAG, "Sensor is SDP811-500Pa");
65  break;
66  case 0x02: // SDP800-125Pa
67  ESP_LOGCONFIG(TAG, "Sensor is SDP800-125Pa");
68  break;
69  case 0x0B: // SDP810-125Pa
70  ESP_LOGCONFIG(TAG, "Sensor is SDP810-125Pa");
71  break;
72  }
73  } else if (data[1] >> 8 == 0x01) {
74  if ((data[1] & 0xFF) == 0x01) {
75  ESP_LOGCONFIG(TAG, "Sensor is SDP31-500Pa");
76  } else if ((data[1] & 0xFF) == 0x02) {
77  ESP_LOGCONFIG(TAG, "Sensor is SDP32-125Pa");
78  }
79  }
80 
81  if (!this->write_command(measurement_mode_ == DP_AVG ? SDP3X_START_DP_AVG : SDP3X_START_MASS_FLOW_AVG)) {
82  ESP_LOGE(TAG, "Start Measurements SDP3X failed!");
83  this->mark_failed();
84  return;
85  }
86  ESP_LOGCONFIG(TAG, "SDP3X started!");
87  });
88 }
90  LOG_SENSOR(" ", "SDP3X", this);
91  LOG_I2C_DEVICE(this);
92  if (this->is_failed()) {
93  ESP_LOGE(TAG, " Connection with SDP3X failed!");
94  }
95  LOG_UPDATE_INTERVAL(this);
96 }
97 
99  uint16_t data[3];
100  if (!this->read_data(data, 3)) {
101  ESP_LOGW(TAG, "Couldn't read SDP3X data!");
102  this->status_set_warning();
103  return;
104  }
105 
106  int16_t pressure_raw = data[0];
107  int16_t temperature_raw = data[1];
108  int16_t scale_factor_raw = data[2];
109  // scale factor is in Pa - convert to hPa
110  float pressure = pressure_raw / (scale_factor_raw * 100.0f);
111  ESP_LOGV(TAG, "Got raw pressure=%d, raw scale factor =%d, raw temperature=%d ", pressure_raw, scale_factor_raw,
112  temperature_raw);
113  ESP_LOGD(TAG, "Got Pressure=%.3f hPa", pressure);
114 
115  this->publish_state(pressure);
116  this->status_clear_warning();
117 }
118 
120 
121 } // namespace sdp3x
122 } // namespace esphome
const float DATA
For components that import data from directly connected sensors like DHT.
Definition: component.cpp:19
void status_set_warning(const char *message="unspecified")
Definition: component.cpp:146
uint8_t pressure
Definition: tt21100.cpp:19
bool write_command(T i2c_register)
Write a command to the i2c device.
Definition: i2c_sensirion.h:82
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_data(uint16_t *data, uint8_t len)
Read data words from i2c device.
MeasurementMode measurement_mode_
Definition: sdp3x.h:26
void setup() override
Setup the sensor and test for a connection.
Definition: sdp3x.cpp:19
void status_clear_warning()
Definition: component.cpp:161
void publish_state(float state)
Publish a new state to the front-end.
Definition: sensor.cpp:39
float get_setup_priority() const override
Definition: sdp3x.cpp:119
void update() override
Schedule temperature+pressure readings.
Definition: sdp3x.cpp:17
virtual void mark_failed()
Mark this component as failed.
Definition: component.cpp:113
void dump_config() override
Definition: sdp3x.cpp:89
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
void read_pressure_()
Internal method to read the pressure from the component after it has been scheduled.
Definition: sdp3x.cpp:98