#include #include "bsec.h" #define USE_DISPLAY #ifdef USE_DISPLAY #include #ifdef U8X8_HAVE_HW_SPI #include #endif #ifdef U8X8_HAVE_HW_I2C #include #endif #include #define LED_PIN 18 #define LED_COUNT 8 Adafruit_NeoPixel strip(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); //U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 15, /* data=*/ 4, /* reset=*/ 16); U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2(U8G2_R0, /* clock=*/ 15, /* data=*/ 4, /* reset=*/ 16); #endif int DisplayUpdateLoopInterval = 1000; uint32_t DisplayUpdateLoopMillis = millis() - DisplayUpdateLoopInterval; int NeoPixelUpdateLoopInterval = 1000; uint32_t NeoPixelUpdateLoopMillis = millis() - NeoPixelUpdateLoopInterval; // Create an object of the class Bsec Bsec iaqSensor; String output; // Entry point for the example void setup(void) { Serial.begin(115200); Wire.begin(); iaqSensor.begin(BME680_I2C_ADDR_PRIMARY, Wire); output = "\nBSEC library version " + String(iaqSensor.version.major) + "." + String(iaqSensor.version.minor) + "." + String(iaqSensor.version.major_bugfix) + "." + String(iaqSensor.version.minor_bugfix); Serial.println(output); checkIaqSensorStatus(); bsec_virtual_sensor_t sensorList[10] = { BSEC_OUTPUT_RAW_TEMPERATURE, BSEC_OUTPUT_RAW_PRESSURE, BSEC_OUTPUT_RAW_HUMIDITY, BSEC_OUTPUT_RAW_GAS, BSEC_OUTPUT_IAQ, BSEC_OUTPUT_STATIC_IAQ, BSEC_OUTPUT_CO2_EQUIVALENT, BSEC_OUTPUT_BREATH_VOC_EQUIVALENT, BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_TEMPERATURE, BSEC_OUTPUT_SENSOR_HEAT_COMPENSATED_HUMIDITY, }; iaqSensor.updateSubscription(sensorList, 10, BSEC_SAMPLE_RATE_LP); checkIaqSensorStatus(); #ifdef USE_DISPLAY setupDisplay(); #endif // Print the header output = "Timestamp [ms], raw temperature [°C], pressure [hPa], raw relative humidity [%], gas [Ohm], IAQ, IAQ accuracy, temperature [°C], relative humidity [%], Static IAQ, CO2 equivalent, breath VOC equivalent"; Serial.println(output); strip.begin(); strip.show(); strip.setBrightness(50); } // Function that is looped forever void loop(void) { unsigned long time_trigger = millis(); if (iaqSensor.run()) { // If new data is available output = String(time_trigger); output += ", " + String(iaqSensor.rawTemperature); output += ", " + String(iaqSensor.pressure); output += ", " + String(iaqSensor.rawHumidity); output += ", " + String(iaqSensor.gasResistance); output += ", " + String(iaqSensor.iaq); output += ", " + String(iaqSensor.iaqAccuracy); output += ", " + String(iaqSensor.temperature); output += ", " + String(iaqSensor.humidity); output += ", " + String(iaqSensor.staticIaq); output += ", " + String(iaqSensor.co2Equivalent); output += ", " + String(iaqSensor.breathVocEquivalent); Serial.println(output); } else { checkIaqSensorStatus(); } #ifdef USE_DISPLAY updateDisplay(); #endif updateNeoPixel(); } // Helper function definitions void checkIaqSensorStatus(void) { if (iaqSensor.status != BSEC_OK) { if (iaqSensor.status < BSEC_OK) { output = "BSEC error code : " + String(iaqSensor.status); Serial.println(output); for (;;) errLeds(); /* Halt in case of failure */ } else { output = "BSEC warning code : " + String(iaqSensor.status); Serial.println(output); } } if (iaqSensor.bme680Status != BME680_OK) { if (iaqSensor.bme680Status < BME680_OK) { output = "BME680 error code : " + String(iaqSensor.bme680Status); Serial.println(output); for (;;) errLeds(); /* Halt in case of failure */ } else { output = "BME680 warning code : " + String(iaqSensor.bme680Status); Serial.println(output); } } } void errLeds(void) { pinMode(LED_BUILTIN, OUTPUT); digitalWrite(LED_BUILTIN, HIGH); delay(100); digitalWrite(LED_BUILTIN, LOW); delay(100); } #ifdef USE_DISPLAY void setupDisplay() { u8g2.begin(); u8g2.setFont(u8g2_font_courB08_tr); // choose a suitable font updateDisplay(); } void updateDisplay() { if(millis() - DisplayUpdateLoopMillis > DisplayUpdateLoopInterval) { DisplayUpdateLoopMillis = millis(); char displayText[256]; u8g2.clearBuffer(); char tempString[10]; dtostrf(iaqSensor.temperature, 4, 2, tempString); sprintf(displayText, "Temp: %s", tempString); u8g2.drawStr(0,10,displayText); char humidString[10]; dtostrf(iaqSensor.humidity, 4, 2, humidString); sprintf(displayText, "Humidity: %s", humidString); u8g2.drawStr(0,20,displayText); char co2String[10]; dtostrf(iaqSensor.co2Equivalent, 4, 2, co2String); sprintf(displayText, "CO2-Equivalent: %s", ""); u8g2.drawStr(0,30,displayText); sprintf(displayText, "%20s", co2String); u8g2.drawStr(0,40,displayText); u8g2.sendBuffer(); } } #endif void updateNeoPixel(){ if(millis() - NeoPixelUpdateLoopMillis > NeoPixelUpdateLoopInterval) { NeoPixelUpdateLoopMillis = millis(); double warningValue = 800; double criticalValue = 1500; double steps = 2000/strip.numPixels(); float co2 = iaqSensor.co2Equivalent; for(int i=0; i= steps*(i+1)) { if(co2 >= criticalValue) strip.setPixelColor(i, 255, 0, 0); else if(co2 >= warningValue) strip.setPixelColor(i, 255, 165, 0); else if(co2 < warningValue) strip.setPixelColor(i, 0, 255, 0); } else { strip.setPixelColor(i, 0, 0, 0); } strip.show(); } } }