mirror of
https://github.com/esphome/esphome.git
synced 2024-11-22 23:18:10 +01:00
Add support for sdp8xx (#2779)
This commit is contained in:
parent
290da8df2d
commit
ccfa1e23f0
3 changed files with 83 additions and 41 deletions
|
@ -11,6 +11,7 @@ static const uint8_t SDP3X_SOFT_RESET[2] = {0x00, 0x06};
|
||||||
static const uint8_t SDP3X_READ_ID1[2] = {0x36, 0x7C};
|
static const uint8_t SDP3X_READ_ID1[2] = {0x36, 0x7C};
|
||||||
static const uint8_t SDP3X_READ_ID2[2] = {0xE1, 0x02};
|
static const uint8_t SDP3X_READ_ID2[2] = {0xE1, 0x02};
|
||||||
static const uint8_t SDP3X_START_DP_AVG[2] = {0x36, 0x15};
|
static const uint8_t SDP3X_START_DP_AVG[2] = {0x36, 0x15};
|
||||||
|
static const uint8_t SDP3X_START_MASS_FLOW_AVG[2] = {0x36, 0x03};
|
||||||
static const uint8_t SDP3X_STOP_MEAS[2] = {0x3F, 0xF9};
|
static const uint8_t SDP3X_STOP_MEAS[2] = {0x3F, 0xF9};
|
||||||
|
|
||||||
void SDP3XComponent::update() { this->read_pressure_(); }
|
void SDP3XComponent::update() { this->read_pressure_(); }
|
||||||
|
@ -26,46 +27,69 @@ void SDP3XComponent::setup() {
|
||||||
ESP_LOGW(TAG, "Soft Reset SDP3X failed!"); // This sometimes fails for no good reason
|
ESP_LOGW(TAG, "Soft Reset SDP3X failed!"); // This sometimes fails for no good reason
|
||||||
}
|
}
|
||||||
|
|
||||||
delayMicroseconds(20000);
|
this->set_timeout(20, [this] {
|
||||||
|
if (this->write(SDP3X_READ_ID1, 2) != i2c::ERROR_OK) {
|
||||||
|
ESP_LOGE(TAG, "Read ID1 SDP3X failed!");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (this->write(SDP3X_READ_ID2, 2) != i2c::ERROR_OK) {
|
||||||
|
ESP_LOGE(TAG, "Read ID2 SDP3X failed!");
|
||||||
|
this->mark_failed();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (this->write(SDP3X_READ_ID1, 2) != i2c::ERROR_OK) {
|
uint8_t data[18];
|
||||||
ESP_LOGE(TAG, "Read ID1 SDP3X failed!");
|
if (this->read(data, 18) != i2c::ERROR_OK) {
|
||||||
this->mark_failed();
|
ESP_LOGE(TAG, "Read ID SDP3X failed!");
|
||||||
return;
|
this->mark_failed();
|
||||||
}
|
return;
|
||||||
if (this->write(SDP3X_READ_ID2, 2) != i2c::ERROR_OK) {
|
}
|
||||||
ESP_LOGE(TAG, "Read ID2 SDP3X failed!");
|
if (!(check_crc_(&data[0], 2, data[2]) && check_crc_(&data[3], 2, data[5]))) {
|
||||||
this->mark_failed();
|
ESP_LOGE(TAG, "CRC ID SDP3X failed!");
|
||||||
return;
|
this->mark_failed();
|
||||||
}
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
uint8_t data[18];
|
// SDP8xx
|
||||||
if (this->read(data, 18) != i2c::ERROR_OK) {
|
// ref:
|
||||||
ESP_LOGE(TAG, "Read ID SDP3X failed!");
|
// https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/8_Differential_Pressure/Datasheets/Sensirion_Differential_Pressure_Datasheet_SDP8xx_Digital.pdf
|
||||||
this->mark_failed();
|
if (data[2] == 0x02) {
|
||||||
return;
|
switch (data[3]) {
|
||||||
}
|
case 0x01: // SDP800-500Pa
|
||||||
|
ESP_LOGCONFIG(TAG, "Sensor is SDP800-500Pa");
|
||||||
|
break;
|
||||||
|
case 0x0A: // SDP810-500Pa
|
||||||
|
ESP_LOGCONFIG(TAG, "Sensor is SDP810-500Pa");
|
||||||
|
break;
|
||||||
|
case 0x04: // SDP801-500Pa
|
||||||
|
ESP_LOGCONFIG(TAG, "Sensor is SDP801-500Pa");
|
||||||
|
break;
|
||||||
|
case 0x0D: // SDP811-500Pa
|
||||||
|
ESP_LOGCONFIG(TAG, "Sensor is SDP811-500Pa");
|
||||||
|
break;
|
||||||
|
case 0x02: // SDP800-125Pa
|
||||||
|
ESP_LOGCONFIG(TAG, "Sensor is SDP800-125Pa");
|
||||||
|
break;
|
||||||
|
case 0x0B: // SDP810-125Pa
|
||||||
|
ESP_LOGCONFIG(TAG, "Sensor is SDP810-125Pa");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else if (data[2] == 0x01) {
|
||||||
|
if (data[3] == 0x01) {
|
||||||
|
ESP_LOGCONFIG(TAG, "Sensor is SDP31-500Pa");
|
||||||
|
} else if (data[3] == 0x02) {
|
||||||
|
ESP_LOGCONFIG(TAG, "Sensor is SDP32-125Pa");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (!(check_crc_(&data[0], 2, data[2]) && check_crc_(&data[3], 2, data[5]))) {
|
if (this->write(measurement_mode_ == DP_AVG ? SDP3X_START_DP_AVG : SDP3X_START_MASS_FLOW_AVG, 2) != i2c::ERROR_OK) {
|
||||||
ESP_LOGE(TAG, "CRC ID SDP3X failed!");
|
ESP_LOGE(TAG, "Start Measurements SDP3X failed!");
|
||||||
this->mark_failed();
|
this->mark_failed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
ESP_LOGCONFIG(TAG, "SDP3X started!");
|
||||||
if (data[3] == 0x01) {
|
});
|
||||||
ESP_LOGCONFIG(TAG, "SDP3X is SDP31");
|
|
||||||
pressure_scale_factor_ = 60.0f * 100.0f; // Scale factors converted to hPa per count
|
|
||||||
} else if (data[3] == 0x02) {
|
|
||||||
ESP_LOGCONFIG(TAG, "SDP3X is SDP32");
|
|
||||||
pressure_scale_factor_ = 240.0f * 100.0f;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this->write(SDP3X_START_DP_AVG, 2) != i2c::ERROR_OK) {
|
|
||||||
ESP_LOGE(TAG, "Start Measurements SDP3X failed!");
|
|
||||||
this->mark_failed();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ESP_LOGCONFIG(TAG, "SDP3X started!");
|
|
||||||
}
|
}
|
||||||
void SDP3XComponent::dump_config() {
|
void SDP3XComponent::dump_config() {
|
||||||
LOG_SENSOR(" ", "SDP3X", this);
|
LOG_SENSOR(" ", "SDP3X", this);
|
||||||
|
@ -91,8 +115,12 @@ void SDP3XComponent::read_pressure_() {
|
||||||
}
|
}
|
||||||
|
|
||||||
int16_t pressure_raw = encode_uint16(data[0], data[1]);
|
int16_t pressure_raw = encode_uint16(data[0], data[1]);
|
||||||
float pressure = pressure_raw / pressure_scale_factor_;
|
int16_t temperature_raw = encode_uint16(data[3], data[4]);
|
||||||
ESP_LOGV(TAG, "Got raw pressure=%d, scale factor =%.3f ", pressure_raw, pressure_scale_factor_);
|
int16_t scale_factor_raw = encode_uint16(data[6], data[7]);
|
||||||
|
// scale factor is in Pa - convert to hPa
|
||||||
|
float pressure = pressure_raw / (scale_factor_raw * 100.0f);
|
||||||
|
ESP_LOGV(TAG, "Got raw pressure=%d, raw scale factor =%d, raw temperature=%d ", pressure_raw, scale_factor_raw,
|
||||||
|
temperature_raw);
|
||||||
ESP_LOGD(TAG, "Got Pressure=%.3f hPa", pressure);
|
ESP_LOGD(TAG, "Got Pressure=%.3f hPa", pressure);
|
||||||
|
|
||||||
this->publish_state(pressure);
|
this->publish_state(pressure);
|
||||||
|
|
|
@ -7,6 +7,8 @@
|
||||||
namespace esphome {
|
namespace esphome {
|
||||||
namespace sdp3x {
|
namespace sdp3x {
|
||||||
|
|
||||||
|
enum MeasurementMode { MASS_FLOW_AVG, DP_AVG };
|
||||||
|
|
||||||
class SDP3XComponent : public PollingComponent, public i2c::I2CDevice, public sensor::Sensor {
|
class SDP3XComponent : public PollingComponent, public i2c::I2CDevice, public sensor::Sensor {
|
||||||
public:
|
public:
|
||||||
/// Schedule temperature+pressure readings.
|
/// Schedule temperature+pressure readings.
|
||||||
|
@ -16,14 +18,14 @@ class SDP3XComponent : public PollingComponent, public i2c::I2CDevice, public se
|
||||||
void dump_config() override;
|
void dump_config() override;
|
||||||
|
|
||||||
float get_setup_priority() const override;
|
float get_setup_priority() const override;
|
||||||
|
void set_measurement_mode(MeasurementMode mode) { measurement_mode_ = mode; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/// Internal method to read the pressure from the component after it has been scheduled.
|
/// Internal method to read the pressure from the component after it has been scheduled.
|
||||||
void read_pressure_();
|
void read_pressure_();
|
||||||
|
|
||||||
bool check_crc_(const uint8_t data[], uint8_t size, uint8_t checksum);
|
bool check_crc_(const uint8_t data[], uint8_t size, uint8_t checksum);
|
||||||
|
MeasurementMode measurement_mode_;
|
||||||
float pressure_scale_factor_ = 0.0f; // hPa per count
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sdp3x
|
} // namespace sdp3x
|
||||||
|
|
|
@ -14,6 +14,14 @@ CODEOWNERS = ["@Azimath"]
|
||||||
sdp3x_ns = cg.esphome_ns.namespace("sdp3x")
|
sdp3x_ns = cg.esphome_ns.namespace("sdp3x")
|
||||||
SDP3XComponent = sdp3x_ns.class_("SDP3XComponent", cg.PollingComponent, i2c.I2CDevice)
|
SDP3XComponent = sdp3x_ns.class_("SDP3XComponent", cg.PollingComponent, i2c.I2CDevice)
|
||||||
|
|
||||||
|
|
||||||
|
MeasurementMode = sdp3x_ns.enum("MeasurementMode")
|
||||||
|
MEASUREMENT_MODE = {
|
||||||
|
"mass_flow": MeasurementMode.MASS_FLOW_AVG,
|
||||||
|
"differential_pressure": MeasurementMode.DP_AVG,
|
||||||
|
}
|
||||||
|
CONF_MEASUREMENT_MODE = "measurement_mode"
|
||||||
|
|
||||||
CONFIG_SCHEMA = (
|
CONFIG_SCHEMA = (
|
||||||
sensor.sensor_schema(
|
sensor.sensor_schema(
|
||||||
unit_of_measurement=UNIT_HECTOPASCAL,
|
unit_of_measurement=UNIT_HECTOPASCAL,
|
||||||
|
@ -24,6 +32,9 @@ CONFIG_SCHEMA = (
|
||||||
.extend(
|
.extend(
|
||||||
{
|
{
|
||||||
cv.GenerateID(): cv.declare_id(SDP3XComponent),
|
cv.GenerateID(): cv.declare_id(SDP3XComponent),
|
||||||
|
cv.Optional(
|
||||||
|
CONF_MEASUREMENT_MODE, default="differential_pressure"
|
||||||
|
): cv.enum(MEASUREMENT_MODE),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
.extend(cv.polling_component_schema("60s"))
|
.extend(cv.polling_component_schema("60s"))
|
||||||
|
@ -36,3 +47,4 @@ async def to_code(config):
|
||||||
await cg.register_component(var, config)
|
await cg.register_component(var, config)
|
||||||
await i2c.register_i2c_device(var, config)
|
await i2c.register_i2c_device(var, config)
|
||||||
await sensor.register_sensor(var, config)
|
await sensor.register_sensor(var, config)
|
||||||
|
cg.add(var.set_measurement_mode(config[CONF_MEASUREMENT_MODE]))
|
||||||
|
|
Loading…
Reference in a new issue