BME 680 sensor

Moderators: grovkillen, TD-er, Stuntteam

Post Reply
Message
Author
Barb232
Normal user
Posts: 40
Joined: 12 Mar 2016, 16:40
Location: Earth
Contact:

BME 680 sensor

#1 Post by Barb232 » 22 Apr 2018, 16:38

Does anybody know when P119 bme680 sensor moves from playground to live?

The BME 680 sensor measures Temperature, Humidity, Pressure and VOC (air quality).
And is available on a board from aliexpress for a good price: http://s.click.aliexpress.com/e/6UZzVJY

Further Information
BME 680 on a raspi: https://github.com/alexh-name/bsec_bme680_linux
BME 680 with visual outputs: https://github.com/alexh-name/bme680_outputs

LG
/robin

TD-er
Core team member
Posts: 2620
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: BME 680 sensor

#2 Post by TD-er » 22 Apr 2018, 20:04

Hmm, that's a decent price.
I've not seen them before on the Ali/Banggood. (just ordered one myself)

Is the reliability of this playground implementation regarding temperature reading OK?
The BMP/BME280 always read too high temperatures, even when mounted away from the ESP and sending the sensor to sleep as soon as possible to prevent self-heating.

Barb232
Normal user
Posts: 40
Joined: 12 Mar 2016, 16:40
Location: Earth
Contact:

Re: BME 680 sensor

#3 Post by Barb232 » 22 Apr 2018, 20:12

Hi,
Yes, the price is okay, and the delivery was fast.

I just coded a quick and dirty version for the esp 8266 and MQTT this afternoon myself.
I am watching the values of the sensor, using fhem and make a chart.
I think your are right with the higher temperatures, 1 degree higher, pressure and humidity looks ok. gas I have to check longtime.
Maybe I will publish the code in my blog https://blog.moneybag.de and compare this with other sensors.
Lets wait and see ...

Screenshot 2018-04-22 20.07.36.JPG
Screenshot 2018-04-22 20.07.36.JPG (89.73 KiB) Viewed 10072 times

TD-er
Core team member
Posts: 2620
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: BME 680 sensor

#4 Post by TD-er » 22 Apr 2018, 20:20

How can you measure the altitude? Do you have some stationary reference?

Barb232
Normal user
Posts: 40
Joined: 12 Mar 2016, 16:40
Location: Earth
Contact:

Re: BME 680 sensor

#5 Post by Barb232 » 22 Apr 2018, 20:23

just taken from the adafruit source (i said quick and dirty :-)), altitude is wrong.
I am just interested in gas, the other data arent so much interesting for me.

fazambuja
Normal user
Posts: 13
Joined: 17 Apr 2018, 19:05

Re: BME 680 sensor

#6 Post by fazambuja » 23 Apr 2018, 15:55

