embedded_devices/devices/sensirion/sen66/commands.rs
1use crate::devices::sensirion::commands::define_sensirion_commands;
2use embedded_interfaces::codegen::interface_objects;
3use uom::si::{
4 f64::{MassConcentration, Ratio, ThermodynamicTemperature},
5 mass_concentration::microgram_per_cubic_meter,
6 ratio::{part_per_million, percent},
7 thermodynamic_temperature::degree_celsius,
8};
9
10pub use crate::devices::sensirion::sen6x::commands::{
11 ActivateSHTHeater, AmbientPressure, DeviceReset, GetCo2SensorAutomaticSelfCalibration, GetDataReady,
12 GetNOxAlgorithmTuningParameters, GetProductName, GetSensorAltitude, GetSerialNumber, GetVOCAlgorithmState,
13 GetVOCAlgorithmTuningParameters, PerformForcedCo2Recalibration, ReadNumberConcentrationValues,
14 SetCo2SensorAutomaticSelfCalibration, SetNOxAlgorithmTuningParameters, SetSensorAltitude,
15 SetTemperatureAccelerationParameters, SetTemperatureOffsetParameters, SetVOCAlgorithmState,
16 SetVOCAlgorithmTuningParameters, StartContinuousMeasurement, StartFanCleaning, StopMeasurement,
17};
18
19interface_objects! {
20 struct MeasuredValues(size=18) {
21 /// PM1 mass concentration, LSB = 0.1 µg/m³
22 raw_mass_concentration_pm1: u16 = u16::MAX => {
23 quantity: MassConcentration,
24 unit: microgram_per_cubic_meter,
25 lsb: 1f64 / 10f64,
26 },
27 /// PM2.5 mass concentration, LSB = 0.1 µg/m³
28 raw_mass_concentration_pm2_5: u16 = u16::MAX => {
29 quantity: MassConcentration,
30 unit: microgram_per_cubic_meter,
31 lsb: 1f64 / 10f64,
32 },
33 /// PM4 mass concentration, LSB = 0.1 µg/m³
34 raw_mass_concentration_pm4: u16 = u16::MAX => {
35 quantity: MassConcentration,
36 unit: microgram_per_cubic_meter,
37 lsb: 1f64 / 10f64,
38 },
39 /// PM10 mass concentration, LSB = 0.1 µg/m³
40 raw_mass_concentration_pm10: u16 = u16::MAX => {
41 quantity: MassConcentration,
42 unit: microgram_per_cubic_meter,
43 lsb: 1f64 / 10f64,
44 },
45 /// Ambient relative humidity, LSB = 0.01%
46 raw_relative_humidity: i16 = i16::MAX => {
47 quantity: Ratio,
48 unit: percent,
49 lsb: 1f64 / 100f64,
50 },
51 /// Ambient temperature, LSB = 0.005°C
52 raw_temperature: i16 = i16::MAX => {
53 quantity: ThermodynamicTemperature,
54 unit: degree_celsius,
55 lsb: 1f64 / 200f64,
56 },
57 /// VOC index, LSB = 0.1
58 raw_voc_index: i16 = i16::MAX => {
59 quantity: Ratio,
60 unit: percent,
61 lsb: 1f64 / 10f64,
62 },
63 /// NOx index, LSB = 0.1
64 /// Will be i16::MAX for the first 10-11 seconds after startup or reset.
65 raw_nox_index: i16 = i16::MAX => {
66 quantity: Ratio,
67 unit: percent,
68 lsb: 1f64 / 10f64,
69 },
70 /// CO2 concentration, LSB = 1 ppm
71 /// Will be u16::MAX for the first 5-6 seconds after startup or reset.
72 raw_co2_concentration: u16 = u16::MAX => {
73 quantity: Ratio,
74 unit: part_per_million,
75 lsb: 1f64 / 1f64,
76 },
77 }
78
79 struct MeasuredRawValues(size=10) {
80 /// Raw relative humidity, LSB = 0.01%
81 raw_relative_humidity: i16 = i16::MAX => {
82 quantity: Ratio,
83 unit: percent,
84 lsb: 1f64 / 100f64,
85 },
86 /// Raw temperature, LSB = 0.005°C
87 raw_temperature: i16 = i16::MAX => {
88 quantity: ThermodynamicTemperature,
89 unit: degree_celsius,
90 lsb: 1f64 / 200f64,
91 },
92 /// VOC ticks, LSB = 1
93 voc_ticks: u16 = u16::MAX,
94 /// NOx ticks, LSB = 1
95 /// Will be i16::MAX for the first 10-11 seconds after startup or reset.
96 nox_ticks: u16 = u16::MAX,
97 /// CO2 concentration, not interpolated, LSB = 1 ppm
98 /// Will be u16::MAX for the first 5-6 seconds after startup or reset.
99 raw_co2_concentration: u16 = u16::MAX => {
100 quantity: Ratio,
101 unit: part_per_million,
102 lsb: 1f64 / 1f64,
103 },
104 }
105
106 struct DeviceStatus(size=4) {
107 _: u16{10},
108 /// Fan is switched on, but its speed is more than 10% off the target speed for multiple
109 /// consecutive measurement intervals. During the first 10 seconds after starting the
110 /// measurement, the fan speed is not checked (settling time). Very low or very high ambient
111 /// temperature could trigger this warning during startup. If this flag is set constantly, it
112 /// might indicate a problem with the power supply or with the fan, and the measured PM values
113 /// might be wrong. This flag is automatically cleared as soon as the measured speed is within
114 /// 10% of the target speed or when leaving the measure mode.
115 ///
116 /// Can occur only in measurement mode.
117 fan_speed_warning: bool = false,
118 _: u8, // reserved1
119 _: bool, // reserved_co2_error1
120 /// Error related to the PM sensor. The particulate matter values might be unknown or wrong if
121 /// this flag is set, relative humidity and temperature values might be out of specs due to
122 /// compensation algorithms depending on PM sensor state.
123 ///
124 /// Can occur only in measurement mode.
125 pm_error: bool = false,
126 _: bool, // reserved_hcho_error
127 /// Error related to the CO2 sensor. The CO2 values might be unknown or wrong if this flag is
128 /// set, relative humidity and temperature values might be out of specs due to compensation
129 /// algorithms depending on CO2 sensor state.
130 ///
131 /// Can occur only in measurement mode.
132 co2_error: bool = false,
133 _: bool, // reserved2
134 /// Error related to the gas sensor. The VOC index and NOx index might be unknown or wrong if
135 /// this flag is set, relative humidity and temperature values might be out of specs due to
136 /// compensation algorithms depending on gas sensor state.
137 ///
138 /// Can occur only in measurement mode.
139 gas_error: bool = false,
140 /// Error related to the RH&T sensor. The temperature and humidity values might be unknown or
141 /// wrong if this flag is set, and other measured values might be out of specs due compensation
142 /// algorithms depending on RH&T sensor values.
143 ///
144 /// Can occur only in measurement mode.
145 rh_t_error: bool = false,
146 _: bool, // reserved3
147 /// Fan is switched on, but 0 RPM is measured for multiple consecutive measurement intervals.
148 /// This can occur if the fan is mechanically blocked or broken. Note that the measured values
149 /// are most likely wrong if this error is reported.
150 ///
151 /// Can occur only in measurement mode.
152 fan_error: bool = false,
153 _: u8{4}, // reserved4
154 }
155}
156
157define_sensirion_commands! {
158 id_len 2;
159 marker [
160 ("sensirion-sen66", crate::devices::sensirion::sen66::SEN66Command),
161 ];
162
163 /// Returns the measured values. The command [`GetDataReady`] can be used to check if new data is
164 /// available since the last read operation. If no new data is available, the previous values will
165 /// be returned. If no data is available at all (e.g. measurement not running for at least one
166 /// second), all values will be at their upper limit (0xFFFF for u16, 0x7FFF for i16).
167 ///
168 /// May be executed during measurement.
169 read 0x0300 time_ms=20 ReadMeasuredValues() -> MeasuredValues;
170
171 /// Returns the measured raw values. The command [`GetDataReady`] can be used to check if new data
172 /// is available since the last read operation. If no new data is available, the previous values
173 /// will be returned. If no data is available at all (e.g. measurement not running for at least one
174 /// second), all values will be at their upper limit (0xFFFF for u16, 0x7FFF for i16).
175 ///
176 /// May be executed during measurement.
177 read 0x0405 time_ms=20 ReadMeasuredRawValues() -> MeasuredRawValues;
178
179 /// Reads the current device status.
180 ///
181 /// Note: The status flags of type `Error` are sticky, i.e. they are not cleared automatically even
182 /// if the error condition no longer exists. So, they can only be cleared manually with
183 /// [`ReadAndClearDeviceStatus`] or through a reset, either by calling [`DeviceReset`] or through a
184 /// power cycle. All other flags are not sticky, i.e. they are cleared automatically if the trigger
185 /// condition disappears.
186 ///
187 /// May be executed during measurement.
188 read 0xd206 time_ms=20 ReadDeviceStatus() -> DeviceStatus;
189
190 /// Reads the current device status (like command [`ReadDeviceStatus`]) and clears all
191 /// flags afterwards.
192 ///
193 /// May be executed during measurement.
194 read 0xd210 time_ms=20 ReadAndClearDeviceStatus() -> DeviceStatus;
195}