ESPHome 2026.2.1
Loading...
Searching...
No Matches
dps310.cpp
Go to the documentation of this file.
1#include "dps310.h"
2#include "esphome/core/log.h"
3#include "esphome/core/hal.h"
4
5namespace esphome {
6namespace dps310 {
7
8static const char *const TAG = "dps310";
9
11 uint8_t coef_data_raw[DPS310_NUM_COEF_REGS];
12 auto timer = DPS310_INIT_TIMEOUT;
13 uint8_t reg = 0;
14 // first, reset the sensor
15 if (!this->write_byte(DPS310_REG_RESET, DPS310_CMD_RESET)) {
16 this->mark_failed();
17 return;
18 }
19 delay(10);
20 // wait for the sensor and its coefficients to be ready
21 while (timer-- && (!(reg & DPS310_BIT_SENSOR_RDY) || !(reg & DPS310_BIT_COEF_RDY))) {
22 reg = this->read_byte(DPS310_REG_MEAS_CFG).value_or(0);
23 delay(5);
24 }
25
26 if (!(reg & DPS310_BIT_SENSOR_RDY) || !(reg & DPS310_BIT_COEF_RDY)) { // the flags were not set in time
27 this->mark_failed();
28 return;
29 }
30 // read device ID
31 if (!this->read_byte(DPS310_REG_PROD_REV_ID, &this->prod_rev_id_)) {
32 this->mark_failed();
33 return;
34 }
35 // read in coefficients used to calculate the compensated pressure and temperature values
36 if (!this->read_bytes(DPS310_REG_COEF, coef_data_raw, DPS310_NUM_COEF_REGS)) {
37 this->mark_failed();
38 return;
39 }
40 // read in coefficients source register, too -- we need this a few lines down
41 if (!this->read_byte(DPS310_REG_TMP_COEF_SRC, &reg)) {
42 this->mark_failed();
43 return;
44 }
45 // set up operational stuff
46 if (!this->write_byte(DPS310_REG_PRS_CFG, DPS310_VAL_PRS_CFG)) {
47 this->mark_failed();
48 return;
49 }
50 if (!this->write_byte(DPS310_REG_TMP_CFG, DPS310_VAL_TMP_CFG | (reg & DPS310_BIT_TMP_COEF_SRC))) {
51 this->mark_failed();
52 return;
53 }
54 if (!this->write_byte(DPS310_REG_CFG, DPS310_VAL_REG_CFG)) {
55 this->mark_failed();
56 return;
57 }
58 if (!this->write_byte(DPS310_REG_MEAS_CFG, 0x07)) { // enable background mode
59 this->mark_failed();
60 return;
61 }
62
63 this->c0_ = // we only ever use c0/2, so just divide by 2 here to save time later
65 int16_t(((uint16_t) coef_data_raw[0] << 4) | (((uint16_t) coef_data_raw[1] >> 4) & 0x0F)), 12) /
66 2;
67
68 this->c1_ =
69 DPS310Component::twos_complement(int16_t((((uint16_t) coef_data_raw[1] & 0x0F) << 8) | coef_data_raw[2]), 12);
70
71 this->c00_ = ((uint32_t) coef_data_raw[3] << 12) | ((uint32_t) coef_data_raw[4] << 4) |
72 (((uint32_t) coef_data_raw[5] >> 4) & 0x0F);
74
75 this->c10_ =
76 (((uint32_t) coef_data_raw[5] & 0x0F) << 16) | ((uint32_t) coef_data_raw[6] << 8) | (uint32_t) coef_data_raw[7];
78
79 this->c01_ = int16_t(((uint16_t) coef_data_raw[8] << 8) | (uint16_t) coef_data_raw[9]);
80 this->c11_ = int16_t(((uint16_t) coef_data_raw[10] << 8) | (uint16_t) coef_data_raw[11]);
81 this->c20_ = int16_t(((uint16_t) coef_data_raw[12] << 8) | (uint16_t) coef_data_raw[13]);
82 this->c21_ = int16_t(((uint16_t) coef_data_raw[14] << 8) | (uint16_t) coef_data_raw[15]);
83 this->c30_ = int16_t(((uint16_t) coef_data_raw[16] << 8) | (uint16_t) coef_data_raw[17]);
84}
85
87 ESP_LOGCONFIG(TAG,
88 "DPS310:\n"
89 " Product ID: %u\n"
90 " Revision ID: %u",
91 this->prod_rev_id_ & 0x0F, (this->prod_rev_id_ >> 4) & 0x0F);
92 LOG_I2C_DEVICE(this);
93 if (this->is_failed()) {
94 ESP_LOGE(TAG, ESP_LOG_MSG_COMM_FAIL);
95 }
96 LOG_UPDATE_INTERVAL(this);
97 LOG_SENSOR(" ", "Temperature", this->temperature_sensor_);
98 LOG_SENSOR(" ", "Pressure", this->pressure_sensor_);
99}
100
102 if (!this->update_in_progress_) {
103 this->update_in_progress_ = true;
104 this->read_();
105 }
106}
107
109 uint8_t reg = 0;
110 if (!this->read_byte(DPS310_REG_MEAS_CFG, &reg)) {
111 this->status_set_warning();
112 return;
113 }
114
115 if ((!this->got_pres_) && (reg & DPS310_BIT_PRS_RDY)) {
116 this->read_pressure_();
117 }
118
119 if ((!this->got_temp_) && (reg & DPS310_BIT_TMP_RDY)) {
120 this->read_temperature_();
121 }
122
123 if (this->got_pres_ && this->got_temp_) {
125 this->got_pres_ = false;
126 this->got_temp_ = false;
127 this->update_in_progress_ = false;
128 this->status_clear_warning();
129 } else {
130 auto f = std::bind(&DPS310Component::read_, this);
131 this->set_timeout("dps310", 10, f);
132 }
133}
134
136 uint8_t bytes[3];
137 if (!this->read_bytes(DPS310_REG_PRS_B2, bytes, 3)) {
138 this->status_set_warning();
139 return;
140 }
141 this->got_pres_ = true;
143 int32_t((uint32_t(bytes[0]) << 16) | (uint32_t(bytes[1]) << 8) | (uint32_t(bytes[2]))), 24);
144}
145
147 uint8_t bytes[3];
148 if (!this->read_bytes(DPS310_REG_TMP_B2, bytes, 3)) {
149 this->status_set_warning();
150 return;
151 }
152 this->got_temp_ = true;
154 int32_t((uint32_t(bytes[0]) << 16) | (uint32_t(bytes[1]) << 8) | (uint32_t(bytes[2]))), 24);
155}
156
157// Calculations are taken from the datasheet which can be found here:
158// https://www.infineon.com/dgdl/Infineon-DPS310-DataSheet-v01_02-EN.pdf?fileId=5546d462576f34750157750826c42242
159// Sections "How to Calculate Compensated Pressure Values" and "How to Calculate Compensated Temperature Values"
160// Variable names below match variable names from the datasheet but lowercased
161void DPS310Component::calculate_values_(int32_t raw_temperature, int32_t raw_pressure) {
162 const float t_raw_sc = (float) raw_temperature / DPS310_SCALE_FACTOR;
163 const float p_raw_sc = (float) raw_pressure / DPS310_SCALE_FACTOR;
164
165 const float temperature = t_raw_sc * this->c1_ + this->c0_; // c0/2 done earlier!
166
167 const float pressure = (this->c00_ + p_raw_sc * (this->c10_ + p_raw_sc * (this->c20_ + p_raw_sc * this->c30_)) +
168 t_raw_sc * this->c01_ + t_raw_sc * p_raw_sc * (this->c11_ + p_raw_sc * this->c21_)) /
169 100; // divide by 100 for hPa
170
171 if (this->temperature_sensor_ != nullptr) {
172 this->temperature_sensor_->publish_state(temperature);
173 }
174 if (this->pressure_sensor_ != nullptr) {
175 this->pressure_sensor_->publish_state(pressure);
176 }
177}
178
179int32_t DPS310Component::twos_complement(int32_t val, uint8_t bits) {
180 if (val & ((uint32_t) 1 << (bits - 1))) {
181 val -= (uint32_t) 1 << bits;
182 }
183 return val;
184}
185
186} // namespace dps310
187} // namespace esphome
virtual void mark_failed()
Mark this component as failed.
bool is_failed() const
void status_set_warning(const char *message=nullptr)
ESPDEPRECATED("Use const char* or uint32_t overload instead. Removed in 2026.7.0", "2026.1.0") void set_timeout(const std voi set_timeout)(const char *name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
Definition component.h:429
ESPDEPRECATED("set_retry is deprecated and will be removed in 2026.8.0. Use set_timeout or set_interval instead.", "2026.2.0") void set_retry(const std uint32_t uint8_t std::function< RetryResult(uint8_t)> && f
Definition component.h:373
void status_clear_warning()
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:161
static int32_t twos_complement(int32_t val, uint8_t bits)
Definition dps310.cpp:179
bool write_byte(uint8_t a_register, uint8_t data) const
Definition i2c.h:266
bool read_byte(uint8_t a_register, uint8_t *data)
Definition i2c.h:241
I2CRegister reg(uint8_t a_register)
calls the I2CRegister constructor
Definition i2c.h:153
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:218
void publish_state(float state)
Publish a new state to the front-end.
Definition sensor.cpp:65
mopeka_std_values val[4]
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
void IRAM_ATTR HOT delay(uint32_t ms)
Definition core.cpp:26
uint16_t temperature
Definition sun_gtil2.cpp:12
uint8_t pressure
Definition tt21100.cpp:7