Bosch updated the sensor algorithms not so long ago. It always report higher temperature.
All the playground plugins are broken now, so there is no way to test on mega :(

fazambuja
Normal user
Posts: 13
Joined: 17 Apr 2018, 19:05

Re: BME 680 sensor

#7 Post by fazambuja » 24 Apr 2018, 23:12

I've removed the deprecated string variable from the current playground plug-in. This way it works on the latest mega.

Code: Select all

//#######################################################################################################
//#################### Plugin 119 BME680 I2C Temp/Hum/Barometric/Pressure/Gas Resistence Sensor  ########
//#######################################################################################################

/*******************************************************************************
 * Copyright 2017
 * Written by Rossen Tchobanski (rosko@rosko.net)
 * BSD license, all text above must be included in any redistribution
 *
 * Release notes:
   Adafruit_BME680 Library v1.0.5 required (https://github.com/adafruit/Adafruit_BME680/tree/1.0.5)
/******************************************************************************/


#ifdef PLUGIN_BUILD_DEV
//#ifdef PLUGIN_BUILD_TESTING

#include <Wire.h>
#include <SPI.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME680.h>



#define PLUGIN_119
#define PLUGIN_ID_119         119
#define PLUGIN_NAME_119       "Environment - BME680"
#define PLUGIN_VALUENAME1_119 "Temperature"
#define PLUGIN_VALUENAME2_119 "Humidity"
#define PLUGIN_VALUENAME3_119 "Pressure"
#define PLUGIN_VALUENAME4_119 "Gas"
#define PLUGIN_VALUENAME5_119 "AIQ"

#define BME_SCK 13
#define BME_MISO 12
#define BME_MOSI 11
#define BME_CS 10

#define SEALEVELPRESSURE_HPA (1013.25)

Adafruit_BME680 bme; // I2C
//Adafruit_BME680 bme(BME_CS); // hardware SPI
//Adafruit_BME680 bme(BME_CS, BME_MOSI, BME_MISO,  BME_SCK);


boolean Plugin_119_init = false;

boolean Plugin_119(byte function, struct EventStruct *event, String& string)
{
  boolean success = false;

  switch (function)
  {
    case PLUGIN_DEVICE_ADD:
      {
        Device[++deviceCount].Number = PLUGIN_ID_119;
        Device[deviceCount].Type = DEVICE_TYPE_I2C;
        Device[deviceCount].VType = SENSOR_TYPE_QUAD;
        Device[deviceCount].Ports = 0;
        Device[deviceCount].PullUpOption = false;
        Device[deviceCount].InverseLogicOption = false;
        Device[deviceCount].FormulaOption = true;
        Device[deviceCount].ValueCount = 4;
        Device[deviceCount].SendDataOption = true;
        Device[deviceCount].TimerOption = true;
        Device[deviceCount].GlobalSyncOption = true;
        break;
      }

    case PLUGIN_GET_DEVICENAME:
      {
        string = F(PLUGIN_NAME_119);
        break;
      }

    case PLUGIN_GET_DEVICEVALUENAMES:
      {
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_119));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_119));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_119));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[3], PSTR(PLUGIN_VALUENAME4_119));
        break;
      }

    case PLUGIN_WEBFORM_LOAD:
      {
        byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
        /*
        String options[2];
        options[0] = F("0x76 - default settings (SDO Low)");
        options[1] = F("0x77 - alternate settings (SDO HIGH)");
        */
        int optionValues[2] = { 0x77, 0x76 };
        addFormSelectorI2C(F("plugin_119_BME680_i2c"), 2, optionValues, choice);
        addFormNote(F("SDO Low=0x76, High=0x77"));

        addFormNumericBox(F("Altitude"), F("plugin_119_BME680_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
        addUnit(F("m"));

        success = true;
        break;
      }

    case PLUGIN_WEBFORM_SAVE:
      {
        Settings.TaskDevicePluginConfig[event->TaskIndex][0] = getFormItemInt(F("plugin_119_BME680_i2c"));
        Settings.TaskDevicePluginConfig[event->TaskIndex][1] = getFormItemInt(F("plugin_119_BME680_elev"));
        success = true;
        break;
      }

    case PLUGIN_READ:
      {



        if (!Plugin_119_init)
        {
            addLog(LOG_LEVEL_INFO, F("BME680  : init"));

            Plugin_119_init = bme.begin();

            // Set up oversampling and filter initialization
            bme.setTemperatureOversampling(BME680_OS_8X);
            bme.setHumidityOversampling(BME680_OS_2X);
            bme.setPressureOversampling(BME680_OS_4X);
            bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
            bme.setGasHeater(320, 150); // 320*C for 150 ms

            success = true;
            break;
        }

        if (Plugin_119_init)
        {
            if (! bme.performReading()) {
              addLog(LOG_LEVEL_ERROR, F("BME680 : Failed to perform reading!"));
              success = false;
              break;
            }

            UserVar[event->BaseVarIndex + 0] = bme.temperature;
            UserVar[event->BaseVarIndex + 1] = bme.humidity;
            UserVar[event->BaseVarIndex + 2] = bme.pressure / 100.0;
            UserVar[event->BaseVarIndex + 3] = bme.gas_resistance / 1000.0;
            

        }

        success = true;
        break;
      }

  }
  return success;
}

#endif

Barb232
Normal user
Posts: 40
Joined: 12 Mar 2016, 16:40
Location: Earth
Contact:

Re: BME 680 sensor

#8 Post by Barb232 » 25 Apr 2018, 08:11

Hello,

i see, that u used also the adafruit library, I used version 1.05

i wrote a short blog post for testing.

https://blog.moneybag.de/fhem-air-quali ... -getestet/

With the readings of the temperature and voc i am not satisfied at the moment.

Robin

fazambuja
Normal user
Posts: 13
Joined: 17 Apr 2018, 19:05

Re: BME 680 sensor

#9 Post by fazambuja » 25 Apr 2018, 18:15

Are you getting AIQ readings? The only libraries that I found (including the Bosch) required to change a library for compiling.
This makes harder to get supported by espeasy.

