CanAirIO Sensors Library  0.7.3
Generic sensor manager, abstratctions and bindings of multiple air sensors libraries
Sensors.hpp
1 #ifndef Sensors_hpp
2 #define Sensors_hpp
3 
4 #include <AHTxx.h>
5 #include <AM232X.h>
6 #include <Adafruit_BME280.h>
7 #include <Adafruit_BME680.h>
8 #include <Adafruit_BMP280.h>
9 #include <Adafruit_SHT31.h>
10 #include <Adafruit_SCD30.h>
11 #include <Adafruit_Sensor.h>
12 #include <MHZ19.h>
13 #include <SparkFun_Particle_Sensor_SN-GCJA5_Arduino_Library.h>
14 #include <cm1106_uart.h>
15 #include <s8_uart.h>
16 #include <SensirionI2CScd4x.h>
17 #include <sps30.h>
18 #include <SensirionI2CSen5x.h>
19 #include <drivers/pm1006.h>
20 #include <drivers/geiger.h>
21 #include <DFRobot_MultiGasSensor.h>
22 
23 #ifdef DHT11_ENABLED
24 #include <dht_nonblocking.h>
25 #endif
26 
27 #define CSL_VERSION "0.7.3"
28 #define CSL_REVISION 382
29 
30 /***************************************************************
31 * S E T U P E S P 3 2 B O A R D S A N D F I E L D S
32 ***************************************************************/
33 
34 #ifdef WEMOSOLED
35 #define PMS_RX 13 // config for Wemos board & TTGO18650
36 #define PMS_TX 15 // some old TTGO18650 have PMS_RX 18 & PMS_TX 17
37 #elif HELTEC
38 #define PMS_RX 17 // config for Heltec board, ESP32Sboard & ESPDUINO-32. Use Uart2
39 #define PMS_TX 18 // some old ESP32Sboard have PMS_RX 27 & PMS_TX 25. Jump Uart2 tx from 16 to 18. !6 used by Oled.
40 #elif TTGO_TQ
41 #define PMS_RX 13
42 #define PMS_TX 18
43 #elif M5COREINK
44 #define PMS_RX 13 // config for backward header in M5CoreInk
45 #define PMS_TX 14
46 #elif TTGO_TDISPLAY
47 #define PMS_RX 13
48 #define PMS_TX 12
49 #elif ESP32PICOD4
50 #define PMS_RX 19
51 #define PMS_TX 18
52 #elif ESP32GENERIC
53 #define PMS_RX RX
54 #define PMS_TX TX
55 #elif M5STICKCPLUS
56 #define PMS_RX 36 // provisional for M5StickCPlus board for now
57 #define PMS_TX 0
58 #elif M5COREINK
59 #define PMS_RX 13
60 #define PMS_TX 14
61 #elif M5ATOM
62 #define PMS_RX 23
63 #define PMS_TX 33
64 #elif M5PICOD4
65 #define PMS_RX 3
66 #define PMS_TX 1
67 #elif ESP32C3
68 #define PMS_RX 20
69 #define PMS_TX 21
70 
71 #else // **DEFAULT** for legacy CanAirIO devices:
72 #define PMS_RX 17 // D1MIN1 / TTGOT7 / ESP32DEVKIT, also for main ESP32 dev boards use it
73 #define PMS_TX 16
74 #endif
75 
76 // I2C pins for M5COREINK and M5STICKCPLUS
77 #define HAT_I2C_SDA 0
78 #define HAT_I2C_SCL 26
79 #define EXT_I2C_SDA 32
80 #define EXT_I2C_SCL 33
81 
82 // Read UART sensor retry.
83 #define SENSOR_RETRY 1000 // Max Serial characters
84 
85 // UART defualt port
86 #define SENSOR_COMMS SERIALPORT2
87 
88 // Sensors units definitions (symbol/name)
89 #define SENSOR_UNITS \
90  X(NUNIT, "NUNIT", "NUNIT") \
91  X(PM1, "ug/m3", "PM1") \
92  X(PM25, "ug/m3", "PM2.5") \
93  X(PM4, "ug/m3", "PM4") \
94  X(PM10, "ug/m3", "PM10") \
95  X(TEMP, "C", "T") \
96  X(TEMPK, "K", "T") \
97  X(TEMPF, "F", "T") \
98  X(HUM, "%", "H") \
99  X(CO2, "ppm", "CO2") \
100  X(CO2TEMP, "C", "CO2T") \
101  X(CO2TEMPK, "K", "CO2TK") \
102  X(CO2TEMPF, "F", "CO2TF") \
103  X(CO2HUM, "%", "CO2H") \
104  X(PRESS, "hPa", "P") \
105  X(ALT, "m", "Alt") \
106  X(GAS, "Ohm", "Gas") \
107  X(CPM, "CPM", "RAD") \
108  X(RAD, "uSv/h", "RAD") \
109  X(NH3, "ppm", "NH3") \
110  X(CO, "ppm", "CO") \
111  X(NO2, "ppm", "NO2") \
112  X(UCOUNT, "COUNT", "UCOUNT")
113 
114 
115 #define X(unit, symbol, name) unit,
116 typedef enum UNIT : size_t { SENSOR_UNITS } UNIT;
117 #undef X
118 
119 // sensors types: 1:PM, 2:CO2, 3:ENV
120 #define SENSORS_TYPES \
121  X(Auto, "GENERIC", 1) \
122  X(SGCJA5, "GCJA5", 1) \
123  X(SSPS30, "SPS30", 1) \
124  X(SDS011, "SDS011", 1) \
125  X(SMHZ19, "MHZ19", 2) \
126  X(SCM1106, "CM1106", 2) \
127  X(SAIRS8, "SAIRS8", 2) \
128  X(IKEAVK, "IKEAVK",1) \
129  X(SSCD30, "SCD30", 2) \
130  X(SSCD4X, "SCD4X", 2) \
131  X(SSEN5X, "SEN5X", 1) \
132  X(SSHT31, "SHT31", 3) \
133  X(SBME280, "BME280", 3) \
134  X(SBMP280, "BMP280", 3) \
135  X(SBME680, "BME680", 3) \
136  X(SAHTXX, "AHTXX", 3) \
137  X(SAM232X, "AM232X", 3) \
138  X(SDHTX, "DHTX", 3) \
139  X(SDFRCO, "DFRCO", 3) \
140  X(SDFRNH3, "DFRNH3", 3) \
141  X(SDFRNO2, "DFRNO2", 3) \
142  X(SCAJOE, "CAJOE", 3) \
143  X(SCOUNT, "SCOUNT", 3)
144 
145 #define X(utype, uname, umaintype) utype,
146 typedef enum SENSORS : size_t { SENSORS_TYPES } SENSORS; // backward compatibility
147 #undef X
148 
149 // MAIN SENSOR GROUPS TYPE
150 enum class SensorGroup { SENSOR_NONE,
151  SENSOR_PM,
152  SENSOR_CO2,
153  SENSOR_ENV,
154  SENSOR_RAD // CAJOE_GEIGER
155  };
156 // TEMPERATURE UNITS
157 enum class TEMPUNIT {
158  CELSIUS,
159  FAHRENHEIT,
160  KELVIN
161 };
162 
163 typedef void (*errorCbFn)(const char *msg);
164 typedef void (*voidCbFn)();
165 
170 class Sensors {
171  public:
173  struct sps_values val;
174 
176  bool devmode;
177 
179  int sample_time = 10;
180 
182  float toffset = 0.0;
183 
185  float altoffset = 0.0;
186 
188  float sealevel = 1013.25;
189 
191  float hpa = 0.0;
192 
194  SPS30 sps30;
195 
197  bool i2conly;
198 
199  /*****************************************
200  * I2C sensors:
201  ****************************************/
202 
204  AM232X am2320;
206  Adafruit_BME280 bme280;
208  Adafruit_BMP280 bmp280;
210  Adafruit_BME680 bme680;
212  AHTxx aht10;
214  Adafruit_SHT31 sht31;
215 
216  #ifdef DHT11_ENABLED
218  float dhthumi, dhttemp;
219  #endif
221  MHZ19 mhz19;
223  Adafruit_SCD30 scd30;
225  CM1106_UART *cm1106;
227  CM1106_sensor cm1106sensor;
229  CM1106_ABC abc;
231  SFE_PARTICLE_SENSOR pmGCJA5;
233  S8_UART *s8;
235  S8_sensor s8sensor;
237  SensirionI2CScd4x scd4x;
238  // SEN5x sensor PM
239  SensirionI2CSen5x sen5x;
241  PM1006 *pm1006;
243  DFRobot_GAS_I2C dfrCO;
245  DFRobot_GAS_I2C dfrNH3;
247  DFRobot_GAS_I2C dfrNO2;
249  GEIGER *rad;
250 
251 
252 
253  void init(u_int pms_type = 0, int pms_rx = PMS_RX, int pms_tx = PMS_TX);
254 
255  void loop();
256 
257  bool readAllSensors();
258 
259  bool isDataReady();
260 
261  void setSampleTime(int seconds);
262 
263  void setOnDataCallBack(voidCbFn cb);
264 
265  void setOnErrorCallBack(errorCbFn cb);
266 
267  void setTemperatureUnit(TEMPUNIT tunit);
268 
269  void setDebugMode(bool enable);
270 
271  bool isUARTSensorConfigured();
272 
274 
275  uint16_t getPM1();
276 
277  uint16_t getPM25();
278 
279  uint16_t getPM4();
280 
281  uint16_t getPM10();
282 
283  uint16_t getCO2();
284 
285  float getCO2humi();
286 
287  float getCO2temp();
288 
289  float getTemperature();
290 
291  float getHumidity();
292 
293  float getPressure();
294 
295  float getAltitude();
296 
297  float getGas();
298 
299  float getNH3();
300 
301  float getCO();
302 
303  float getNO2();
304 
305  void enableGeigerSensor(int gpio);
306 
307  uint32_t getGeigerCPM(void);
308 
309  float getGeigerMicroSievertHour(void);
310 
311  void setTempOffset(float offset);
312 
313  void setCO2AltitudeOffset(float altitude);
314 
315  void setSeaLevelPressure(float hpa);
316 
317  void setCO2RecalibrationFactor(int ppmValue);
318 
319  void detectI2COnly(bool enable);
320 
321  String getLibraryVersion();
322 
323  int16_t getLibraryRevision();
324 
325  bool isSensorRegistered(SENSORS sensor);
326 
327  uint8_t *getSensorsRegistered();
328 
329  uint8_t getSensorsRegisteredCount();
330 
331  String getSensorName(SENSORS sensor);
332 
333  SensorGroup getSensorGroup(SENSORS sensor);
334 
335  uint8_t getUnitsRegisteredCount();
336 
337  bool isUnitRegistered(UNIT unit);
338 
339  String getUnitName(UNIT unit);
340 
341  String getUnitSymbol(UNIT unit);
342 
343  UNIT getNextUnit();
344 
345  void resetUnitsRegister();
346 
347  void resetSensorsRegister();
348 
349  void resetNextUnit();
350 
351  void resetAllVariables();
352 
353  float getUnitValue(UNIT unit);
354 
355  void printUnitsRegistered(bool debug = false);
356 
357  void printSensorsRegistered(bool debug = false);
358 
359  private:
360 
361  #ifdef DHT11_ENABLED
363  uint32_t delayMS;
364  #endif
366  Stream *_serial;
368  errorCbFn _onErrorCb = nullptr;
370  voidCbFn _onDataCb = nullptr;
371 
372  int dev_uart_type = -1;
373 
374  bool dataReady;
375 
376  bool readAllComplete = false;
377 
378  uint8_t sensors_registered_count;
379 
380  uint8_t units_registered_count;
381 
382  uint8_t current_unit = 0;
383 
384  uint16_t pm1; // PM1
385  uint16_t pm25; // PM2.5
386  uint16_t pm4; // PM4
387  uint16_t pm10; // PM10
388 
389  float humi = 0.0; // % Relative humidity
390  float temp = 0.0; // Temperature (°C)
391  float pres = 0.0; // Pressure
392  float alt = 0.0;
393  float gas = 0.0; //
394 
395  // temperature unit (C,K,F)
396  TEMPUNIT temp_unit = TEMPUNIT::CELSIUS;
397 
398  uint16_t CO2Val; // CO2 in ppm
399  float CO2humi = 0.0; // humidity of CO2 sensor
400  float CO2temp = 0.0; // temperature of CO2 sensor
401 
402  float nh3; // Amonium in ppm
403  float co; // Carbon monoxide in ppm
404  float no2; // Nitrogen dioxide in ppm
405 
406  void am2320Init();
407  void am2320Read();
408 
409  void bme280Init();
410  void bme280Read();
411 
412  void bmp280Init();
413  void bmp280Read();
414 
415  void bme680Init();
416  void bme680Read();
417 
418  void aht10Init();
419  void aht10Read();
420 
421  void sht31Init();
422  void sht31Read();
423 
424  void CO2scd30Init();
425  void CO2scd30Read();
426  void setSCD30TempOffset(float offset);
427  void setSCD30AltitudeOffset(float offset);
428  void CO2correctionAlt();
429  float hpaCalculation(float altitude);
430 
431  void CO2scd4xInit();
432  void CO2scd4xRead();
433  void setSCD4xTempOffset(float offset);
434  void setSCD4xAltitudeOffset(float offset);
435 
436  void sen5xInit();
437  void sen5xRead();
438  void setsen5xTempOffset(float offset);
439 
440  void GCJA5Init();
441  void GCJA5Read();
442 
443  #ifdef DHT11_ENABLED
444  void dhtInit();
445  void dhtRead();
446  bool dhtIsReady(float *temperature, float *humidity);
447  #endif
448 
449  void DFRobotNH3Init();
450  void DFRobotNH3Read();
451  void DFRobotCOInit();
452  void DFRobotCORead();
453  void DFRobotNO2Init();
454  void DFRobotNO2Read();
455 
456  // UART sensors methods:
457 
458  bool sensorSerialInit(u_int pms_type, int rx, int tx);
459  bool pmSensorAutoDetect(u_int pms_type);
460  bool pmSensorRead();
461  bool pmGenericRead();
462  bool pmGCJA5Read();
463  bool pmSDS011Read();
464  bool pm1006Read();
465  bool CO2Mhz19Read();
466  bool CO2CM1106Read();
467  bool CO2Mhz19Init();
468  bool CO2CM1106Init();
469  bool senseAirS8Init();
470  bool senseAirS8Read();
471  bool PM1006Init();
472 
473  bool sps30I2CInit();
474  bool sps30UARTInit();
475  bool sps30Read();
476  bool sps30tests();
477  void sps30ErrToMess(char *mess, uint8_t r);
478  void sps30Errorloop(char *mess, uint8_t r);
479  void sps30DeviceInfo();
480 
481  void geigerRead();
482 
483  void onSensorError(const char *msg);
484 
485  void startI2C();
486 
487  void enableWire1();
488 
489  void disableWire1();
490 
491  bool serialInit(u_int pms_type, unsigned long speed_baud, int pms_rx, int pms_tx);
492 
493  String hwSerialRead(unsigned int lenght_buffer);
494 
495  void restart(); // restart serial (it isn't works sometimes)
496 
497  void DEBUG(const char *text, const char *textb = "");
498 
499  void printValues();
500 
501  void printHumTemp();
502 
503  void tempRegister(bool isCO2temp);
504 
505  void sensorRegister(SENSORS sensor);
506 
507  void sensorAnnounce(SENSORS sensor);
508 
509  void unitRegister(UNIT unit);
510 
511  uint8_t *getUnitsRegistered();
512 
513 // @todo use DEBUG_ESP_PORT ?
514 #ifdef WM_DEBUG_PORT
515  Stream &_debugPort = WM_DEBUG_PORT;
516 #else
517  Stream &_debugPort = Serial; // debug output stream ref
518 #endif
519 };
520 
521 #if !defined(NO_GLOBAL_INSTANCES) && !defined(NO_GLOBAL_SENSORSHANDLER)
522 extern Sensors sensors;
523 #endif
524 
525 #endif
526 
CanAirIO Sensors Manager main class.
Definition: Sensors.hpp:170
void printUnitsRegistered(bool debug=false)
print the sensor units names available
Definition: Sensors.cpp:666
void setTempOffset(float offset)
Set temperature offset for all temperature sensors.
Definition: Sensors.cpp:386
SensirionI2CScd4x scd4x
SCD4x object sensor.
Definition: Sensors.hpp:237
bool i2conly
only detect i2c sensors flag
Definition: Sensors.hpp:197
uint8_t getUnitsRegisteredCount()
get device sensors units detected count
Definition: Sensors.cpp:531
DFRobot_GAS_I2C dfrNH3
DFRobot gravity NH3 object sensor addr 0x7A.
Definition: Sensors.hpp:245
float getHumidity()
get humidity % value of environment sensor
Definition: Sensors.cpp:298
void loop()
Main sensors loop. All sensors are read here, please call it on main loop.
Definition: Sensors.cpp:34
void setCO2AltitudeOffset(float altitude)
set CO2 altitude offset (m)
Definition: Sensors.cpp:205
void resetAllVariables()
reset all library variables (generic sensors units)
Definition: Sensors.cpp:1846
String getUnitSymbol(UNIT unit)
get the sensor unit symbol
Definition: Sensors.cpp:550
float getPressure()
get Pressure value in hPa
Definition: Sensors.cpp:404
CM1106_UART * cm1106
CM1106 UART main object sensor.
Definition: Sensors.hpp:225
bool devmode
Debug mode for increase verbose.
Definition: Sensors.hpp:176
void resetUnitsRegister()
reset the sensor units registry.
Definition: Sensors.cpp:575
void setCO2RecalibrationFactor(int ppmValue)
set CO2 recalibration PPM value (400 to 2000)
Definition: Sensors.cpp:169
String getUnitName(UNIT unit)
get the sensor unit name
Definition: Sensors.cpp:540
AHTxx aht10
AHTXX sensors object.
Definition: Sensors.hpp:212
float altoffset
Altitud compensation variable.
Definition: Sensors.hpp:185
bool readAllSensors()
Read all sensors but use only one time or use loop() instead. All sensors are read here....
Definition: Sensors.cpp:61
float getNO2()
get NO2 value in ppm
Definition: Sensors.cpp:419
uint16_t getPM1()
get PM1.0 ug/m3 value
Definition: Sensors.cpp:268
uint32_t getGeigerCPM(void)
get Geiger count. Tics in the last 60secs
Definition: Sensors.cpp:1890
Adafruit_BMP280 bmp280
BMP280 object (Humidity, Pressure, Altitude and Temperature)
Definition: Sensors.hpp:208
struct sps_values val
SPS30 values. Only for Sensirion SPS30 sensor.
Definition: Sensors.hpp:173
float getGas()
get Gas resistance value of BMP680 sensor
Definition: Sensors.cpp:394
bool isDataReady()
get the sensor status
Definition: Sensors.cpp:263
Adafruit_BME280 bme280
BME280 object (Humidity, Pressure, Altitude and Temperature)
Definition: Sensors.hpp:206
void enableGeigerSensor(int gpio)
Enable Geiger sensor on specific pin.
Definition: Sensors.cpp:1876
void setOnDataCallBack(voidCbFn cb)
Get sensor data.
Definition: Sensors.cpp:242
float getCO()
get CO value in ppm
Definition: Sensors.cpp:414
float getNH3()
get NH3 value in ppm
Definition: Sensors.cpp:409
AM232X am2320
AM2320 object (Humidity and temperature)
Definition: Sensors.hpp:204
float getCO2temp()
get temperature value from the CO2 sensor device
Definition: Sensors.cpp:326
Adafruit_SCD30 scd30
SCD30 object sensor.
Definition: Sensors.hpp:223
float getGeigerMicroSievertHour(void)
get Geiger count in uSv/h units
Definition: Sensors.cpp:1899
float getUnitValue(UNIT unit)
get the sensor unit value (float)
Definition: Sensors.cpp:613
float getCO2humi()
get humidity % value of CO2 sensor device
Definition: Sensors.cpp:293
uint16_t getPM10()
get PM10 ug/m3 value
Definition: Sensors.cpp:283
void resetSensorsRegister()
reset the sensor registry.
Definition: Sensors.cpp:588
CM1106_sensor cm1106sensor
CM1106 UART main variable.
Definition: Sensors.hpp:227
Adafruit_SHT31 sht31
SHT31 object (Humidity and temperature)
Definition: Sensors.hpp:214
void setSeaLevelPressure(float hpa)
set the sea level pressure (hPa)
Definition: Sensors.cpp:227
SFE_PARTICLE_SENSOR pmGCJA5
Panasonic SN-GCJA5 object sensor.
Definition: Sensors.hpp:231
Adafruit_BME680 bme680
BME680 object (Humidity, Gas, IAQ, Pressure, Altitude and Temperature)
Definition: Sensors.hpp:210
DFRobot_GAS_I2C dfrNO2
DFRobot gravity NO2 object sensor add 0x7B.
Definition: Sensors.hpp:247
String getSensorName(SENSORS sensor)
get the sensor name
Definition: Sensors.cpp:479
bool isUARTSensorConfigured()
UART only: check if the UART sensor is registered.
Definition: Sensors.cpp:427
PM1006 * pm1006
IKEA Vindriktn object sensor.
Definition: Sensors.hpp:241
int getUARTDeviceTypeSelected()
UART only: get the UART sensor type. See SENSORS enum. Also getDeviceName()
Definition: Sensors.cpp:435
float sealevel
Sea level pressure (hPa)
Definition: Sensors.hpp:188
void init(u_int pms_type=0, int pms_rx=PMS_RX, int pms_tx=PMS_TX)
All sensors init.
Definition: Sensors.cpp:108
void setOnErrorCallBack(errorCbFn cb)
Optional callback for get the sensors errors.
Definition: Sensors.cpp:250
SensorGroup getSensorGroup(SENSORS sensor)
get the sensor group type
Definition: Sensors.cpp:492
bool isUnitRegistered(UNIT unit)
get the sensor unit status on the registry
Definition: Sensors.cpp:512
bool isSensorRegistered(SENSORS sensor)
Read and check the sensors status on initialization.
Definition: Sensors.cpp:467
float getTemperature()
get temperature value from environment sensor
Definition: Sensors.cpp:339
float hpa
Altitud hpa calculation.
Definition: Sensors.hpp:191
void setSampleTime(int seconds)
set loop time interval for each sensor sample
Definition: Sensors.cpp:153
void setDebugMode(bool enable)
Optional for increase the debug level.
Definition: Sensors.cpp:258
uint16_t getPM4()
get PM4 ug/m3 value
Definition: Sensors.cpp:278
float toffset
Temperature offset (for final temp output)
Definition: Sensors.hpp:182
CM1106_ABC abc
CM1106 UART calibration object.
Definition: Sensors.hpp:229
UNIT getNextUnit()
get the next sensor unit available
Definition: Sensors.cpp:558
S8_UART * s8
SenseAir S8 CO2 object sensor.
Definition: Sensors.hpp:233
DFRobot_GAS_I2C dfrCO
DFRobot gravity CO object sensor addr 0x78.
Definition: Sensors.hpp:243
MHZ19 mhz19
Mhz19 object sensor.
Definition: Sensors.hpp:221
int sample_time
Initial sample time for all sensors.
Definition: Sensors.hpp:179
uint8_t getSensorsRegisteredCount()
get device sensors detected count
Definition: Sensors.cpp:458
uint16_t getCO2()
get CO2 ppm value
Definition: Sensors.cpp:288
int16_t getLibraryRevision()
return the current revision code number
Definition: Sensors.cpp:453
uint16_t getPM25()
get PM2.5 ug/m3 value
Definition: Sensors.cpp:273
float getAltitude()
get Altitude value in meters
Definition: Sensors.cpp:399
S8_sensor s8sensor
SenseAir S8 CO2 object sensor.
Definition: Sensors.hpp:235
void detectI2COnly(bool enable)
Forced to enable I2C sensors only. Recommended to use only if you are using a I2C sensor and improve ...
Definition: Sensors.cpp:443
void resetNextUnit()
reset the next sensor unit counter.
Definition: Sensors.cpp:601
void setTemperatureUnit(TEMPUNIT tunit)
set the temperature type unit
Definition: Sensors.cpp:306
void printSensorsRegistered(bool debug=false)
print the sensor names detected
Definition: Sensors.cpp:681
GEIGER * rad
Geiger CAJOE object sensor.
Definition: Sensors.hpp:249
String getLibraryVersion()
returns the CanAirIO Sensorslib version
Definition: Sensors.cpp:448
uint8_t * getSensorsRegistered()
get the sensor registry for retrieve the sensor names
Definition: Sensors.cpp:502
SPS30 sps30
Sensirion library.
Definition: Sensors.hpp:194