# Homeyduino BME 680 BSEC library

**URL:** <https://community.homey.app/t/homeyduino-bme-680-bsec-library/25078>\
**Category:** Devices\
**Created:** [January 27, 2020, 1:48pm UTC](https://community.homey.app/t/homeyduino-bme-680-bsec-library/25078 "2020-01-27T13:48:08Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![rindler](https://sea1.discourse-cdn.com/flex025/user_avatar/community.homey.app/rindler/32/5501_2.png) [@rindler](https://community.homey.app/u/rindler)\
**Post date:** [January 27, 2020, 1:48pm UTC](https://community.homey.app/t/homeyduino-bme-680-bsec-library/25078/1 "2020-01-27T13:48:08Z")

</div>

Okey, this is a bit complicated, but still. If you want to build an indoor air quality sensor and measure VOC, the BME680 sensor ([Gas Sensor BME680 | Bosch Sensortec](https://www.bosch-sensortec.com/products/environmental-sensors/gas-sensors-bme680/)) is probably the way to go. However the Bosch BSEC library which converts the gas resistance value to an IAQ value is a bit complicated. I am really a beginner coding Arduino code but still managed it, so here’s the guide to it, if you want to do it yourself. See also this forum post if you want to get inspired how to do it with an enclosure and TFT display [HomeyDuino CO2 sensor - #8 by Lars\_Machiels](https://community.homey.app/t/homeyduino-co2-sensor/20410/8).

The output values from the sensor is temperature, pressure, humidity, IAQ, staticIAQ, and two calculated values breathVOC and eCO2 in ppm, which should work as human detectors. However I haven’t managed to use custom capabilities in Homeyduino, so in my code I used `measure_rain` for sIAQ and `measure_CO` for breathVOC, hehe. However, since both these values are calculated it is probably meaningless to display all those values.

> - Static IAQ:
> 
> - bVOCeq estimate:
> 
> - CO2eq estimate:

So before you start, I would recommend to connect the BME680 sensor to the Arduino and run some I2C scanner code, so you are sure it is connected to `0x76` for the `BME680_I2C_ADDR_PRIMARY` setting or `0x77` for `BME680_I2C_ADDR_SECONDARY` otherwise you just end up with error messages in the Serial monitor.

Then you have to change the code in` platform.txt` in C:\Users[username]\AppData\Local\Arduino15\packages\esp8266\hardware\2.6.2 according to this [GitHub - boschsensortec/BSEC-Arduino-library: Arduino library for BSEC to simplify integration into compatible platforms. To report issues, go to https://community.bosch-sensortec.com/t5/Bosch-Sensortec-Community/ct-p/bst\_community](https://github.com/BoschSensortec/BSEC-Arduino-library#esp8266-community-forums-esp8266-core) (you have to change this back when you are done with this project/sensor).

And in `eagle.app.v6.common.ld.h` typically found in `{YourESP8266PPackageDirectory}\tools\sdk\ld` (same root folder) according to this [GitHub - boschsensortec/BSEC-Arduino-library: Arduino library for BSEC to simplify integration into compatible platforms. To report issues, go to https://community.bosch-sensortec.com/t5/Bosch-Sensortec-Community/ct-p/bst\_community](https://github.com/BoschSensortec/BSEC-Arduino-library#esp8266---modify-the-linker-script-header)

Then add this library in Arduino [https://github.com/BoschSensortec/BSEC-Arduino-library/archive/master.zip](https://github.com/BoschSensortec/BSEC-Arduino-library/archive/master.zip)

And upload this code to your esp8266:

```
#include "bsec.h"
#include <Homey.h>
#include <ESP8266WiFi.h>
#include <WiFiClient.h>

// Helper functions declarations
void checkIaqSensorStatus(void);
void errLeds(void);

// Create an object of the class Bsec
Bsec iaqSensor;

String output;

// Entry point for the example

unsigned long previousMillis = 0;
const unsigned long interval = 300000; //Interval in milliseconds

void wifi() {
  if (WiFi.status() != WL_CONNECTED) {
    WiFi.begin("SSID", "password");
    uint8_t timeout = 30;
    while (WiFi.status() != WL_CONNECTED) {
      delay(500);
      Serial.print(".");
      if (timeout<1) break;
    }
    if (WiFi.status() == WL_CONNECTED) {
      //Print IP address
      Serial.print("Connected to WiFi! (");
      Serial.print(WiFi.localIP());
      Serial.println(")");
    }
  }
}

void setup(void)
{
  Serial.begin(115200);
  Wire.begin();
  Homey.begin("bme680nodemcu");
  Homey.setClass("sensor");
  Homey.addCapability("measure_temperature");
  Homey.addCapability("measure_humidity");
  Homey.addCapability("measure_pressure");
  Homey.addCapability("measure_co");
  Homey.addCapability("measure_co2");
  Homey.addCapability("measure_rain");

  iaqSensor.begin(BME680_I2C_ADDR_SECONDARY, 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();

  // 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);
}

// Function that is looped forever
void loop(void)
{
  wifi();
  Homey.loop();
  unsigned long currentMillis = millis();
  if(currentMillis - previousMillis > interval) {
    previousMillis = currentMillis;
    updateSensor();
    }
    

  
  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();
  }
 
}

void updateSensor() {  
  Homey.setCapabilityValue("measure_temperature", (float) iaqSensor.temperature );
  Homey.setCapabilityValue("measure_pressure", (float) iaqSensor.pressure/100 );
  Homey.setCapabilityValue("measure_humidity", (float) iaqSensor.humidity );
  Homey.setCapabilityValue("measure_co2", (int) iaqSensor.co2Equivalent );
  Homey.setCapabilityValue("measure_rain", (int) iaqSensor.staticIaq ); 
  Homey.setCapabilityValue("measure_co", (float) iaqSensor.breathVocEquivalent );
  Serial.println("Homey values sent");
}

// 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);
}

```