Barb232
Normal user
Posts: 40
Joined: 12 Mar 2016, 16:40
Location: Earth
Contact:

Re: BME 680 sensor

#10 Post by Barb232 » 25 Apr 2018, 18:53

Hello,

i get the same readings as in your source.
but i am doing a longer test at the moment and i compare the plots with a co2 sensor and voc sensor

https://blog.moneybag.de/luftqualitaets ... gsbericht/
https://blog.moneybag.de/fhem-luftquali ... asy-wemos/

robin

fazambuja
Normal user
Posts: 13
Joined: 17 Apr 2018, 19:05

Re: BME 680 sensor

#11 Post by fazambuja » 30 Apr 2018, 07:59

I’ve been using the Bosh BSEC Arduino library and its way more sofisticated than the ones usually used on the esp. It kind of self calibrates to get more accurate. It also gives an AIQ score. But uses a precompiled library that will make really hard to get supported...

Barb232
Normal user
Posts: 40
Joined: 12 Mar 2016, 16:40
Location: Earth
Contact:

Re: BME 680 sensor

#12 Post by Barb232 » 30 Apr 2018, 08:25

I compared the plots against BME680, Voltcraft Raumluftsensor and MH-Z19 together an I am not really satisfied with the results of the bme680.
Maybe a software bug, i used the adafruit lib 1.05. The 3 sensors laying next to each other. i am waiting for a espeasy plugin. :-)

references:
https://blog.moneybag.de/iobroker-usb-r ... bertragen/
https://blog.moneybag.de/fhem-air-quali ... -getestet/

Screenshot 2018-04-30 08.21.44.JPG
Screenshot 2018-04-30 08.21.44.JPG (139.34 KiB) Viewed 9861 times

TD-er
Core team member
Posts: 2620
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: BME 680 sensor

#13 Post by TD-er » 30 Apr 2018, 22:39

A VOC sensor does not measure CO2 concentration.
It measures totally different gasses and computes some value which somewhat relates to a CO2 concentration, when used in a room full of people.
So it is a cheap alternative to determine when to switch on a ventilator or tell you to open a window.

The reported value looks like the inverted curve of the CO2 value. So it can be used to determine ventilation needs :)

Barb232
Normal user
Posts: 40
Joined: 12 Mar 2016, 16:40
Location: Earth
Contact:

Re: BME 680 sensor

#14 Post by Barb232 » 30 Apr 2018, 22:45

You are right. A few years ago i asked the support and became the same answer:
„Der Sensor ist nicht selektiv und erfaßt nur einen Summenparameter aller vorhandenen reduzierenden Gase. Wir messen eine Widerstandsänderung und rechnen diese mittels Algorithmus in ppm CO2.“
And yes, the plot shows the graphs upside down, but i am still testing.

pppp33
Normal user
Posts: 67
Joined: 25 Oct 2015, 17:53

Re: BME 680 sensor

#15 Post by pppp33 » 14 Jun 2018, 19:20

Hello bme680 users,
I bought aliexpress version (purple, about 15$), loadef P119, compiled and run.
In my test set (DHT22, DS18B20, BME680) Temperature and pressure are quite Ok: difference is +/- 0.2-0.5°C

But Humidity measured by BME680 is about +10 points higher than DHT22 value: 71.4% vs. 61.5%
Did someone get same results and find some reason and solution ?

About VOC, It's 51.5
Is it reasonable ?

Regards
Paolo

TD-er
Core team member
Posts: 2620
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: BME 680 sensor

#16 Post by TD-er » 14 Jun 2018, 19:49

pppp33 wrote:
14 Jun 2018, 19:20
[...]
In my test set (DHT22, DS18B20, BME680) Temperature and pressure are quite Ok: difference is +/- 0.2-0.5°C

But Humidity measured by BME680 is about +10 points higher than DHT22 value: 71.4% vs. 61.5%
Did someone get same results and find some reason and solution ?
[...]
Similar chips from Bosch, the BME280 and BMP280 were always having a temperature output value that was too high and thus a humidity which is too low. (both are related a you may know).
Last week I changed the code for BME280 in the Mega branch to read all I2C registers in 1 run.
This resulted in more accurate results for that sensor.
I have spoken to someone from Bosch and they confirmed these sensors could be updating internal registers between I2C reads and as such it is best to read them all at once.
Maybe the BME680 has some similar issues?
Please have a look at the BME280 source in the Mega branch to see how to read them all at once.
https://github.com/letscontrolit/ESPEas ... #L496-L531

