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