@@ -45,6 +45,15 @@ class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
4545 : WipperSnapper_I2C_Driver(i2c, sensorAddress) {
4646 _i2c = i2c;
4747 _sensorAddress = sensorAddress;
48+ _massConcentrationPm1p0 = NAN;
49+ _massConcentrationPm2p5 = NAN;
50+ _massConcentrationPm4p0 = NAN;
51+ _massConcentrationPm10p0 = NAN;
52+ _ambientHumidity = NAN;
53+ _ambientTemperature = NAN;
54+ _vocIndex = NAN;
55+ _noxIndex = NAN;
56+ _co2 = 0uL;
4857 }
4958
5059 /* ******************************************************************************/
@@ -70,6 +79,63 @@ class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
7079 return true ;
7180 }
7281
82+ /* ******************************************************************************/
83+ /* !
84+ @brief Checks if sensor was read within last 1s, or is the first read.
85+ @returns True if the sensor was recently read, False otherwise.
86+ */
87+ bool hasBeenReadInLastSecond () {
88+ return _lastRead != 0 && millis () - _lastRead < 1000 ;
89+ }
90+
91+ /* ******************************************************************************/
92+ /* !
93+ @brief Checks if the sensor is ready to be read
94+ @returns True if the sensor is ready, False otherwise.
95+ */
96+ /* ******************************************************************************/
97+ bool isSensorReady () {
98+ bool isDataReady = false ;
99+ uint8_t padding = 0x0 ;
100+ uint16_t error = _sen->getDataReady (padding, isDataReady);
101+ if (error != 0 || !isDataReady) {
102+ // failed, one more quick attempt
103+ delay (100 );
104+ error = _sen->getDataReady (padding, isDataReady);
105+ if (error != 0 || !isDataReady) {
106+ return false ;
107+ }
108+ }
109+ return true ;
110+ }
111+
112+ /* ******************************************************************************/
113+ /* !
114+ @brief Reads the sensor.
115+ @returns True if the sensor was read successfully, False otherwise.
116+ */
117+ /* ******************************************************************************/
118+ bool readSensorData () {
119+ // dont read sensor more than once per second
120+ if (hasBeenReadInLastSecond ()) {
121+ return true ;
122+ }
123+
124+ if (!isSensorReady ()) {
125+ return false ;
126+ }
127+
128+ uint16_t error = _sen->readMeasuredValues (
129+ _massConcentrationPm1p0, _massConcentrationPm2p5,
130+ _massConcentrationPm4p0, _massConcentrationPm10p0, _ambientHumidity,
131+ _ambientTemperature, _vocIndex, _noxIndex, _co2);
132+ if (error != 0 ) {
133+ return false ;
134+ }
135+ _lastRead = millis ();
136+ return true ;
137+ }
138+
73139 /* ******************************************************************************/
74140 /* !
75141 @brief Gets the SEN6X's current temperature.
@@ -80,21 +146,10 @@ class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
80146 */
81147 /* ******************************************************************************/
82148 bool getEventAmbientTemp (sensors_event_t *tempEvent) {
83- float massConcentrationPm1p0, massConcentrationPm2p5,
84- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
85- ambientTemperature, vocIndex, noxIndex;
86- uint16_t co2;
87- uint16_t error;
88-
89- error = _sen->readMeasuredValues (
90- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
91- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
92- noxIndex, co2);
93- if ((_tempSensorPeriod != 0 && error != 0 ) || ambientTemperature == NAN) {
149+ if (!readSensorData () || _ambientTemperature == NAN) {
94150 return false ;
95151 }
96-
97- tempEvent->temperature = ambientTemperature;
152+ tempEvent->temperature = _ambientTemperature;
98153 return true ;
99154 }
100155
@@ -108,21 +163,10 @@ class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
108163 */
109164 /* ******************************************************************************/
110165 bool getEventRelativeHumidity (sensors_event_t *humidEvent) {
111- float massConcentrationPm1p0, massConcentrationPm2p5,
112- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
113- ambientTemperature, vocIndex, noxIndex;
114- uint16_t co2;
115- uint16_t error;
116-
117- error = _sen->readMeasuredValues (
118- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
119- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
120- noxIndex, co2);
121- if ((_humidSensorPeriod != 0 && error != 0 ) || ambientHumidity == NAN) {
166+ if (!readSensorData () || _ambientHumidity == NAN) {
122167 return false ;
123168 }
124-
125- humidEvent->relative_humidity = ambientHumidity;
169+ humidEvent->relative_humidity = _ambientHumidity;
126170 return true ;
127171 }
128172
@@ -139,21 +183,10 @@ class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
139183 */
140184 /* ******************************************************************************/
141185 bool getEventNOxIndex (sensors_event_t *noxIndexEvent) {
142- float massConcentrationPm1p0, massConcentrationPm2p5,
143- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
144- ambientTemperature, vocIndex, noxIndex;
145- uint16_t co2;
146- uint16_t error;
147-
148- error = _sen->readMeasuredValues (
149- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
150- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
151- noxIndex, co2);
152- if ((_NOxIndexPeriod != 0 && error != 0 ) || noxIndex == NAN) {
186+ if (!readSensorData () || _noxIndex == NAN) {
153187 return false ;
154188 }
155-
156- noxIndexEvent->nox_index = noxIndex;
189+ noxIndexEvent->nox_index = _noxIndex;
157190 return true ;
158191 }
159192
@@ -167,21 +200,10 @@ class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
167200 */
168201 /* ******************************************************************************/
169202 bool getEventVOCIndex (sensors_event_t *vocIndexEvent) {
170- float massConcentrationPm1p0, massConcentrationPm2p5,
171- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
172- ambientTemperature, vocIndex, noxIndex;
173- uint16_t co2;
174- uint16_t error;
175-
176- error = _sen->readMeasuredValues (
177- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
178- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
179- noxIndex, co2);
180- if ((_VOCIndexPeriod != 0 && error != 0 ) || vocIndex == NAN) {
203+ if (!readSensorData () || _vocIndex == NAN) {
181204 return false ;
182205 }
183-
184- vocIndexEvent->voc_index = vocIndex;
206+ vocIndexEvent->voc_index = _vocIndex;
185207 return true ;
186208 }
187209
@@ -195,23 +217,11 @@ class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
195217 */
196218 /* ******************************************************************************/
197219 bool getEventPM10_STD (sensors_event_t *pm10StdEvent) {
198- float massConcentrationPm1p0, massConcentrationPm2p5,
199- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
200- ambientTemperature, vocIndex, noxIndex;
201- uint16_t co2;
202- uint16_t error;
203-
204- error = _sen->readMeasuredValues (
205- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
206- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
207- noxIndex, co2);
208- if ((_PM10SensorPeriod != 0 && error != 0 ) ||
209- massConcentrationPm1p0 == NAN ||
210- massConcentrationPm1p0 == OVERFLOW_SEN6X) {
220+ if (!readSensorData () || _massConcentrationPm1p0 == NAN ||
221+ _massConcentrationPm1p0 == OVERFLOW_SEN6X) {
211222 return false ;
212223 }
213-
214- pm10StdEvent->pm10_std = massConcentrationPm1p0;
224+ pm10StdEvent->pm10_std = _massConcentrationPm1p0;
215225 return true ;
216226 }
217227
@@ -225,23 +235,11 @@ class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
225235 */
226236 /* ******************************************************************************/
227237 bool getEventPM25_STD (sensors_event_t *pm25StdEvent) {
228- float massConcentrationPm1p0, massConcentrationPm2p5,
229- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
230- ambientTemperature, vocIndex, noxIndex;
231- uint16_t co2;
232- uint16_t error;
233-
234- error = _sen->readMeasuredValues (
235- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
236- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
237- noxIndex, co2);
238- if ((_PM25SensorPeriod != 0 && error != 0 ) ||
239- massConcentrationPm2p5 == NAN ||
240- massConcentrationPm2p5 == OVERFLOW_SEN6X) {
238+ if (!readSensorData () || _massConcentrationPm2p5 == NAN ||
239+ _massConcentrationPm2p5 == OVERFLOW_SEN6X) {
241240 return false ;
242241 }
243-
244- pm25StdEvent->pm25_std = massConcentrationPm2p5;
242+ pm25StdEvent->pm25_std = _massConcentrationPm2p5;
245243 return true ;
246244 }
247245
@@ -255,23 +253,11 @@ class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
255253 */
256254 /* ******************************************************************************/
257255 bool getEventPM40_STD (sensors_event_t *pm40StdEvent) {
258- float massConcentrationPm1p0, massConcentrationPm2p5,
259- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
260- ambientTemperature, vocIndex, noxIndex;
261- uint16_t co2;
262- uint16_t error;
263-
264- error = _sen->readMeasuredValues (
265- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
266- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
267- noxIndex, co2);
268- if ((_PM25SensorPeriod != 0 && error != 0 ) ||
269- massConcentrationPm4p0 == NAN ||
270- massConcentrationPm4p0 == OVERFLOW_SEN6X) {
256+ if (!readSensorData () || _massConcentrationPm4p0 == NAN ||
257+ _massConcentrationPm4p0 == OVERFLOW_SEN6X) {
271258 return false ;
272259 }
273-
274- pm40StdEvent->data [0 ] = massConcentrationPm4p0;
260+ pm40StdEvent->data [0 ] = _massConcentrationPm4p0;
275261 return true ;
276262 }
277263
@@ -285,23 +271,11 @@ class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
285271 */
286272 /* ******************************************************************************/
287273 bool getEventPM100_STD (sensors_event_t *pm100StdEvent) {
288- float massConcentrationPm1p0, massConcentrationPm2p5,
289- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
290- ambientTemperature, vocIndex, noxIndex;
291- uint16_t co2;
292- uint16_t error;
293-
294- error = _sen->readMeasuredValues (
295- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
296- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
297- noxIndex, co2);
298- if ((_PM100SensorPeriod != 0 && error != 0 ) ||
299- massConcentrationPm10p0 == NAN ||
300- massConcentrationPm10p0 == OVERFLOW_SEN6X) {
274+ if (!readSensorData () || _massConcentrationPm10p0 == NAN ||
275+ _massConcentrationPm10p0 == OVERFLOW_SEN6X) {
301276 return false ;
302277 }
303-
304- pm100StdEvent->pm100_std = massConcentrationPm10p0;
278+ pm100StdEvent->pm100_std = _massConcentrationPm10p0;
305279 return true ;
306280 }
307281
@@ -315,27 +289,20 @@ class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
315289 */
316290 /* ******************************************************************************/
317291 bool getEventCO2 (sensors_event_t *co2Event) {
318- float massConcentrationPm1p0, massConcentrationPm2p5,
319- massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
320- ambientTemperature, vocIndex, noxIndex;
321- uint16_t co2;
322- uint16_t error;
323-
324- error = _sen->readMeasuredValues (
325- massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
326- massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
327- noxIndex, co2);
328-
329- if ((_CO2SensorPeriod != 0 && error != 0 ) || co2 == 0xFFFF ) {
292+ if (!readSensorData () || _co2 == 0xFFFF ) {
330293 return false ;
331294 }
332-
333- co2Event->CO2 = co2;
295+ co2Event->CO2 = _co2;
334296 return true ;
335297 }
336298
337299protected:
338- SensirionI2cSen66 *_sen; // /< SEN6X driver object
300+ SensirionI2cSen66 *_sen = nullptr ; // /< SEN6X driver object
301+ float _massConcentrationPm1p0, _massConcentrationPm2p5,
302+ _massConcentrationPm4p0, _massConcentrationPm10p0, _ambientHumidity,
303+ _ambientTemperature, _vocIndex, _noxIndex; // /< Sensor float values
304+ uint16_t _co2; // /< CO2 value
305+ ulong _lastRead; // /< Last time the sensor was read
339306};
340307
341308#endif // WipperSnapper_I2C_Driver_SEN6X
0 commit comments