fluppie
Normal user
Posts: 88
Joined: 09 Oct 2015, 13:23

Re: BME 680 sensor

#17 Post by fluppie » 15 Jun 2018, 12:31

Here you can see the logging of 3 pieces BME680, all within 5cmof eachother: https://emoncms.org/Edegem/bme680voc I'm using the one from Pimoroni: https://shop.pimoroni.com/products/bme680-breakout
I'm not to convinced about the VOC accuracy, the trend is the same but I think the absolute value in kOhms says nothing. I received my Senseair S8 CO2 sensor from @Grovkillen his webshop. Will solder that one soon and put it in the same spot.
The code in the plugin playground is a bit dirty as the I2C address selection is not working, had to hardcode this myself.

TD-er
Core team member
Posts: 2620
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: BME 680 sensor

#18 Post by TD-er » 15 Jun 2018, 20:47

Those S8 sensors from Senseair (and also the MHZ19) are NDIR sensors.
They read the amount of IR absorption, so make sure not to position them in direct sunlight.

pppp33
Normal user
Posts: 67
Joined: 25 Oct 2015, 17:53

Re: BME 680 sensor

#19 Post by pppp33 » 15 Jun 2018, 21:22

Hello, thanx to all of you for info & support.....
Actually, the only surely wrong value is humi....
Temp & Baro are ok.
VOC is quite difficult to evaluate....
Am I the only that gets humi wrong only ?
If yes, it could be my sensor broken..... :oops:
Regards
Paolo

TD-er
Core team member
Posts: 2620
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: BME 680 sensor

#20 Post by TD-er » 15 Jun 2018, 23:06

Make sure you apply enough ventilation over the sensor itself.
So you could test it open in the air and make sure it doesn't heat up.

pppp33
Normal user
Posts: 67
Joined: 25 Oct 2015, 17:53

Re: BME 680 sensor

#21 Post by pppp33 » 16 Jun 2018, 14:22

Hello,
Latest update:
if you reduce sample time (I used 120 sec.), you get slightly better results, especially in terms of VOC: it passed from about 45 to 25 (same conditions).
Humidity is about +8 points (66% instead of 58%)....

Regards
Paolo

whatsupskip
Normal user
Posts: 104
Joined: 28 Feb 2018, 07:40

Re: BME 680 sensor

#22 Post by whatsupskip » 05 Nov 2019, 05:48

Is there any up date on this?

I thought I saw the BME680 in one of the test versions of Mega. It doesn't appear to be in mega-20191003 version.

TD-er
Core team member
Posts: 2620
Joined: 01 Sep 2017, 22:13
Location: the Netherlands
Contact:

Re: BME 680 sensor

#23 Post by TD-er » 05 Nov 2019, 09:02

It is in P119, which is part of the playground.
I have no idea if it will compile with the current ESPeasy core code.

whatsupskip
Normal user
Posts: 104
Joined: 28 Feb 2018, 07:40

Re: BME 680 sensor

#24 Post by whatsupskip » 05 Nov 2019, 21:25

Thanks

seb82
Normal user
Posts: 51
Joined: 05 Sep 2018, 10:56

Re: BME 680 sensor

#25 Post by seb82 » 02 May 2020, 16:51

I tried to get this sensor working. Here is some feedback :
- I started with Adafruit library, but I was getting very weird results and spikes in temperature.
- Then I switched to SV-Zanshin library. This one was apparently better.
- For temperature measurement, it seems to overheat by 1-1.5 degree. If I disable the gas resistance measurement (gas heater off) and do some power off/on of the sensor with rules, I manage to get a +0.3 overheating only (compared to two other sensors), and a very stable and reproductible value. For reference, I am using this board, where the sensor is somehow a little bit isolated.
- Humidity is definitely lower than other sensors I have by 10-15%.
- Pressure after altitude correction seems good.
- For gas resistance, I can hardly make any sense of it. It seems that turning off the gas heater affects the measure even if I put it back some time before the measure. And turning off/on the sensor power supply (to limit overheating for temperature measurement) makes it worse. It probably needs some more attention on longuer periods.
- I discovered there is a BME680 driver made directly by Bosch. Maybe this could be the way to go for better results.
- In addition, Bosch is supplying an arduino library. This one uses the previous driver and applies some "higher-level signal processing and fusion for the BME680". Code it not open, and it requires some changes in Arduino IDE to compile. It seems to be well documented though.

