Add support for sdp8xx (#2779)

This commit is contained in:
Martin 2021-11-24 23:28:19 +01:00 committed by GitHub
parent 290da8df2d
commit ccfa1e23f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 83 additions and 41 deletions

View File

@ -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_ID2[2] = {0xE1, 0x02};
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};
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
}
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) {
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;
}
uint8_t data[18];
if (this->read(data, 18) != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Read ID SDP3X failed!");
this->mark_failed();
return;
}
if (!(check_crc_(&data[0], 2, data[2]) && check_crc_(&data[3], 2, data[5]))) {
ESP_LOGE(TAG, "CRC ID SDP3X failed!");
this->mark_failed();
return;
}
uint8_t data[18];
if (this->read(data, 18) != i2c::ERROR_OK) {
ESP_LOGE(TAG, "Read ID SDP3X failed!");
this->mark_failed();
return;
}
// SDP8xx
// ref:
// https://www.sensirion.com/fileadmin/user_upload/customers/sensirion/Dokumente/8_Differential_Pressure/Datasheets/Sensirion_Differential_Pressure_Datasheet_SDP8xx_Digital.pdf
if (data[2] == 0x02) {
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]))) {
ESP_LOGE(TAG, "CRC ID SDP3X failed!");
this->mark_failed();
return;
}
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!");
if (this->write(measurement_mode_ == DP_AVG ? SDP3X_START_DP_AVG : SDP3X_START_MASS_FLOW_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() {
LOG_SENSOR(" ", "SDP3X", this);
@ -91,8 +115,12 @@ void SDP3XComponent::read_pressure_() {
}
int16_t pressure_raw = encode_uint16(data[0], data[1]);
float pressure = pressure_raw / pressure_scale_factor_;
ESP_LOGV(TAG, "Got raw pressure=%d, scale factor =%.3f ", pressure_raw, pressure_scale_factor_);
int16_t temperature_raw = encode_uint16(data[3], data[4]);
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);
this->publish_state(pressure);

View File

@ -7,6 +7,8 @@
namespace esphome {
namespace sdp3x {
enum MeasurementMode { MASS_FLOW_AVG, DP_AVG };
class SDP3XComponent : public PollingComponent, public i2c::I2CDevice, public sensor::Sensor {
public:
/// Schedule temperature+pressure readings.
@ -16,14 +18,14 @@ class SDP3XComponent : public PollingComponent, public i2c::I2CDevice, public se
void dump_config() override;
float get_setup_priority() const override;
void set_measurement_mode(MeasurementMode mode) { measurement_mode_ = mode; }
protected:
/// Internal method to read the pressure from the component after it has been scheduled.
void read_pressure_();
bool check_crc_(const uint8_t data[], uint8_t size, uint8_t checksum);
float pressure_scale_factor_ = 0.0f; // hPa per count
MeasurementMode measurement_mode_;
};
} // namespace sdp3x

View File

@ -14,6 +14,14 @@ CODEOWNERS = ["@Azimath"]
sdp3x_ns = cg.esphome_ns.namespace("sdp3x")
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 = (
sensor.sensor_schema(
unit_of_measurement=UNIT_HECTOPASCAL,
@ -24,6 +32,9 @@ CONFIG_SCHEMA = (
.extend(
{
cv.GenerateID(): cv.declare_id(SDP3XComponent),
cv.Optional(
CONF_MEASUREMENT_MODE, default="differential_pressure"
): cv.enum(MEASUREMENT_MODE),
}
)
.extend(cv.polling_component_schema("60s"))
@ -36,3 +47,4 @@ async def to_code(config):
await cg.register_component(var, config)
await i2c.register_i2c_device(var, config)
await sensor.register_sensor(var, config)
cg.add(var.set_measurement_mode(config[CONF_MEASUREMENT_MODE]))