@@ -52,18 +52,20 @@ Average<float> avg_a(20);
5252// I2C
5353
5454// MOTION
55- #define MPU6050 // MPU 6050 GY521 3axis gyro/accel
56- #define HMC5883L // NI Honeywell HMC5883L
57- #define MLX90393 // 3 axis magnetometer
55+ // #define MPU6050 // MPU 6050 GY521 3axis gyro/accel
56+ // #define HMC5883L // NI Honeywell HMC5883L
57+ // #define MLX90393 // 3 axis magnetometer
5858
5959// TEMP/HUMIDITY/GAS
60- #define SI7021
60+ // #define SI7021
6161
62- #define AHTX0
62+ // #define AHTX0
63+
64+ #define SGP30
6365
6466// Sensiron
65- #define USESHT31 // SHT31 Temp/Humidity
66- #define USESHT21 // SHT21 / HTU21D Temp/Humidity
67+ // #define USESHT31 // SHT31 Temp/Humidity
68+ // #define USESHT21 // SHT21 / HTU21D Temp/Humidity
6769
6870
6971// BOSCH
@@ -77,19 +79,19 @@ Up to 0.03hPa / 0.25m resolution
7779-40 to +85°C operational range, +-2°C temperature accuracy
7880This board/chip uses I2C 7-bit address 0x77.
7981*/
80- #define USEBMP280 // BMP280 Temp/Pressure/Altitude (upgrade for BMP085/BMP180/BMP183)
82+ // #define USEBMP280 // BMP280 Temp/Pressure/Altitude (upgrade for BMP085/BMP180/BMP183)
8183// #define USEBME280 // BME280 Humidity/Pressure/Altitude
8284// Pressure: 300...1100 hPa
8385
84- #define SDC4X // SDC40 Co2/Temp/Humidity
85- #define USECS811 // CCS811 Temp/CO2/VOC
86+ // #define SDC4X // SDC40 Co2/Temp/Humidity
87+ // #define USECS811 // CCS811 Temp/CO2/VOC
8688// #define USEGP2Y // Sharp Particle/Dust sensor GP2Y1010AU0F, GP2Y1014AU0F
87- #define PMSx
89+ // #define PMSx
8890
8991// LIGHT
90- #define APDS9960 // Proximity, Light, RGB, and Gesture Sensor
92+ // #define APDS9960 // Proximity, Light, RGB, and Gesture Sensor
9193
92- #define USEBH1750 // Light Sensor
94+ // #define USEBH1750 // Light Sensor
9395/*
9496 BH1750 has six different measurement modes. They are divided in two groups;
9597 continuous and one-time measurements. In continuous mode, sensor continuously
@@ -120,7 +122,7 @@ This board/chip uses I2C 7-bit address 0x77.
120122 BH1750_ONE_TIME_HIGH_RES_MODE_2
121123*/
122124
123- #define VEML6070 // UV Sensor
125+ // #define VEML6070 // UV Sensor
124126
125127
126128// #define TSL2561 // Luminosity/Lux/Light Address = 0x39 //Slave addr also 0x29 or 0x49
@@ -144,15 +146,15 @@ Interface: I2C
144146*/
145147
146148// SOUND
147- #define MAX9814 // MAX9814 Auto GC amplifier
148- #define MAX4466 // MAX4466 Adj GC amplifier
149+ // #define MAX9814 // MAX9814 Auto GC amplifier
150+ // #define MAX4466 // MAX4466 Adj GC amplifier
149151
150152// Energy
151- #define INA219 // INA219 current sense
153+ // #define INA219 // INA219 current sense
152154
153155// IO
154- #define MCP4725 // 12bit DAC with EEPROM
155- #define MCP3421 // 18bit delta-sigma ADC
156+ // #define MCP4725 // 12bit DAC with EEPROM
157+ // #define MCP3421 // 18bit delta-sigma ADC
156158// #define PCF8591 // PCF8591 io expander
157159
158160
@@ -1401,4 +1403,84 @@ float get_aht(uint8_t channel = 0){
14011403}
14021404#endif
14031405
1406+
1407+
1408+ #ifdef SGP30
1409+ #include " Adafruit_SGP30.h"
1410+ Adafruit_SGP30 sgp;
1411+
1412+ void init_sgp30 (){
1413+ bool ret = false ;
1414+ ret = sgp.begin ();
1415+ if (!ret){
1416+ Logger.println (" [ERROR] _sgp30 init FAILED" );
1417+ }
1418+ else Logger.println (" [ENV] _sgp30 is ACTIVE" );
1419+
1420+ // If you have a baseline measurement from before you can assign it to start, to 'self-calibrate'
1421+ // sgp.setIAQBaseline(0x8E68, 0x8F41); // Will vary for each sensor!
1422+ // return ret;
1423+
1424+ // If you have a temperature / humidity sensor, you can set the absolute humidity to enable the humditiy compensation for the air quality signals
1425+ // float temperature = 22.1; // [°C]
1426+ // float humidity = 45.2; // [%RH]
1427+ // sgp.setHumidity(getAbsoluteHumidity(temperature, humidity));
1428+
1429+ }
1430+
1431+ void print_sgp30 (){
1432+ Logger.print (" Found SGP30 serial #" );
1433+ Logger.print (sgp.serialnumber [0 ], HEX);
1434+ Logger.print (sgp.serialnumber [1 ], HEX);
1435+ Logger.println (sgp.serialnumber [2 ], HEX);
1436+
1437+ if (! sgp.IAQmeasure ()){
1438+ Logger.println (" Measurement failed" );
1439+ return ;
1440+ }
1441+ Logger.print (" TVOC " ); Logger.print (sgp.TVOC ); Logger.println (" ppb\t " );
1442+ Logger.print (" eCO2 " ); Logger.print (sgp.eCO2 ); Logger.println (" ppm" );
1443+
1444+ if (! sgp.IAQmeasureRaw ()){
1445+ Logger.println (" Raw Measurement failed" );
1446+ return ;
1447+ }
1448+ Logger.print (" Raw H2 " ); Logger.println (sgp.rawH2 );
1449+ Logger.print (" Raw Ethanol " ); Logger.println (sgp.rawEthanol );
1450+
1451+ uint16_t TVOC_base, eCO2_base;
1452+ if (! sgp.getIAQBaseline (&eCO2_base, &TVOC_base)){
1453+ Logger.println (" Failed to get baseline readings" );
1454+ return ;
1455+ }
1456+ Logger.print (" ****Baseline values: \n eCO2: 0x" ); Logger.println (eCO2_base, HEX);
1457+ Logger.print (" TVOC: 0x" ); Logger.println (TVOC_base, HEX);
1458+ }
1459+
1460+ float get_sgp30 (uint8_t channel = 0 ){
1461+ print_sgp30 ();
1462+ if (sgp.IAQmeasure ()){
1463+ if (channel == 0 ) return sgp.TVOC ;
1464+ if (channel == 1 ) return sgp.eCO2 ;
1465+
1466+ if (sgp.IAQmeasureRaw ()){
1467+ if (channel == 2 ) return sgp.rawH2 ;
1468+ if (channel == 3 ) return sgp.rawEthanol ;
1469+ }
1470+ }
1471+ // else "error"
1472+ }
1473+ #endif
1474+
1475+ /* return absolute humidity [mg/m^3] with approximation formula
1476+ * @param temperature [°C]
1477+ * @param humidity [%RH]
1478+ */
1479+ uint32_t getAbsoluteHumidity (float temperature, float humidity){
1480+ // approximation formula from Sensirion SGP30 Driver Integration chapter 3.15
1481+ const float absoluteHumidity = 216 .7f * ((humidity / 100 .0f ) * 6 .112f * exp ((17 .62f * temperature) / (243 .12f + temperature)) / (273 .15f + temperature)); // [g/m^3]
1482+ const uint32_t absoluteHumidityScaled = static_cast <uint32_t >(1000 .0f * absoluteHumidity); // [mg/m^3]
1483+ return absoluteHumidityScaled;
1484+ }
1485+
14041486#endif
0 commit comments