12static const char *
const TAG =
"scd30";
14static const uint16_t SCD30_CMD_GET_FIRMWARE_VERSION = 0xd100;
15static const uint16_t SCD30_CMD_START_CONTINUOUS_MEASUREMENTS = 0x0010;
16static const uint16_t SCD30_CMD_ALTITUDE_COMPENSATION = 0x5102;
17static const uint16_t SCD30_CMD_AUTOMATIC_SELF_CALIBRATION = 0x5306;
18static const uint16_t SCD30_CMD_GET_DATA_READY_STATUS = 0x0202;
19static const uint16_t SCD30_CMD_READ_MEASUREMENT = 0x0300;
22static const uint16_t SCD30_CMD_STOP_MEASUREMENTS = 0x0104;
23static const uint16_t SCD30_CMD_MEASUREMENT_INTERVAL = 0x4600;
24static const uint16_t SCD30_CMD_FORCED_CALIBRATION = 0x5204;
25static const uint16_t SCD30_CMD_TEMPERATURE_OFFSET = 0x5403;
26static const uint16_t SCD30_CMD_SOFT_RESET = 0xD304;
30 Wire.setClockStretchLimit(150000);
34 uint16_t raw_firmware_version[3];
35 if (!this->
get_register(SCD30_CMD_GET_FIRMWARE_VERSION, raw_firmware_version, 3)) {
40 ESP_LOGD(TAG,
"SCD30 Firmware v%0d.%02d", (uint16_t(raw_firmware_version[0]) >> 8),
41 uint16_t(raw_firmware_version[0] & 0xFF));
50 if (!this->
write_command(SCD30_CMD_TEMPERATURE_OFFSET, temp_offset)) {
51 ESP_LOGE(TAG,
"Sensor SCD30 error setting temperature offset.");
70 ESP_LOGE(TAG,
"Sensor SCD30 error setting update interval.");
82 ESP_LOGE(TAG,
"Sensor SCD30 error setting altitude compensation.");
93 ESP_LOGE(TAG,
"Sensor SCD30 error setting automatic self calibration.");
104 ESP_LOGE(TAG,
"Sensor SCD30 error starting continuous measurements.");
118 ESP_LOGCONFIG(TAG,
"scd30:");
119 LOG_I2C_DEVICE(
this);
121 switch (this->error_code_) {
123 ESP_LOGW(TAG, ESP_LOG_MSG_COMM_FAIL);
126 ESP_LOGW(TAG,
"Measurement Initialization failed");
129 ESP_LOGW(TAG,
"Unable to read sensor firmware version");
132 ESP_LOGW(TAG,
"Unknown setup error");
137 ESP_LOGCONFIG(TAG,
" Altitude compensation: OFF");
142 " Automatic self calibration: %s\n"
143 " Ambient pressure compensation: %dmBar\n"
144 " Temperature offset: %.2f °C\n"
145 " Update interval: %ds",
154 uint16_t raw_read_status;
155 if (!this->
read_data(raw_read_status) || raw_read_status == 0x00) {
157 ESP_LOGW(TAG,
"Data not ready yet!");
162 ESP_LOGW(TAG,
"Error reading measurement!");
168 uint16_t raw_data[6];
174 union uint32_float_t {
178 uint32_t temp_c_o2_u32 = (((uint32_t(raw_data[0])) << 16) | (uint32_t(raw_data[1])));
179 uint32_float_t co2{.uint32 = temp_c_o2_u32};
181 uint32_t temp_temp_u32 = (((uint32_t(raw_data[2])) << 16) | (uint32_t(raw_data[3])));
182 uint32_float_t
temperature{.uint32 = temp_temp_u32};
184 uint32_t temp_hum_u32 = (((uint32_t(raw_data[4])) << 16) | (uint32_t(raw_data[5])));
185 uint32_float_t humidity{.uint32 = temp_hum_u32};
187 ESP_LOGD(TAG,
"Got CO2=%.2fppm temperature=%.2f°C humidity=%.2f%%", co2.value,
temperature.value, humidity.value);
204 uint16_t is_data_ready;
205 if (!this->
read_data(&is_data_ready, 1)) {
208 return is_data_ready == 1;
212 ESP_LOGD(TAG,
"Performing CO2 force recalibration with reference %dppm.", co2_reference);
213 if (this->
write_command(SCD30_CMD_FORCED_CALIBRATION, co2_reference)) {
214 ESP_LOGD(TAG,
"Force recalibration complete.");
217 ESP_LOGE(TAG,
"Failed to force recalibration with reference.");
225 uint16_t forced_calibration_reference;
227 if (!this->
get_register(SCD30_CMD_FORCED_CALIBRATION, forced_calibration_reference)) {
228 ESP_LOGE(TAG,
"Unable to read forced calibration reference.");
230 return forced_calibration_reference;
virtual void mark_failed()
Mark this component as failed.
void status_set_warning(const char *message=nullptr)
void set_interval(const std::string &name, uint32_t interval, std::function< void()> &&f)
Set an interval function with a unique name.
void status_clear_warning()
void set_timeout(const std::string &name, uint32_t timeout, std::function< void()> &&f)
Set a timeout function with a unique name.
uint16_t ambient_pressure_compensation_
sensor::Sensor * humidity_sensor_
sensor::Sensor * temperature_sensor_
uint16_t get_forced_calibration_reference()
uint16_t altitude_compensation_
float temperature_offset_
bool force_recalibration_with_reference(uint16_t co2_reference)
@ MEASUREMENT_INIT_FAILED
@ FORCE_RECALIBRATION_FAILED
@ FIRMWARE_IDENTIFICATION_FAILED
sensor::Sensor * co2_sensor_
void dump_config() override
uint16_t update_interval_
bool get_register(uint16_t command, uint16_t *data, uint8_t len, uint8_t delay=0)
get data words from i2c register.
bool write_command(T i2c_register)
Write a command to the i2c device.
bool read_data(uint16_t *data, uint8_t len)
Read data words from i2c device.
void publish_state(float state)
Publish a new state to the front-end.
Providing packet encoding functions for exchanging data with a remote host.
void IRAM_ATTR HOT delay(uint32_t ms)