Skip to content

Commit aba5d51

Browse files
derived from sen5x driver
1 parent 570c166 commit aba5d51

File tree

2 files changed

+341
-0
lines changed

2 files changed

+341
-0
lines changed

platformio.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ lib_deps =
8585
https://github.com/Sensirion/arduino-sht.git
8686
https://github.com/Sensirion/arduino-i2c-scd4x.git
8787
https://github.com/Sensirion/arduino-i2c-sen5x.git
88+
https://github.com/Sensirion/arduino-i2c-sen66.git
8889
https://github.com/adafruit/WiFiNINA.git
8990
https://github.com/Starmbi/hp_BH1750.git
9091
https://github.com/adafruit/Adafruit_TinyUSB_Arduino.git
Lines changed: 340 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,340 @@
1+
/*!
2+
* @file WipperSnapper_I2C_Driver_SEN6x.h
3+
*
4+
* Device driver for the SEN66 Particulate Matter, Temperature, Humidity, VOC, NOX, and CO2 sensor.
5+
*
6+
* Adafruit invests time and resources providing this open source code,
7+
* please support Adafruit and open-source hardware by purchasing
8+
* products from Adafruit!
9+
*
10+
* Copyright (c) Marni Brewster 2022 for Adafruit Industries.
11+
* Modified (c) by Martin Ebner 2024 https://github.com/MartinEbnerSensirion
12+
*
13+
* MIT license, all text here must be included in any redistribution.
14+
*
15+
*/
16+
17+
#ifndef WipperSnapper_I2C_Driver_SEN6X_H
18+
#define WipperSnapper_I2C_Driver_SEN6X_H
19+
20+
#include "WipperSnapper_I2C_Driver.h"
21+
#include <SensirionI2CSen66.h>
22+
#include <Wire.h>
23+
24+
/**************************************************************************/
25+
/*!
26+
@brief Class that provides a driver interface for the SEN6X sensor.
27+
*/
28+
/**************************************************************************/
29+
class WipperSnapper_I2C_Driver_SEN6X : public WipperSnapper_I2C_Driver {
30+
31+
const float OVERFLOW_SEN6X = (0xFFFF / 10); // maxes out at u_int16 / 10
32+
33+
public:
34+
/*******************************************************************************/
35+
/*!
36+
@brief Constructor for a SEN6X sensor.
37+
@param i2c
38+
The I2C interface.
39+
@param sensorAddress
40+
7-bit device address.
41+
*/
42+
/*******************************************************************************/
43+
WipperSnapper_I2C_Driver_SEN6X(TwoWire *i2c, uint16_t sensorAddress)
44+
: WipperSnapper_I2C_Driver(i2c, sensorAddress) {
45+
_i2c = i2c;
46+
_sensorAddress = sensorAddress;
47+
}
48+
49+
/*******************************************************************************/
50+
/*!
51+
@brief Initializes the SEN6X sensor and begins I2C.
52+
@returns True if initialized successfully, False otherwise.
53+
*/
54+
/*******************************************************************************/
55+
bool begin() {
56+
_sen = new SensirionI2cSen66();
57+
_sen->begin(*_i2c, (uint8_t)_sensorAddress);
58+
u_int16_t error_stop = _sen->deviceReset();
59+
if (error_stop != 0) {
60+
return false;
61+
}
62+
// Wait 1 second for sensors to start recording + 100ms for reset command
63+
delay(1100);
64+
u_int16_t error_start = _sen->startContinuousMeasurement();
65+
if (error_start != 0) {
66+
return false;
67+
}
68+
69+
return true;
70+
}
71+
72+
/*******************************************************************************/
73+
/*!
74+
@brief Gets the SEN6X's current temperature.
75+
@param tempEvent
76+
Pointer to an Adafruit_Sensor event.
77+
@returns True if the temperature was obtained successfully, False
78+
otherwise.
79+
*/
80+
/*******************************************************************************/
81+
bool getEventAmbientTemp(sensors_event_t *tempEvent) {
82+
float massConcentrationPm1p0, massConcentrationPm2p5,
83+
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
84+
ambientTemperature, vocIndex, noxIndex;
85+
uint16_t co2;
86+
uint16_t error;
87+
88+
error = _sen->readMeasuredValues(
89+
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
90+
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
91+
noxIndex, co2);
92+
if ((_tempSensorPeriod != 0 && error != 0) || ambientTemperature == NAN) {
93+
return false;
94+
}
95+
96+
tempEvent->temperature = ambientTemperature;
97+
return true;
98+
}
99+
100+
/*******************************************************************************/
101+
/*!
102+
@brief Gets the SEN6X's current relative humidity reading.
103+
@param humidEvent
104+
Pointer to an Adafruit_Sensor event.
105+
@returns True if the humidity was obtained successfully, False
106+
otherwise.
107+
*/
108+
/*******************************************************************************/
109+
bool getEventRelativeHumidity(sensors_event_t *humidEvent) {
110+
float massConcentrationPm1p0, massConcentrationPm2p5,
111+
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
112+
ambientTemperature, vocIndex, noxIndex;
113+
uint16_t co2;
114+
uint16_t error;
115+
116+
error = _sen->readMeasuredValues(
117+
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
118+
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
119+
noxIndex, co2);
120+
if ((_humidSensorPeriod != 0 && error != 0) || ambientHumidity == NAN) {
121+
return false;
122+
}
123+
124+
humidEvent->relative_humidity = ambientHumidity;
125+
return true;
126+
}
127+
128+
/*******************************************************************************/
129+
/*!
130+
@brief Gets the SEN6X's current NOX reading.
131+
Note: If this value is unknown, which is true for SEN54,
132+
NAN is returned. During the first 10..11 seconds after
133+
power-on or device reset, this value will be NAN as well.
134+
@param noxIndexEvent
135+
Adafruit Sensor event for NOx Index (0-500, 1 is normal)
136+
@returns True if the sensor value was obtained successfully, False
137+
otherwise.
138+
*/
139+
/*******************************************************************************/
140+
bool getEventNOxIndex(sensors_event_t *noxIndexEvent) {
141+
float massConcentrationPm1p0, massConcentrationPm2p5,
142+
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
143+
ambientTemperature, vocIndex, noxIndex;
144+
uint16_t co2;
145+
uint16_t error;
146+
147+
error = _sen->readMeasuredValues(
148+
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
149+
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
150+
noxIndex, co2);
151+
if ((_NOxIndexPeriod != 0 && error != 0) || noxIndex == NAN) {
152+
return false;
153+
}
154+
155+
noxIndexEvent->nox_index = noxIndex;
156+
return true;
157+
}
158+
159+
/*******************************************************************************/
160+
/*!
161+
@brief Gets the SEN6X's current VOC reading.
162+
@param vocIndexEvent
163+
Adafruit Sensor event for VOC Index (1-500, 100 is normal)
164+
@returns True if the sensor value was obtained successfully, False
165+
otherwise.
166+
*/
167+
/*******************************************************************************/
168+
bool getEventVOCIndex(sensors_event_t *vocIndexEvent) {
169+
float massConcentrationPm1p0, massConcentrationPm2p5,
170+
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
171+
ambientTemperature, vocIndex, noxIndex;
172+
uint16_t co2;
173+
uint16_t error;
174+
175+
error = _sen->readMeasuredValues(
176+
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
177+
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
178+
noxIndex, co2);
179+
if ((_VOCIndexPeriod != 0 && error != 0) || vocIndex == NAN) {
180+
return false;
181+
}
182+
183+
vocIndexEvent->voc_index = vocIndex;
184+
return true;
185+
}
186+
187+
/*******************************************************************************/
188+
/*!
189+
@brief Gets the SEN6X sensor's PM1.0 STD reading.
190+
@param pm10StdEvent
191+
Adafruit Sensor event for PM1.0
192+
@returns True if the sensor value was obtained successfully, False
193+
otherwise.
194+
*/
195+
/*******************************************************************************/
196+
bool getEventPM10_STD(sensors_event_t *pm10StdEvent) {
197+
float massConcentrationPm1p0, massConcentrationPm2p5,
198+
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
199+
ambientTemperature, vocIndex, noxIndex;
200+
uint16_t co2;
201+
uint16_t error;
202+
203+
error = _sen->readMeasuredValues(
204+
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
205+
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
206+
noxIndex, co2);
207+
if ((_PM10SensorPeriod != 0 && error != 0) ||
208+
massConcentrationPm1p0 == NAN ||
209+
massConcentrationPm1p0 == OVERFLOW_SEN6X) {
210+
return false;
211+
}
212+
213+
pm10StdEvent->pm10_std = massConcentrationPm1p0;
214+
return true;
215+
}
216+
217+
/*******************************************************************************/
218+
/*!
219+
@brief Gets the SEN6X sensor's PM2.5 STD reading.
220+
@param pm25StdEvent
221+
Adafruit Sensor event for PM2.5
222+
@returns True if the sensor value was obtained successfully, False
223+
otherwise.
224+
*/
225+
/*******************************************************************************/
226+
bool getEventPM25_STD(sensors_event_t *pm25StdEvent) {
227+
float massConcentrationPm1p0, massConcentrationPm2p5,
228+
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
229+
ambientTemperature, vocIndex, noxIndex;
230+
uint16_t co2;
231+
uint16_t error;
232+
233+
error = _sen->readMeasuredValues(
234+
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
235+
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
236+
noxIndex, co2);
237+
if ((_PM25SensorPeriod != 0 && error != 0) ||
238+
massConcentrationPm2p5 == NAN ||
239+
massConcentrationPm2p5 == OVERFLOW_SEN6X) {
240+
return false;
241+
}
242+
243+
pm25StdEvent->pm25_std = massConcentrationPm2p5;
244+
return true;
245+
}
246+
247+
/*******************************************************************************/
248+
/*!
249+
@brief Gets the SEN6X sensor's PM4.0 STD reading.
250+
@param pm40StdEvent
251+
Adafruit Sensor event for PM4.0
252+
@returns True if the sensor value was obtained successfully, False
253+
otherwise.
254+
*/
255+
/*******************************************************************************/
256+
bool getEventPM40_STD(sensors_event_t *pm40StdEvent) {
257+
float massConcentrationPm1p0, massConcentrationPm2p5,
258+
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
259+
ambientTemperature, vocIndex, noxIndex;
260+
uint16_t co2;
261+
uint16_t error;
262+
263+
error = _sen->readMeasuredValues(
264+
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
265+
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
266+
noxIndex, co2);
267+
if ((_PM25SensorPeriod != 0 && error != 0) ||
268+
massConcentrationPm4p0 == NAN ||
269+
massConcentrationPm4p0 == OVERFLOW_SEN6X) {
270+
return false;
271+
}
272+
273+
pm40StdEvent->data[0] = massConcentrationPm4p0;
274+
return true;
275+
}
276+
277+
/*******************************************************************************/
278+
/*!
279+
@brief Gets the SEN6X sensor's PM10.0 STD reading.
280+
@param pm100StdEvent
281+
Adafruit Sensor event for PM10.0
282+
@returns True if the sensor value was obtained successfully, False
283+
otherwise.
284+
*/
285+
/*******************************************************************************/
286+
bool getEventPM100_STD(sensors_event_t *pm100StdEvent) {
287+
float massConcentrationPm1p0, massConcentrationPm2p5,
288+
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
289+
ambientTemperature, vocIndex, noxIndex;
290+
uint16_t co2;
291+
uint16_t error;
292+
293+
error = _sen->readMeasuredValues(
294+
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
295+
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
296+
noxIndex, co2);
297+
if ((_PM100SensorPeriod != 0 && error != 0) ||
298+
massConcentrationPm10p0 == NAN ||
299+
massConcentrationPm10p0 == OVERFLOW_SEN6X) {
300+
return false;
301+
}
302+
303+
pm100StdEvent->pm100_std = massConcentrationPm10p0;
304+
return true;
305+
}
306+
307+
/*******************************************************************************/
308+
/*!
309+
@brief Gets the SEN6X sensor's CO2 reading.
310+
@param co2Event
311+
Adafruit Sensor event for CO2
312+
@returns True if the sensor value was obtained successfully, False
313+
otherwise.
314+
*/
315+
/*******************************************************************************/
316+
bool getEventCO2(sensors_event_t *co2Event) {
317+
float massConcentrationPm1p0, massConcentrationPm2p5,
318+
massConcentrationPm4p0, massConcentrationPm10p0, ambientHumidity,
319+
ambientTemperature, vocIndex, noxIndex;
320+
uint16_t co2;
321+
uint16_t error;
322+
323+
error = _sen->readMeasuredValues(
324+
massConcentrationPm1p0, massConcentrationPm2p5, massConcentrationPm4p0,
325+
massConcentrationPm10p0, ambientHumidity, ambientTemperature, vocIndex,
326+
noxIndex, co2);
327+
328+
if ((_CO2SensorPeriod != 0 && error != 0) || co2 == NAN) {
329+
return false;
330+
}
331+
332+
co2Event->CO2 = co2;
333+
return true;
334+
}
335+
336+
protected:
337+
SensirionI2cSen66 *_sen; ///< SEN6X driver object
338+
};
339+
340+
#endif // WipperSnapper_I2C_Driver_SEN6X

0 commit comments

Comments
 (0)