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}