embedded_devices/devices/sensirion/sen65/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::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=16) {
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 }
70
71 struct MeasuredRawValues(size=8) {
72 /// Raw relative humidity, LSB = 0.01%
73 raw_relative_humidity: i16 = i16::MAX => {
74 quantity: Ratio,
75 unit: percent,
76 lsb: 1f64 / 100f64,
77 },
78 /// Raw temperature, LSB = 0.005°C
79 raw_temperature: i16 = i16::MAX => {
80 quantity: ThermodynamicTemperature,
81 unit: degree_celsius,
82 lsb: 1f64 / 200f64,
83 },
84 /// VOC ticks, LSB = 1
85 voc_ticks: u16 = u16::MAX,
86 /// NOx ticks, LSB = 1
87 /// Will be i16::MAX for the first 10-11 seconds after startup or reset.
88 nox_ticks: u16 = u16::MAX,
89 }
90
91 struct DeviceStatus(size=4) {
92 _: u16{10},
93 /// Fan is switched on, but its speed is more than 10% off the target speed for multiple
94 /// consecutive measurement intervals. During the first 10 seconds after starting the
95 /// measurement, the fan speed is not checked (settling time). Very low or very high ambient
96 /// temperature could trigger this warning during startup. If this flag is set constantly, it
97 /// might indicate a problem with the power supply or with the fan, and the measured PM values
98 /// might be wrong. This flag is automatically cleared as soon as the measured speed is within
99 /// 10% of the target speed or when leaving the measure mode.
100 ///
101 /// Can occur only in measurement mode.
102 fan_speed_warning: bool = false,
103 _: u8, // reserved1
104 _: bool, // reserved_co2_error
105 /// Error related to the PM sensor. The particulate matter values might be unknown or wrong if
106 /// this flag is set, relative humidity and temperature values might be out of specs due to
107 /// compensation algorithms depending on PM sensor state.
108 ///
109 /// Can occur only in measurement mode.
110 pm_error: bool = false,
111 _: bool, // reserved_hcho_error
112 _: bool, // reserved_co2_error2
113 _: bool, // reserved2
114 /// Error related to the gas sensor. The VOC index and NOx index might be unknown or wrong if
115 /// this flag is set, relative humidity and temperature values might be out of specs due to
116 /// compensation algorithms depending on gas sensor state.
117 ///
118 /// Can occur only in measurement mode.
119 gas_error: bool = false,
120 /// Error related to the RH&T sensor. The temperature and humidity values might be unknown or
121 /// wrong if this flag is set, and other measured values might be out of specs due compensation
122 /// algorithms depending on RH&T sensor values.
123 ///
124 /// Can occur only in measurement mode.
125 rh_t_error: bool = false,
126 _: bool, // reserved3
127 /// Fan is switched on, but 0 RPM is measured for multiple consecutive measurement intervals.
128 /// This can occur if the fan is mechanically blocked or broken. Note that the measured values
129 /// are most likely wrong if this error is reported.
130 ///
131 /// Can occur only in measurement mode.
132 fan_error: bool = false,
133 _: u8{4}, // reserved4
134 }
135}
136
137define_sensirion_commands! {
138 id_len 2;
139 marker [
140 ("sensirion-sen65", crate::devices::sensirion::sen65::SEN65Command),
141 ];
142
143 /// Returns the measured values. The command [`GetDataReady`] can be used to check if new data is
144 /// available since the last read operation. If no new data is available, the previous values will
145 /// be returned. If no data is available at all (e.g. measurement not running for at least one
146 /// second), all values will be at their upper limit (0xFFFF for u16, 0x7FFF for i16).
147 ///
148 /// May be executed during measurement.
149 read 0x0446 time_ms=20 ReadMeasuredValues() -> MeasuredValues;
150
151 /// Returns the measured raw values. The command [`GetDataReady`] can be used to check if new data
152 /// is available since the last read operation. If no new data is available, the previous values
153 /// will be returned. If no data is available at all (e.g. measurement not running for at least one
154 /// second), all values will be at their upper limit (0xFFFF for u16, 0x7FFF for i16).
155 ///
156 /// May be executed during measurement.
157 read 0x0455 time_ms=20 ReadMeasuredRawValues() -> MeasuredRawValues;
158
159 /// Reads the current device status.
160 ///
161 /// Note: The status flags of type `Error` are sticky, i.e. they are not cleared automatically even
162 /// if the error condition no longer exists. So, they can only be cleared manually with
163 /// [`ReadAndClearDeviceStatus`] or through a reset, either by calling [`DeviceReset`] or through a
164 /// power cycle. All other flags are not sticky, i.e. they are cleared automatically if the trigger
165 /// condition disappears.
166 ///
167 /// May be executed during measurement.
168 read 0xd206 time_ms=20 ReadDeviceStatus() -> DeviceStatus;
169
170 /// Reads the current device status (like command [`ReadDeviceStatus`]) and clears all
171 /// flags afterwards.
172 ///
173 /// May be executed during measurement.
174 read 0xd210 time_ms=20 ReadAndClearDeviceStatus() -> DeviceStatus;
175}