For those interested, here is the code I used. It is base on the BME280 code, with the use of SV-Zanshin library. It does measure in two times : first temperature/humidity/pressure, and then gas resistance. It is probably not the best way to do it (especially at startup, it send zeros), but so far this is the best results I got.

Any feedback or inputs are welcomed.

Code: Select all

//#ifdef USES_P120

//#######################################################################################################
//############# Plugin 120 BME680 I2C Temp/Hum/Barometric/Pressure/Gas Resistence Sensor ################
//#######################################################################################################

#include "_Plugin_Helper.h"

#include <map>

#include "Zanshin_BME680.h" // Include the BME680 Sensor library

#define PLUGIN_120
#define PLUGIN_ID_120        120
#define PLUGIN_NAME_120       "Environment - BME680"
#define PLUGIN_VALUENAME1_120 "Temperature"
#define PLUGIN_VALUENAME2_120 "Humidity"
#define PLUGIN_VALUENAME3_120 "Pressure"
#define PLUGIN_VALUENAME4_120 "Gas Resistance"

BME680_Class P120_BME680; 	// Create an instance of the BME680

bool P120_gas_cycle = 0;	// Measure Gas Resistance alternatively with temp/hum/press

enum P120_BMx_state {
  P120_BMx_Uninitialized = 0,
  P120_BMx_Initialized,
};

struct P120_sensordata {
  P120_sensordata() :
    last_hum_val(0.0),
    last_press_val(0.0),
    last_temp_val(0.0),
    last_dew_temp_val(0.0),
	last_gas_resistance_val(0.0),
    last_measurement(0),
    //i2cAddress(0),
    state(P120_BMx_Uninitialized) {}
    String getDeviceName() const {
	  return "BME680";
    }
    bool initialized() const {
      return state != P120_BMx_Uninitialized;
    }
  float last_hum_val;
  float last_press_val;
  float last_temp_val;
  float last_dew_temp_val;
  float last_gas_resistance_val;
  unsigned long last_measurement;
  //uint8_t i2cAddress;
  P120_BMx_state state;
};

std::map<uint8_t, P120_sensordata> P120_sensors;

int Plugin_120_i2c_addresses[2] = { 0x76, 0x77 };

uint8_t Plugin_120_i2c_addr(struct EventStruct *event) {
  uint8_t i2cAddress = static_cast<uint8_t>(PCONFIG(0));
  if (i2cAddress != Plugin_120_i2c_addresses[0] && i2cAddress != Plugin_120_i2c_addresses[1]) {
    // Set to default address
    i2cAddress = Plugin_120_i2c_addresses[0];
  }
  if (P120_sensors.count(i2cAddress) == 0) {
    P120_sensors[i2cAddress] = P120_sensordata();
  }
  return i2cAddress;
}

//boolean Plugin_120_init = false;

