@@ -43,6 +43,14 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver {
4343 : WipperSnapper_I2C_Driver(i2c, sensorAddress) {
4444 _i2c = i2c;
4545 _sensorAddress = sensorAddress;
46+ _massConcentrationPm1p0 = NAN;
47+ _massConcentrationPm2p5 = NAN;
48+ _massConcentrationPm4p0 = NAN;
49+ _massConcentrationPm10p0 = NAN;
50+ _ambientHumidity = NAN;
51+ _ambientTemperature = NAN;
52+ _vocIndex = NAN;
53+ _noxIndex = NAN;
4654 }
4755
4856 /* ******************************************************************************/
@@ -68,6 +76,62 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver {
6876 return true ;
6977 }
7078
79+ /* ******************************************************************************/
80+ /* !
81+ @brief Checks if sensor was read within last 1s, or is the first read.
82+ @returns True if the sensor was recently read, False otherwise.
83+ */
84+ bool hasBeenReadInLastSecond () {
85+ return _lastRead != 0 && millis () - _lastRead < 1000 ;
86+ }
87+
88+ /* ******************************************************************************/
89+ /* !
90+ @brief Checks if the sensor is ready to be read
91+ @returns True if the sensor is ready, False otherwise.
92+ */
93+ /* ******************************************************************************/
94+ bool isSensorReady () {
95+ bool isDataReady = false ;
96+ uint16_t error = _sen->readDataReady (isDataReady);
97+ if (error != 0 || !isDataReady) {
98+ // failed, one more quick attempt
99+ delay (100 );
100+ error = _sen->readDataReady (isDataReady);
101+ if (error != 0 || !isDataReady) {
102+ return false ;
103+ }
104+ }
105+ return true ;
106+ }
107+
108+ /* ******************************************************************************/
109+ /* !
110+ @brief Reads the sensor.
111+ @returns True if the sensor was read successfully, False otherwise.
112+ */
113+ /* ******************************************************************************/
114+ bool readSensorData () {
115+ // dont read sensor more than once per second
116+ if (hasBeenReadInLastSecond ()) {
117+ return true ;
118+ }
119+
120+ if (!isSensorReady ()) {
121+ return false ;
122+ }
123+
124+ uint16_t error = _sen->readMeasuredValues (
125+ _massConcentrationPm1p0, _massConcentrationPm2p5,
126+ _massConcentrationPm4p0, _massConcentrationPm10p0, _ambientHumidity,
127+ _ambientTemperature, _vocIndex, _noxIndex);
128+ if (error != 0 ) {
129+ return false ;
130+ }
131+ _lastRead = millis ();
132+ return true ;
133+ }
134+
71135 /* ******************************************************************************/
72136 /* !
73137 @brief Gets the SEN5X's current temperature.
@@ -78,20 +142,10 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver {
78142 */
79143 /* ******************************************************************************/
80144 bool getEventAmbientTemp (sensors_event_t *tempEvent) {
81- float massConcentrationPm1p0, massConcentrationPm2p5,
82- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
83- ambientTemperature, vocIndex, noxIndex;
84- uint16_t error;
85-
86- error = _sen->readMeasuredValues (
87- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
88- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
89- noxIndex);
90- if ((_tempSensorPeriod != 0 && error != 0 ) || ambientTemperature == NAN) {
145+ if (!readSensorData () || _ambientTemperature == NAN) {
91146 return false ;
92147 }
93-
94- tempEvent->temperature = ambientTemperature;
148+ tempEvent->temperature = _ambientTemperature;
95149 return true ;
96150 }
97151
@@ -105,20 +159,10 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver {
105159 */
106160 /* ******************************************************************************/
107161 bool getEventRelativeHumidity (sensors_event_t *humidEvent) {
108- float massConcentrationPm1p0, massConcentrationPm2p5,
109- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
110- ambientTemperature, vocIndex, noxIndex;
111- uint16_t error;
112-
113- error = _sen->readMeasuredValues (
114- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
115- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
116- noxIndex);
117- if ((_humidSensorPeriod != 0 && error != 0 ) || ambientHumidity == NAN) {
162+ if (!readSensorData () || _ambientHumidity == NAN) {
118163 return false ;
119164 }
120-
121- humidEvent->relative_humidity = ambientHumidity;
165+ humidEvent->relative_humidity = _ambientHumidity;
122166 return true ;
123167 }
124168
@@ -135,20 +179,10 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver {
135179 */
136180 /* ******************************************************************************/
137181 bool getEventNOxIndex (sensors_event_t *noxIndexEvent) {
138- float massConcentrationPm1p0, massConcentrationPm2p5,
139- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
140- ambientTemperature, vocIndex, noxIndex;
141- uint16_t error;
142-
143- error = _sen->readMeasuredValues (
144- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
145- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
146- noxIndex);
147- if ((_NOxIndexPeriod != 0 && error != 0 ) || noxIndex == NAN) {
182+ if (!readSensorData () || _noxIndex == NAN) {
148183 return false ;
149184 }
150-
151- noxIndexEvent->nox_index = noxIndex;
185+ noxIndexEvent->nox_index = _noxIndex;
152186 return true ;
153187 }
154188
@@ -162,20 +196,10 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver {
162196 */
163197 /* ******************************************************************************/
164198 bool getEventVOCIndex (sensors_event_t *vocIndexEvent) {
165- float massConcentrationPm1p0, massConcentrationPm2p5,
166- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
167- ambientTemperature, vocIndex, noxIndex;
168- uint16_t error;
169-
170- error = _sen->readMeasuredValues (
171- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
172- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
173- noxIndex);
174- if ((_VOCIndexPeriod != 0 && error != 0 ) || vocIndex == NAN) {
199+ if (!readSensorData () || _vocIndex == NAN) {
175200 return false ;
176201 }
177-
178- vocIndexEvent->voc_index = vocIndex;
202+ vocIndexEvent->voc_index = _vocIndex;
179203 return true ;
180204 }
181205
@@ -189,22 +213,11 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver {
189213 */
190214 /* ******************************************************************************/
191215 bool getEventPM10_STD (sensors_event_t *pm10StdEvent) {
192- float massConcentrationPm1p0, massConcentrationPm2p5,
193- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
194- ambientTemperature, vocIndex, noxIndex;
195- uint16_t error;
196-
197- error = _sen->readMeasuredValues (
198- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
199- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
200- noxIndex);
201- if ((_PM10SensorPeriod != 0 && error != 0 ) ||
202- massConcentrationPm1p0 == NAN ||
203- massConcentrationPm1p0 == OVERFLOW_SEN55) {
216+ if (!readSensorData () || _massConcentrationPm1p0 == NAN ||
217+ _massConcentrationPm1p0 == OVERFLOW_SEN55) {
204218 return false ;
205219 }
206-
207- pm10StdEvent->pm10_std = massConcentrationPm1p0;
220+ pm10StdEvent->pm10_std = _massConcentrationPm1p0;
208221 return true ;
209222 }
210223
@@ -218,22 +231,11 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver {
218231 */
219232 /* ******************************************************************************/
220233 bool getEventPM25_STD (sensors_event_t *pm25StdEvent) {
221- float massConcentrationPm1p0, massConcentrationPm2p5,
222- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
223- ambientTemperature, vocIndex, noxIndex;
224- uint16_t error;
225-
226- error = _sen->readMeasuredValues (
227- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
228- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
229- noxIndex);
230- if ((_PM25SensorPeriod != 0 && error != 0 ) ||
231- massConcentrationPm2p5 == NAN ||
232- massConcentrationPm2p5 == OVERFLOW_SEN55) {
234+ if (!readSensorData () || _massConcentrationPm2p5 == NAN ||
235+ _massConcentrationPm2p5 == OVERFLOW_SEN55) {
233236 return false ;
234237 }
235-
236- pm25StdEvent->pm25_std = massConcentrationPm2p5;
238+ pm25StdEvent->pm25_std = _massConcentrationPm2p5;
237239 return true ;
238240 }
239241
@@ -247,22 +249,11 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver {
247249 */
248250 /* ******************************************************************************/
249251 bool getEventPM40_STD (sensors_event_t *pm40StdEvent) {
250- float massConcentrationPm1p0, massConcentrationPm2p5,
251- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
252- ambientTemperature, vocIndex, noxIndex;
253- uint16_t error;
254-
255- error = _sen->readMeasuredValues (
256- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
257- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
258- noxIndex);
259- if ((_PM25SensorPeriod != 0 && error != 0 ) ||
260- massConcentrationPm4p0 == NAN ||
261- massConcentrationPm4p0 == OVERFLOW_SEN55) {
252+ if (!readSensorData () || _massConcentrationPm4p0 == NAN ||
253+ _massConcentrationPm4p0 == OVERFLOW_SEN55) {
262254 return false ;
263255 }
264-
265- pm40StdEvent->data [0 ] = massConcentrationPm4p0;
256+ pm40StdEvent->data [0 ] = _massConcentrationPm4p0;
266257 return true ;
267258 }
268259
@@ -276,27 +267,20 @@ class WipperSnapper_I2C_Driver_SEN5X : public WipperSnapper_I2C_Driver {
276267 */
277268 /* ******************************************************************************/
278269 bool getEventPM100_STD (sensors_event_t *pm100StdEvent) {
279- float massConcentrationPm1p0, massConcentrationPm2p5,
280- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
281- ambientTemperature, vocIndex, noxIndex;
282- uint16_t error;
283-
284- error = _sen->readMeasuredValues (
285- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
286- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
287- noxIndex);
288- if ((_PM100SensorPeriod != 0 && error != 0 ) ||
289- massConcentrationPm10p0 == NAN ||
290- massConcentrationPm10p0 == OVERFLOW_SEN55) {
270+ if (!readSensorData () || _massConcentrationPm10p0 == NAN ||
271+ _massConcentrationPm10p0 == OVERFLOW_SEN55) {
291272 return false ;
292273 }
293-
294- pm100StdEvent->pm100_std = massConcentrationPm10p0;
274+ pm100StdEvent->pm100_std = _massConcentrationPm10p0;
295275 return true ;
296276 }
297277
298278protected:
299- SensirionI2CSen5x *_sen; // /< SEN5X driver object
279+ SensirionI2CSen5x *_sen = nullptr ; // /< SEN5X driver object
280+ float _massConcentrationPm1p0, _massConcentrationPm2p5,
281+ _massConcentrationPm4p0, _massConcentrationPm10p0, _ambientHumidity,
282+ _ambientTemperature, _vocIndex, _noxIndex; // /< Sensor values
283+ ulong _lastRead = 0uL; // /< Last time the sensor was read
300284};
301285
302286#endif // WipperSnapper_I2C_Driver_SEN5X
0 commit comments