ESPHome 2026.11.0-dev
Loading...
Searching...
No Matches
dps310.cpp
Go to the documentation of this file.
1#include "dps310.h"
3#include "esphome/core/log.h"
4#include "esphome/core/hal.h"
5
6namespace esphome::dps310 {
7
8ESPHOME_LOG_TAG(TAG, "dps310");
9
10static constexpr uint32_t READ_RETRY_TIMEOUT_ID = 0;
11
13 if (!this->setup_registers_())
14 this->mark_failed(LOG_STR(ESP_LOG_MSG_COMM_FAIL));
15}
16
18 uint8_t coef_data_raw[DPS310_NUM_COEF_REGS];
19 auto timer = DPS310_INIT_TIMEOUT;
20 uint8_t reg = 0;
21 // first, reset the sensor
22 if (!this->write_byte(DPS310_REG_RESET, DPS310_CMD_RESET)) {
23 return false;
24 }
25 delay(10);
26 // wait for the sensor and its coefficients to be ready
27 while (timer-- && (!(reg & DPS310_BIT_SENSOR_RDY) || !(reg & DPS310_BIT_COEF_RDY))) {
28 reg = this->read_byte(DPS310_REG_MEAS_CFG).value_or(0);
29 delay(5);
30 }
31
32 if (!(reg & DPS310_BIT_SENSOR_RDY) || !(reg & DPS310_BIT_COEF_RDY)) { // the flags were not set in time
33 return false;
34 }
35 // read device ID
36 if (!this->read_byte(DPS310_REG_PROD_REV_ID, &this->prod_rev_id_)) {
37 return false;
38 }
39 // read in coefficients used to calculate the compensated pressure and temperature values
40 if (!this->read_bytes(DPS310_REG_COEF, coef_data_raw, DPS310_NUM_COEF_REGS)) {
41 return false;
42 }
43 // read in coefficients source register, too -- we need this a few lines down
44 if (!this->read_byte(DPS310_REG_TMP_COEF_SRC, &reg)) {
45 return false;
46 }
47 // set up operational stuff
48 if (!this->write_byte(DPS310_REG_PRS_CFG, DPS310_VAL_PRS_CFG)) {
49 return false;
50 }
51 if (!this->write_byte(DPS310_REG_TMP_CFG, DPS310_VAL_TMP_CFG | (reg & DPS310_BIT_TMP_COEF_SRC))) {
52 return false;
53 }
54 if (!this->write_byte(DPS310_REG_CFG, DPS310_VAL_REG_CFG)) {
55 return false;
56 }
57 if (!this->write_byte(DPS310_REG_MEAS_CFG, 0x07)) { // enable background mode
58 return false;
59 }
60
61 // we only ever use c0/2, so just divide by 2 here to save time later
62 this->c0_ = sign_extend<12>(encode_uint16(coef_data_raw[0], coef_data_raw[1]) >> 4) / 2;
63 this->c1_ = sign_extend<12>(encode_uint16(coef_data_raw[1], coef_data_raw[2]));
64 this->c00_ = sign_extend<20>(encode_uint24(coef_data_raw[3], coef_data_raw[4], coef_data_raw[5]) >> 4);
65 this->c10_ = sign_extend<20>(encode_uint24(coef_data_raw[5], coef_data_raw[6], coef_data_raw[7]));
66 this->c01_ = encode_value<int16_t>(&coef_data_raw[8]);
67 this->c11_ = encode_value<int16_t>(&coef_data_raw[10]);
68 this->c20_ = encode_value<int16_t>(&coef_data_raw[12]);
69 this->c21_ = encode_value<int16_t>(&coef_data_raw[14]);
70 this->c30_ = encode_value<int16_t>(&coef_data_raw[16]);
71 return true;
72}
73
75 ESP_LOGCONFIG(TAG,
76 "DPS310:\n"
77 " Product ID: %u\n"
78 " Revision ID: %u",
79 this->prod_rev_id_ & 0x0F, (this->prod_rev_id_ >> 4) & 0x0F);
80 LOG_I2C_DEVICE(this);
81 LOG_UPDATE_INTERVAL(this);
82 LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
83 LOG_SENSOR(" ", "Pressure", this->pressure_sensor_);
84}
85
87 if (!this->update_in_progress_) {
88 this->update_in_progress_ = true;
89 this->read_();
90 }
91}
92
94 uint8_t reg = 0;
95 if (!this->read_byte(DPS310_REG_MEAS_CFG, &reg)) {
96 this->status_set_warning();
97 return;
98 }
99
100 if ((!this->got_pres_) && (reg & DPS310_BIT_PRS_RDY)) {
101 this->read_pressure_();
102 }
103
104 if ((!this->got_temp_) && (reg & DPS310_BIT_TMP_RDY)) {
105 this->read_temperature_();
106 }
107
108 if (this->got_pres_ && this->got_temp_) {
110 this->got_pres_ = false;
111 this->got_temp_ = false;
112 this->update_in_progress_ = false;
113 this->status_clear_warning();
114 } else {
115 this->set_timeout(READ_RETRY_TIMEOUT_ID, 10, [this]() { this->read_(); });
116 }
117}
118
120 uint8_t bytes[3];
121 if (!this->read_bytes(DPS310_REG_PRS_B2, bytes, 3)) {
122 this->status_set_warning();
123 return;
124 }
125 this->got_pres_ = true;
126 this->raw_pressure_ = sign_extend<24>(encode_uint24(bytes[0], bytes[1], bytes[2]));
127}
128
130 uint8_t bytes[3];
131 if (!this->read_bytes(DPS310_REG_TMP_B2, bytes, 3)) {
132 this->status_set_warning();
133 return;
134 }
135 this->got_temp_ = true;
136 this->raw_temperature_ = sign_extend<24>(encode_uint24(bytes[0], bytes[1], bytes[2]));
137}
138
139// Calculations are taken from the datasheet which can be found here:
140// https://www.infineon.com/dgdl/Infineon-DPS310-DataSheet-v01_02-EN.pdf?fileId=5546d462576f34750157750826c42242
141// Sections "How to Calculate Compensated Pressure Values" and "How to Calculate Compensated Temperature Values"
142// Variable names below match variable names from the datasheet but lowercased
143void DPS310Component::calculate_values_(int32_t raw_temperature, int32_t raw_pressure) {
144 const float t_raw_sc = (float) raw_temperature / DPS310_SCALE_FACTOR;
145 const float p_raw_sc = (float) raw_pressure / DPS310_SCALE_FACTOR;
146
147 const float temperature = t_raw_sc * this->c1_ + this->c0_; // c0/2 done earlier!
148
149 const float pressure = (this->c00_ + p_raw_sc * (this->c10_ + p_raw_sc * (this->c20_ + p_raw_sc * this->c30_)) +
150 t_raw_sc * this->c01_ + t_raw_sc * p_raw_sc * (this->c11_ + p_raw_sc * this->c21_)) /
151 100; // divide by 100 for hPa
152
153 if (this->temperature_sensor_ != nullptr) {
154 this->temperature_sensor_->publish_state(temperature);
155 }
156 if (this->pressure_sensor_ != nullptr) {
157 this->pressure_sensor_->publish_state(pressure);
158 }
159}
160
161} // namespace esphome::dps310
void mark_failed()
Mark this component as failed.
void set_timeout(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a const char* name.
Definition component.cpp:96
void status_clear_warning()
Definition component.h:296
sensor::Sensor * pressure_sensor_
Definition dps310.h:56
sensor::Sensor * temperature_sensor_
Definition dps310.h:55
void calculate_values_(int32_t raw_temperature, int32_t raw_pressure)
Definition dps310.cpp:143
bool setup_registers_()
Configure the sensor; false on a failure.
Definition dps310.cpp:17
bool write_byte(uint8_t a_register, uint8_t data) const
Definition i2c.h:312
bool read_byte(uint8_t a_register, uint8_t *data)
Definition i2c.h:272
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
Definition i2c.h:164
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:249
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:65
ESPHOME_LOG_TAG(TAG, "dps310")
constexpr uint32_t encode_uint24(uint8_t byte1, uint8_t byte2, uint8_t byte3)
Encode a 24-bit value given three bytes in most to least significant byte order.
Definition helpers.h:1002
constexpr T encode_value(const uint8_t *bytes)
Encode a value from its constituent bytes (from most to least significant) in an array with length si...
Definition helpers.h:1019
constexpr int32_t sign_extend(uint32_t value)
Sign-extend the low BITS bits of value, e.g. sign_extend<24>(0xFFFFFE) == -2. Higher bits are ignored...
Definition helpers.h:1012
constexpr uint16_t encode_uint16(uint8_t msb, uint8_t lsb)
Encode a 16-bit value given the most and least significant byte.
Definition helpers.h:998
void HOT delay(uint32_t ms)
Definition hal.cpp:85
static void uint32_t
uint16_t temperature
Definition sun_gtil2.cpp:12
uint8_t pressure
Definition tt21100.cpp:7