boolean Plugin_120(byte function, struct EventStruct *event, String& string)
{
  boolean success = false;

  switch (function)
  {
    case PLUGIN_DEVICE_ADD:
      {
        Device[++deviceCount].Number = PLUGIN_ID_120;
        Device[deviceCount].Type = DEVICE_TYPE_I2C;
        Device[deviceCount].VType = SENSOR_TYPE_QUAD;
        Device[deviceCount].Ports = 0;
        Device[deviceCount].PullUpOption = false;
        Device[deviceCount].InverseLogicOption = false;
        Device[deviceCount].FormulaOption = true;
        Device[deviceCount].ValueCount = 4;
        Device[deviceCount].SendDataOption = true;
        Device[deviceCount].TimerOption = true;
		Device[deviceCount].TimerOptional = true;
        Device[deviceCount].GlobalSyncOption = true;
        break;
      }

    case PLUGIN_GET_DEVICENAME:
      {
        string = F(PLUGIN_NAME_120);
        break;
      }

    case PLUGIN_GET_DEVICEVALUENAMES:
      {
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_120));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_120));
        strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_120));
		strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[3], PSTR(PLUGIN_VALUENAME4_120));
        break;
      }

    case PLUGIN_WEBFORM_LOAD:
      {
        //const uint8_t i2cAddress = Plugin_120_i2c_addr(event);
        //addFormSelectorI2C(F("p120_bme680_i2c"), 2, Plugin_120_i2c_addresses, i2cAddress);
        //addFormNote(F("SDO Low=0x76, High=0x77"));
        addFormNumericBox(F("Altitude"), F("p120_bme680_elev"), PCONFIG(1));
        addUnit(F("m"));
        addFormNumericBox(F("Temperature offset"), F("p120_bme680_tempoffset"), PCONFIG(2));
        addUnit(F("x 0.1C"));
        String offsetNote = F("Offset in units of 0.1 degree Celcius");
        offsetNote += F(" (also correct humidity)");
        addFormNote(offsetNote);
        success = true;
        break;
      }

    case PLUGIN_WEBFORM_SAVE:
      {
        const uint8_t i2cAddress = getFormItemInt(F("p120_bme680_i2c"));
        PCONFIG(0) = i2cAddress;
        PCONFIG(1) = getFormItemInt(F("p120_bme680_elev"));
        PCONFIG(2) = getFormItemInt(F("p120_bme680_tempoffset"));
        success = true;
        break;
      }

    case PLUGIN_READ:
      {
        const uint8_t i2cAddress = Plugin_120_i2c_addr(event);
		const float tempOffset = PCONFIG(2) / 10.0;
		if (!Plugin_120_update_measurements(i2cAddress, tempOffset)) {
			success = false;
			break;
        }
        P120_sensordata& sensor = P120_sensors[i2cAddress];
        UserVar[event->BaseVarIndex] = sensor.last_temp_val;
        UserVar[event->BaseVarIndex + 1] = sensor.last_hum_val;
        const int elev = PCONFIG(1);
        if (elev) {
           UserVar[event->BaseVarIndex + 2] = Plugin_120_pressureElevation(sensor.last_press_val, elev);
        } else {
           UserVar[event->BaseVarIndex + 2] = sensor.last_press_val;
        }
		UserVar[event->BaseVarIndex + 3] = sensor.last_gas_resistance_val;
        if (loglevelActiveFor(LOG_LEVEL_INFO)) {
          String log;
          log.reserve(40); // Prevent re-allocation
          log = sensor.getDeviceName();
          log += F(" : Address: 0x");
          log += String(i2cAddress,HEX);
          addLog(LOG_LEVEL_INFO, log);
          log = sensor.getDeviceName();
          log += F(" : Temperature: ");
          log += UserVar[event->BaseVarIndex];
          addLog(LOG_LEVEL_INFO, log);
          log = sensor.getDeviceName();
          log += F(" : Humidity: ");
          log += UserVar[event->BaseVarIndex + 1];
          addLog(LOG_LEVEL_INFO, log);
          log = sensor.getDeviceName();
          log += F(" : Barometric Pressure: ");
          log += UserVar[event->BaseVarIndex + 2];
          addLog(LOG_LEVEL_INFO, log);
          log = sensor.getDeviceName();
          log += F(" : Gas Resistance: ");
          log += UserVar[event->BaseVarIndex + 3];
          addLog(LOG_LEVEL_INFO, log);
        }
        success = true;
        break;
      }
	  
      case PLUGIN_EXIT:
      {
        const uint8_t i2cAddress = Plugin_120_i2c_addr(event);
        P120_sensors.erase(i2cAddress);
        break;
      }
  }
  return success;
}


