@@ -12,49 +12,45 @@ static const char *const ESP_LOG_MSG_CO2_CAL_FAIL = "Perform Forced CO₂ Calibr
1212static const char *const ESP_LOG_MSG_ACT_SHT_HEATER_FAIL = " Activate SHT Heater failed" ;
1313static const char *const ESP_LOG_MSG_FAN_CLEAN_FAIL = " Fan Cleaning failed" ;
1414
15- // ------------------------------------------------------------------------------------------------------------------------
16- // -------------------------------------------------------------------------SEN50|SEN54|SEN55|SEN60|SEN63|SEN65|SEN66|SEN68
17- // ------------------------------------------------------------------------------------------------------------------------
18- static const uint16_t SEN5X_C_READ_MEASUREMENT = 0x03C4 ; // ---------- * | * | * | | | | |
19- static const uint16_t SEN60_C_READ_MEASUREMENT = 0xEC05 ; // ---------- | | | * | | | |
20- static const uint16_t SEN63_C_READ_MEASUREMENT = 0x0471 ; // ---------- | | | | * | | |
21- static const uint16_t SEN65_C_READ_MEASUREMENT = 0x0446 ; // ---------- | | | | | * | |
22- static const uint16_t SEN66_C_READ_MEASUREMENT = 0x0300 ; // ---------- | | | | | | * |
23- static const uint16_t SEN68_C_READ_MEASUREMENT = 0x0467 ; // ---------- | | | | | | | *
24- static const uint16_t SEN60_C_RESET = 0x3F8D ; // ---------- | | | * | | | |
25- static const uint16_t SEN60_C_START_MEASUREMENTS = 0x2152 ; // ---------- | | | * | | | |
26- static const uint16_t SEN60_C_STOP_MEASUREMENTS = 0x3F86 ; // ---------- | | | * | | | |
27- static const uint16_t SEN60_C_GET_DATA_READY_STATUS = 0xE4B8 ; // ---------- | | | * | | | |
28- static const uint16_t SEN60_C_START_CLEANING_FAN = 0x3730 ; // ---------- | | | * | | | |
29- static const uint16_t SEN60_C_GET_SERIAL_NUMBER = 0x3682 ; // ---------- | | | * | | | |
30- static const uint16_t SEN60_C_READ_DEVICE_STATUS = 0xD206 ; // ---------- | | | * | | | |
31-
32- static const uint16_t SEN6X_C_TEMPERATURE_ACCEL_PARAMETERS = 0x6100 ; // --- | | | | * | * | * | *
33- static const uint16_t SEN6X_C_PERFORM_FORCED_CO2_RECAL = 0x6707 ; // --- | | | | * | | * |
34- static const uint16_t SEN6X_C_CO2_SENSOR_AUTO_SELF_CAL = 0x6711 ; // --- | | | | * | | * |
35- static const uint16_t SEN6X_C_AMBIENT_PRESSURE = 0x6720 ; // --- | | | | * | * | * | *
36- static const uint16_t SEN6X_C_SENSOR_ALTITUDE = 0x6736 ; // --- | | | | * | * | * | *
37- static const uint16_t SEN6X_C_ACTIVATE_SHT_HEATER = 0x6765 ; // --- | | | | * | * | * | *
38- static const uint16_t SEN6X_C_READ_DEVICE_STATUS = 0xD206 ; // --- | | | | * | * | * | *
39- static const uint16_t SEN6X_C_READ_AND_CLEAR_DEVICE_STATUS = 0xD210 ; // --- | | | | * | * | * | *
40-
41- static const uint16_t SEN5X_C_START_MEASUREMENTS_RHT_ONLY = 0x0037 ; // ---- * | * | * | | | | |
42- static const uint16_t SEN5X_C_RHT_ACCELERATION_MODE = 0x60F7 ; // ---- * | * | * | | | | |
43- static const uint16_t SEN5X_C_AUTO_CLEANING_INTERVAL = 0x8004 ; // ---- * | * | * | | | | |
44-
45- static const uint16_t C_RESET = 0xD304 ; // ------------- * | * | * | | * | * | * | *
46- static const uint16_t C_START_MEASUREMENTS = 0x0021 ; // ------------- * | * | * | | * | * | * | *
47- static const uint16_t C_STOP_MEASUREMENTS = 0x0104 ; // ------------- * | * | * | | * | * | * | *
48- static const uint16_t C_START_CLEANING_FAN = 0x5607 ; // ------------- * | * | * | | * | * | * | *
49- static const uint16_t C_TEMPERATURE_COMPENSATION = 0x60B2 ; // ------------- * | * | * | | * | * | * | *
50- static const uint16_t C_VOC_ALGORITHM_TUNING = 0x60D0 ; // ------------- * | * | * | | | * | * | *
51- static const uint16_t C_NOX_ALGORITHM_TUNING = 0x60E1 ; // ------------- * | * | * | | | * | * | *
52- static const uint16_t C_VOC_ALGORITHM_STATE = 0x6181 ; // ------------- * | * | * | | | * | * | *
53- static const uint16_t C_GET_PRODUCT_NAME = 0xD014 ; // ------------- * | * | * | | * | * | * | *
54- static const uint16_t C_GET_SERIAL_NUMBER = 0xD033 ; // ------------- * | * | * | | * | * | * | *
55- static const uint16_t C_GET_DATA_READY_STATUS = 0x0202 ; // ------------- * | * | * | | * | * | * | *
56- static const uint16_t C_GET_FIRMWARE_VERSION = 0xD100 ; // ------------- * | * | * | ? | * | * | * | *
57- // -------------------------------------------------------------------------------------------------------------------------
15+ static const uint16_t SEN5X_CMD_READ_MEASUREMENT = 0x03C4 ;
16+ static const uint16_t SEN60_CMD_READ_MEASUREMENT = 0xEC05 ;
17+ static const uint16_t SEN63_CMD_READ_MEASUREMENT = 0x0471 ;
18+ static const uint16_t SEN65_CMD_READ_MEASUREMENT = 0x0446 ;
19+ static const uint16_t SEN66_CMD_READ_MEASUREMENT = 0x0300 ;
20+ static const uint16_t SEN68_CMD_READ_MEASUREMENT = 0x0467 ;
21+ static const uint16_t SEN60_CMD_RESET = 0x3F8D ;
22+ static const uint16_t SEN60_CMD_START_MEASUREMENTS = 0x2152 ;
23+ static const uint16_t SEN60_CMD_STOP_MEASUREMENTS = 0x3F86 ;
24+ static const uint16_t SEN60_CMD_GET_DATA_READY_STATUS = 0xE4B8 ;
25+ static const uint16_t SEN60_CMD_START_CLEANING_FAN = 0x3730 ;
26+ static const uint16_t SEN60_CMD_GET_SERIAL_NUMBER = 0x3682 ;
27+ static const uint16_t SEN60_CMD_READ_DEVICE_STATUS = 0xD206 ;
28+
29+ static const uint16_t SEN6X_CMD_TEMPERATURE_ACCEL_PARAMETERS = 0x6100 ;
30+ static const uint16_t SEN6X_CMD_PERFORM_FORCED_CO2_RECAL = 0x6707 ;
31+ static const uint16_t SEN6X_CMD_CO2_SENSOR_AUTO_SELF_CAL = 0x6711 ;
32+ static const uint16_t SEN6X_CMD_AMBIENT_PRESSURE = 0x6720 ;
33+ static const uint16_t SEN6X_CMD_SENSOR_ALTITUDE = 0x6736 ;
34+ static const uint16_t SEN6X_CMD_ACTIVATE_SHT_HEATER = 0x6765 ;
35+ static const uint16_t SEN6X_CMD_READ_DEVICE_STATUS = 0xD206 ;
36+ static const uint16_t SEN6X_CMD_READ_AND_CLEAR_DEVICE_STATUS = 0xD210 ;
37+
38+ static const uint16_t SEN5X_CMD_START_MEASUREMENTS_RHT_ONLY = 0x0037 ;
39+ static const uint16_t SEN5X_CMD_RHT_ACCELERATION_MODE = 0x60F7 ;
40+ static const uint16_t SEN5X_CMD_AUTO_CLEANING_INTERVAL = 0x8004 ;
41+
42+ static const uint16_t CMD_RESET = 0xD304 ;
43+ static const uint16_t CMD_START_MEASUREMENTS = 0x0021 ;
44+ static const uint16_t CMD_STOP_MEASUREMENTS = 0x0104 ;
45+ static const uint16_t CMD_START_CLEANING_FAN = 0x5607 ;
46+ static const uint16_t CMD_TEMPERATURE_COMPENSATION = 0x60B2 ;
47+ static const uint16_t CMD_VOC_ALGORITHM_TUNING = 0x60D0 ;
48+ static const uint16_t CMD_NOX_ALGORITHM_TUNING = 0x60E1 ;
49+ static const uint16_t CMD_VOC_ALGORITHM_STATE = 0x6181 ;
50+ static const uint16_t CMD_GET_PRODUCT_NAME = 0xD014 ;
51+ static const uint16_t CMD_GET_SERIAL_NUMBER = 0xD033 ;
52+ static const uint16_t CMD_GET_DATA_READY_STATUS = 0x0202 ;
53+ static const uint16_t CMD_GET_FIRMWARE_VERSION = 0xD100 ;
5854
5955static const int8_t SEN5X_INDEX_SCALE_FACTOR = 10 ; // used for VOC and NOx index values
6056static const int8_t SEN5X_MIN_INDEX_VALUE = 1 * SEN5X_INDEX_SCALE_FACTOR; // must be adjusted by the scale factor
@@ -116,7 +112,7 @@ void SEN5XComponent::internal_setup_(uint8_t state) {
116112 break ;
117113 case 1 :
118114 // Check if measurement is ready before reading the value
119- if (!this ->write_command (C_GET_DATA_READY_STATUS )) {
115+ if (!this ->write_command (CMD_GET_DATA_READY_STATUS )) {
120116 ESP_LOGE (TAG, " Failed to write data ready status command" );
121117 this ->error_code_ = COMMUNICATION_FAILED;
122118 this ->mark_failed ();
@@ -142,17 +138,18 @@ void SEN5XComponent::internal_setup_(uint8_t state) {
142138 this ->mark_failed ();
143139 return ;
144140 }
145- // According to the SEN5x datasheet the sensor will only respond to other commands after waiting 200 ms after
146- // issuing the stop_periodic_measurement command
147- // According to the SEN66 datasheet the sensor will only respond to other commands after waiting 1000 ms after
148- stop_measurement_delay = 1000 ;
141+ if (this ->is_sen6x ()) {
142+ stop_measurement_delay = 1000 ;
143+ } else {
144+ stop_measurement_delay = 200 ;
145+ }
149146 } else {
150147 stop_measurement_delay = 0 ;
151148 }
152149 this ->set_timeout (stop_measurement_delay, [this ]() { this ->internal_setup_ (3 ); });
153150 break ;
154151 case 3 :
155- if (!this ->get_register (C_GET_SERIAL_NUMBER , string_number, 16 , 20 )) {
152+ if (!this ->get_register (CMD_GET_SERIAL_NUMBER , string_number, 16 , 20 )) {
156153 ESP_LOGE (TAG, " Failed to read serial number" );
157154 this ->error_code_ = SERIAL_NUMBER_IDENTIFICATION_FAILED;
158155 this ->mark_failed ();
@@ -163,7 +160,7 @@ void SEN5XComponent::internal_setup_(uint8_t state) {
163160 this ->set_timeout (20 , [this ]() { this ->internal_setup_ (4 ); });
164161 break ;
165162 case 4 :
166- if (!this ->get_register (C_GET_PRODUCT_NAME , string_number, 16 , 20 )) {
163+ if (!this ->get_register (CMD_GET_PRODUCT_NAME , string_number, 16 , 20 )) {
167164 ESP_LOGE (TAG, " Failed to read product name" );
168165 this ->error_code_ = PRODUCT_NAME_FAILED;
169166 this ->mark_failed ();
@@ -206,7 +203,7 @@ void SEN5XComponent::internal_setup_(uint8_t state) {
206203 break ;
207204 case 5 :
208205 uint16_t firmware;
209- if (!this ->get_register (C_GET_FIRMWARE_VERSION , &firmware, 1 , 20 )) {
206+ if (!this ->get_register (CMD_GET_FIRMWARE_VERSION , &firmware, 1 , 20 )) {
210207 ESP_LOGE (TAG, " Failed to read firmware version" );
211208 this ->error_code_ = FIRMWARE_FAILED;
212209 this ->mark_failed ();
@@ -227,8 +224,7 @@ void SEN5XComponent::internal_setup_(uint8_t state) {
227224 if (this ->voc_sensor_ && this ->store_baseline_ ) {
228225 uint32_t combined_serial =
229226 encode_uint24 (this ->serial_number_ [0 ], this ->serial_number_ [1 ], this ->serial_number_ [2 ]);
230- // Hash with compilation time and serial number
231- // This ensures the baseline storage is cleared after OTA
227+ // Hash with compilation time and serial number, this ensures the baseline storage is cleared after OTA
232228 // Serial numbers are unique to each sensor, so multiple sensors can be used without conflict
233229 uint32_t hash = fnv1_hash (App.get_compilation_time () + this ->serial_number_ );
234230 this ->pref_ = global_preferences->make_preference <Sen5xBaselines>(hash, true );
@@ -251,7 +247,7 @@ void SEN5XComponent::internal_setup_(uint8_t state) {
251247 states[2 ] = voc_baselines_storage_.state1 >> 16 ;
252248 states[3 ] = voc_baselines_storage_.state1 & 0xFFFF ;
253249
254- if (!this ->write_command (C_VOC_ALGORITHM_STATE , states, 4 )) {
250+ if (!this ->write_command (CMD_VOC_ALGORITHM_STATE , states, 4 )) {
255251 ESP_LOGE (TAG, " Failed to set VOC baseline from saved state" );
256252 }
257253 }
@@ -267,7 +263,7 @@ void SEN5XComponent::internal_setup_(uint8_t state) {
267263 this ->mark_failed ();
268264 return ;
269265 }
270- if (!write_command (SEN5X_C_AUTO_CLEANING_INTERVAL , this ->auto_cleaning_interval_ .value ())) {
266+ if (!write_command (SEN5X_CMD_AUTO_CLEANING_INTERVAL , this ->auto_cleaning_interval_ .value ())) {
271267 ESP_LOGE (TAG, " Failed to set Automatic Cleaning Interval" );
272268 this ->error_code_ = COMMUNICATION_FAILED;
273269 this ->mark_failed ();
@@ -285,7 +281,7 @@ void SEN5XComponent::internal_setup_(uint8_t state) {
285281 this ->mark_failed ();
286282 return ;
287283 }
288- if (!this ->write_command (SEN5X_C_RHT_ACCELERATION_MODE , this ->acceleration_mode_ .value ())) {
284+ if (!this ->write_command (SEN5X_CMD_RHT_ACCELERATION_MODE , this ->acceleration_mode_ .value ())) {
289285 ESP_LOGE (TAG, " Failed to set RH/T Acceleration Mode" );
290286 this ->error_code_ = COMMUNICATION_FAILED;
291287 this ->mark_failed ();
@@ -304,7 +300,7 @@ void SEN5XComponent::internal_setup_(uint8_t state) {
304300 this ->mark_failed ();
305301 return ;
306302 }
307- if (!this ->write_tuning_parameters_ (C_VOC_ALGORITHM_TUNING , this ->voc_tuning_params_ .value ())) {
303+ if (!this ->write_tuning_parameters_ (CMD_VOC_ALGORITHM_TUNING , this ->voc_tuning_params_ .value ())) {
308304 ESP_LOGE (TAG, " Failed to set VOC Algorithm Tuning Parameters" );
309305 this ->error_code_ = COMMUNICATION_FAILED;
310306 this ->mark_failed ();
@@ -323,7 +319,7 @@ void SEN5XComponent::internal_setup_(uint8_t state) {
323319 this ->mark_failed ();
324320 return ;
325321 }
326- if (!this ->write_tuning_parameters_ (C_NOX_ALGORITHM_TUNING , this ->nox_tuning_params_ .value ())) {
322+ if (!this ->write_tuning_parameters_ (CMD_NOX_ALGORITHM_TUNING , this ->nox_tuning_params_ .value ())) {
327323 ESP_LOGE (TAG, " Failed to set VOC Algorithm Tuning Parameters" );
328324 this ->error_code_ = COMMUNICATION_FAILED;
329325 this ->mark_failed ();
@@ -362,7 +358,7 @@ void SEN5XComponent::internal_setup_(uint8_t state) {
362358 this ->mark_failed ();
363359 return ;
364360 }
365- if (!this ->write_command (SEN6X_C_CO2_SENSOR_AUTO_SELF_CAL , this ->co2_auto_calibrate_ .value () ? 0x01 : 0x00 )) {
361+ if (!this ->write_command (SEN6X_CMD_CO2_SENSOR_AUTO_SELF_CAL , this ->co2_auto_calibrate_ .value () ? 0x01 : 0x00 )) {
366362 ESP_LOGE (TAG, " Failed to set CO₂ Sensor Automatic Self Calibration" );
367363 this ->error_code_ = COMMUNICATION_FAILED;
368364 this ->mark_failed ();
@@ -382,7 +378,7 @@ void SEN5XComponent::internal_setup_(uint8_t state) {
382378 this ->mark_failed ();
383379 return ;
384380 }
385- if (!this ->write_command (SEN6X_C_CO2_SENSOR_AUTO_SELF_CAL , this ->co2_auto_calibrate_ .value () ? 0x01 : 0x00 )) {
381+ if (!this ->write_command (SEN6X_CMD_CO2_SENSOR_AUTO_SELF_CAL , this ->co2_auto_calibrate_ .value () ? 0x01 : 0x00 )) {
386382 ESP_LOGE (TAG, " Failed to set CO₂ Sensor Automatic Self Calibration" );
387383 this ->error_code_ = COMMUNICATION_FAILED;
388384 this ->mark_failed ();
@@ -545,7 +541,7 @@ void SEN5XComponent::update() {
545541 // Store baselines after defined interval or if the difference between current and stored baseline becomes too
546542 // much
547543 if (this ->store_baseline_ && this ->seconds_since_last_store_ > SHORTEST_BASELINE_STORE_INTERVAL) {
548- if (this ->write_command (C_VOC_ALGORITHM_STATE )) {
544+ if (this ->write_command (CMD_VOC_ALGORITHM_STATE )) {
549545 // run it a bit later to avoid adding a delay here
550546 this ->set_timeout (550 , [this ]() {
551547 uint16_t states[4 ];
@@ -577,27 +573,27 @@ void SEN5XComponent::update() {
577573 case SEN50:
578574 case SEN54:
579575 case SEN55:
580- cmd = SEN5X_C_READ_MEASUREMENT ;
576+ cmd = SEN5X_CMD_READ_MEASUREMENT ;
581577 length = 9 ;
582578 break ;
583579 case SEN60:
584- cmd = SEN60_C_READ_MEASUREMENT ;
580+ cmd = SEN60_CMD_READ_MEASUREMENT ;
585581 length = 4 ;
586582 break ;
587583 case SEN63C:
588- cmd = SEN63_C_READ_MEASUREMENT ;
584+ cmd = SEN63_CMD_READ_MEASUREMENT ;
589585 length = 7 ;
590586 break ;
591587 case SEN65:
592- cmd = SEN65_C_READ_MEASUREMENT ;
588+ cmd = SEN65_CMD_READ_MEASUREMENT ;
593589 length = 8 ;
594590 break ;
595591 case SEN66:
596- cmd = SEN66_C_READ_MEASUREMENT ;
592+ cmd = SEN66_CMD_READ_MEASUREMENT ;
597593 length = 9 ;
598594 break ;
599595 case SEN68:
600- cmd = SEN68_C_READ_MEASUREMENT ;
596+ cmd = SEN68_CMD_READ_MEASUREMENT ;
601597 length = 9 ;
602598 break ;
603599 }
@@ -721,20 +717,20 @@ bool SEN5XComponent::start_measurements_() {
721717 case SEN50:
722718 case SEN54:
723719 case SEN55:
724- cmd = SEN5X_C_START_MEASUREMENTS_RHT_ONLY ;
720+ cmd = SEN5X_CMD_START_MEASUREMENTS_RHT_ONLY ;
725721 if (this ->pm_1_0_sensor_ || this ->pm_2_5_sensor_ || this ->pm_4_0_sensor_ || this ->pm_10_0_sensor_ ) {
726722 // if any of the gas sensors are active we need a full measurement
727- cmd = C_START_MEASUREMENTS ;
723+ cmd = CMD_START_MEASUREMENTS ;
728724 }
729725 break ;
730726 case SEN60:
731- cmd = SEN60_C_START_MEASUREMENTS ;
727+ cmd = SEN60_CMD_START_MEASUREMENTS ;
732728 break ;
733729 case SEN63C:
734730 case SEN65:
735731 case SEN66:
736732 case SEN68:
737- cmd = C_START_MEASUREMENTS ;
733+ cmd = CMD_START_MEASUREMENTS ;
738734 break ;
739735 }
740736
@@ -750,9 +746,9 @@ bool SEN5XComponent::start_measurements_() {
750746bool SEN5XComponent::stop_measurements_ () {
751747 uint16_t cmd;
752748 if (this ->model_ .value () == SEN60) {
753- cmd = SEN60_C_STOP_MEASUREMENTS ;
749+ cmd = SEN60_CMD_STOP_MEASUREMENTS ;
754750 } else {
755- cmd = C_STOP_MEASUREMENTS ;
751+ cmd = CMD_STOP_MEASUREMENTS ;
756752 }
757753 auto result = this ->write_command (cmd);
758754 if (!result) {
@@ -803,15 +799,16 @@ bool SEN5XComponent::write_temperature_compensation_(const TemperatureCompensati
803799 params[0 ] = compensation.offset ;
804800 params[1 ] = compensation.normalized_offset_slope ;
805801 params[2 ] = compensation.time_constant ;
806- auto result = this ->write_command (C_TEMPERATURE_COMPENSATION , params, 3 );
802+ auto result = this ->write_command (CMD_TEMPERATURE_COMPENSATION , params, 3 );
807803 if (!result) {
808804 ESP_LOGE (TAG, " Write error Temperature Compensation (error=%d)" , this ->last_error_ );
809805 }
810806 return result;
811807}
812808
813809bool SEN5XComponent::update_co2_ambient_pressure_compensation_ (uint16_t pressure_in_hpa) {
814- auto result = this ->write_command (SEN6X_C_CO2_SENSOR_AUTO_SELF_CAL, this ->co2_auto_calibrate_ .value () ? 0x01 : 0x00 );
810+ auto result =
811+ this ->write_command (SEN6X_CMD_CO2_SENSOR_AUTO_SELF_CAL, this ->co2_auto_calibrate_ .value () ? 0x01 : 0x00 );
815812 if (!result) {
816813 ESP_LOGE (TAG, " Write error Auto Self Calibration (error=%d)" , this ->last_error_ );
817814 }
@@ -865,9 +862,9 @@ bool SEN5XComponent::start_fan_cleaning() {
865862 this ->set_timeout (1000 , [this ]() {
866863 uint16_t cmd;
867864 if (this ->model_ .value () == SEN60) {
868- cmd = SEN60_C_START_CLEANING_FAN ;
865+ cmd = SEN60_CMD_START_CLEANING_FAN ;
869866 } else {
870- cmd = C_START_CLEANING_FAN ;
867+ cmd = CMD_START_CLEANING_FAN ;
871868 }
872869 if (!this ->write_command (cmd)) {
873870 ESP_LOGE (TAG, " I2C Write error Start Cleaning Fan (error=%d)" , this ->last_error_ );
@@ -905,7 +902,7 @@ bool SEN5XComponent::activate_heater() {
905902 return false ;
906903 }
907904 this ->set_timeout (1000 , [this ]() {
908- if (!this ->write_command (SEN6X_C_ACTIVATE_SHT_HEATER )) {
905+ if (!this ->write_command (SEN6X_CMD_ACTIVATE_SHT_HEATER )) {
909906 ESP_LOGE (TAG, " I2C Write error Activate SHT Heater (error=%d)" , this ->last_error_ );
910907 if (!this ->running_ ) {
911908 this ->start_measurements_ ();
@@ -944,7 +941,7 @@ bool SEN5XComponent::perform_forced_co2_calibration(uint16_t co2) {
944941 return false ;
945942 }
946943 this ->set_timeout (1000 , [this , co2]() {
947- if (!this ->write_command (SEN6X_C_PERFORM_FORCED_CO2_RECAL , co2)) {
944+ if (!this ->write_command (SEN6X_CMD_PERFORM_FORCED_CO2_RECAL , co2)) {
948945 ESP_LOGE (TAG, " I2C Write error Perform Forced CO₂ Recalibration (error=%d)" , this ->last_error_ );
949946 if (!this ->running_ ) {
950947 this ->start_measurements_ ();
0 commit comments