bool Plugin_120_update_measurements(const uint8_t i2cAddress, float tempOffset) {
	P120_sensordata& sensor = P120_sensors[i2cAddress];
	const unsigned long current_time = millis();
	
	String log;
	if (loglevelActiveFor(LOG_LEVEL_INFO)) {
	log.reserve(120); // Prevent re-allocation
	log = sensor.getDeviceName();
	log += F(" : ");
	}	
	
	// Read all sensors togeter
	/*
	// Initialize sensor once
	if (!sensor.initialized()) {
		if (!Plugin_120_begin(i2cAddress,false)) {
		  if (loglevelActiveFor(LOG_LEVEL_INFO)) {
			log += F(" Failed to find and initialize BME680 sensor");
			addLog(LOG_LEVEL_INFO, log);
		  }
		  return false;
		}
		sensor.state = P120_BMx_Initialized;
		sensor.last_measurement = 0;
	}
	static int32_t temperature, humidity, pressure, gas;     // Variable to store readings
	P120_BME680.getSensorData(temperature,humidity,pressure,gas); // Get most recent readings
	if ( (humidity == 100 * 1000) || (humidity == 0) ){		// After testing, values are not good if humidity shows 100%
	  if (loglevelActiveFor(LOG_LEVEL_INFO)) {
		log += F(" Reading sensor data failed");
		addLog(LOG_LEVEL_INFO, log);
	  }
	  return false;
	}
	sensor.last_temp_val = ((float) temperature) / 100;
	sensor.last_press_val = ((float) pressure) / 100;
	sensor.last_hum_val = ((float) humidity) / 1000;
	sensor.last_gas_resistance_val = ((float) gas) /100;
	*/

	// Read temp/hum/press or gas resistance

	if (P120_gas_cycle == 0) {											// Temp/Hum/Pressure
	//if (1) {																// Temp/Hum/Pressure
		log += F("Measuring Temperature/Humidity/Pressure");
		P120_gas_cycle = 1;
		if (!Plugin_120_begin(i2cAddress,false)) {
		  if (loglevelActiveFor(LOG_LEVEL_INFO)) {
			log += F(" - Failed to find and initialize BME680 sensor");
			addLog(LOG_LEVEL_INFO, log);
		  }
		  return false;
		}
		static int32_t temperature, humidity, pressure, gas;     		// Variable to store readings
		P120_BME680.getSensorData(temperature,humidity,pressure,gas); 	// Get most recent readings
		if ( (humidity == 100 * 1000) || (humidity == 0) ){				// Sort of data check
		  if (loglevelActiveFor(LOG_LEVEL_INFO)) {
			log += F(" - Reading sensor data failed");
			addLog(LOG_LEVEL_INFO, log);
		  }
		  return false;
		}
		sensor.last_temp_val = ((float) temperature) / 100;
		sensor.last_press_val = ((float) pressure) / 100;
		sensor.last_hum_val = ((float) humidity) / 1000;
		P120_BME680.setGas(320,150); // 320°c for 150 milliseconds		// Turn on gas heater for next cycle
	//}
	} else {															// Gas resistance only											
	//delay(1000);
	//if (1) {															// Gas resistance only											
		log += F(" Measuring Gas Resistance");
		P120_gas_cycle = 0;
		if (!Plugin_120_begin(i2cAddress,true)) {
		  if (loglevelActiveFor(LOG_LEVEL_INFO)) {
			log += F(" - Failed to find and initialize BME680 sensor");
			addLog(LOG_LEVEL_INFO, log);
		  }
		  return false;
		}
		static int32_t temperature, humidity, pressure, gas;     		// Variable to store readings
		P120_BME680.getSensorData(temperature,humidity,pressure,gas); 	// Get most recent readings
		sensor.last_gas_resistance_val = ((float) gas) /100;	
		P120_BME680.setGas(0,0); 										// Turn off gas heater and gas measurements for next cycle
	} 
	


	sensor.last_measurement = current_time;

	if (loglevelActiveFor(LOG_LEVEL_INFO))
	addLog(LOG_LEVEL_INFO, log);

	// Apply half of the temp offset, to correct the dew point offset.
	// The sensor is warmer than the surrounding air, which has effect on the perceived humidity.
	sensor.last_dew_temp_val = compute_dew_point_temp(sensor.last_temp_val + (tempOffset / 2.0), sensor.last_hum_val);

	if (loglevelActiveFor(LOG_LEVEL_INFO)) {
	log.reserve(120); // Prevent re-allocation
	log = sensor.getDeviceName();
	log += F(" : ");
	}
	
	if (tempOffset > 0.1 || tempOffset < -0.1) {
		// There is some offset to apply.
		if (loglevelActiveFor(LOG_LEVEL_INFO)) {
		  log += F(" Apply temp offset ");
		  log += tempOffset;
		  log += F("C");
		}
		if (loglevelActiveFor(LOG_LEVEL_INFO)) {
		  log += F(" humidity ");
		  log += sensor.last_hum_val;
		}
		sensor.last_hum_val = compute_humidity_from_dewpoint(sensor.last_temp_val + tempOffset, sensor.last_dew_temp_val);
		if (loglevelActiveFor(LOG_LEVEL_INFO)) {
		  log += F("% => ");
		  log += sensor.last_hum_val;
		  log += F("%");
		}
		if (loglevelActiveFor(LOG_LEVEL_INFO)) {
		  log += F(" temperature ");
		  log += sensor.last_temp_val;
		}
		sensor.last_temp_val = sensor.last_temp_val + tempOffset;
		if (loglevelActiveFor(LOG_LEVEL_INFO)) {
		  log += F("C => ");
		  log += sensor.last_temp_val;
		  log += F("C - ");
		}
	}

	if (loglevelActiveFor(LOG_LEVEL_INFO)) {
		log += F(" Dew point ");
		log += sensor.last_dew_temp_val;
		log += F("C");
	}

	if (loglevelActiveFor(LOG_LEVEL_INFO))
	addLog(LOG_LEVEL_INFO, log);

	return true;
}

//**************************************************************************/
// Initialize BME680 - Temp/Hum/Barometric/Pressure OR Gas Resistance
//**************************************************************************/

bool Plugin_120_begin(uint8_t i2cAddress, bool measure_gas_only) {
	
	// Read all sensors togeter 
	/*
	if(!P120_BME680.begin(Settings.I2C_clockSpeed)) { // Start BME680 using I2C protocol
		return false;
	}
	P120_BME680.setOversampling(TemperatureSensor,Oversample16); // Use enumerated type values
	P120_BME680.setOversampling(HumiditySensor,   Oversample16);
	P120_BME680.setOversampling(PressureSensor,   Oversample16);
	P120_BME680.setIIRFilter(IIR16);
	P120_BME680.setGas(320,150); // 320°c for 150 milliseconds
	//P120_BME680.setGas(0,0); // Turn off gas heater and measurements
	return true;
	*/
	
	// Read temp/hum/press and then gas resistance	
	if (measure_gas_only) {
		if(!P120_BME680.begin(Settings.I2C_clockSpeed)) { // Start BME680 using I2C protocol
			return false;
		}
		P120_BME680.setOversampling(TemperatureSensor,SensorOff); // Use enumerated type values
		P120_BME680.setOversampling(HumiditySensor,   SensorOff);
		P120_BME680.setOversampling(PressureSensor,   SensorOff);
		P120_BME680.setIIRFilter(IIR4);
		P120_BME680.setGas(320,150); // 320°c for 150 milliseconds
		return true;
	} else {
		if(!P120_BME680.begin(Settings.I2C_clockSpeed)) { // Start BME680 using I2C protocol
			return false;
		}
		P120_BME680.setOversampling(TemperatureSensor,Oversample16); // Use enumerated type values
		P120_BME680.setOversampling(HumiditySensor,   Oversample16);
		P120_BME680.setOversampling(PressureSensor,   Oversample16);
		P120_BME680.setGas(0,0); // Turn off gas heater and gas measurements
		return true;
	}
	
}

//**************************************************************************/
// MSL pressure formula
//**************************************************************************/
float Plugin_120_pressureElevation(float atmospheric, int altitude) {
  return atmospheric / pow(1.0 - (altitude/44330.0), 5.255);
}
//#endif // USES_P120
Sébastien - espRFLinkMQTT gateway RFLink MQTT on esp

FluffyChicken
Normal user
Posts: 6
Joined: 22 Dec 2019, 17:57

Re: BME 680 sensor

#26 Post by FluffyChicken » 02 May 2020, 20:59

That FUSION is the BSEC, I use it on the RaspberryPi myself.
It uses their own calibration and you can also supply a temperature offset to it.
I've not used it on ESP8266 but I think people had trouble when they tried, ESP32 I think was easier. (as a note, 8 bit and 16 bit setups are not recommended!)
Maybe due to it needing 28k or the lite version 17k

There are a few modes for the BME, the Low Power and the Ultra Low Power, don't worry about correct temps as you are suppose to supply an offset for you setup, as you would a BME280. It really is the only way to use it properly since it takes into accoutn the T/P/H reading between them.
Interestingly, the BSEC does not need to be on the ESP itself. It can be networked, say on your hub, and fed the information from the devices.

Best to read in their forum and github, unfortunately a lot of the information was in an old, not closed, github part and I can't remember much of it. But check their forums out and you'll find how it uses calibration to setup AQ readings, this and other BME are designed for inside use. Basically it calibrates it self by reading background for a while, you supply it with a high VOC of what you are reading (your temps will alter what you are reading) so it know high and average etc.

It's been a long time since I delved into it and I didn't get to far into the intricacies.
Of course if you don't want IAQ or eVOC/eCO2 then you don't need to use it, just provide your own offset to the temp and use that to calibrate the humidity.
If you grab the BSEC code, other than the blob, you can see how the rest of it works including in their documentation.

Post Reply

Who is online

Users browsing this forum: No registered users and 10 guests