BME 680 sensor

Moderators: grovkillen, Stuntteam, TD-er

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: 4289
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 16059 times

TD-er
Core team member
Posts: 4289
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 15887 times

TD-er
Core team member
Posts: 4289
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: 4289
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: 89
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: 4289
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: 4289
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: 120
Joined: 28 Feb 2018, 07:40
Location: Gold Coast (QLD), Australia

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.
Friends with kangaroos and some time koala rescuer.

TD-er
Core team member
Posts: 4289
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: 120
Joined: 28 Feb 2018, 07:40
Location: Gold Coast (QLD), Australia

Re: BME 680 sensor

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

Thanks
Friends with kangaroos and some time koala rescuer.

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: 9
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.

Haldi_2
Normal user
Posts: 15
Joined: 24 Aug 2020, 18:10

Re: BME 680 sensor

#27 Post by Haldi_2 » 15 Feb 2021, 17:36

seb82 wrote: 02 May 2020, 16:51
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.
Which makes it kinda annoying to use on a Battery Powered device....
But on the other hand. Is the BME680 even usefull/accurate on a Battery device with deep sleep?

ollo
Normal user
Posts: 5
Joined: 28 Sep 2019, 10:43

Re: BME 680 sensor

#28 Post by ollo » 15 Feb 2021, 19:11

BME680 (on BSEC lib) can be used with deep spleep. One has to take care the timestamp is continuous - see example here:

https://github.com/BoschSensortec/BSEC- ... pSleep.ino

Haldi_2
Normal user
Posts: 15
Joined: 24 Aug 2020, 18:10

Re: BME 680 sensor

#29 Post by Haldi_2 » 19 Feb 2021, 03:17

I've managed to get a value with the rules....

Code: Select all

on BME680#Gas=0 do
 taskrun,1
endon
Image
So there is actually only a tinly little delay needed after boot before the sensore (gas only) is read correctly is what i thought.... but no

Code: Select all

on WiFi#Connected do
 Delay 1000
endon
Delay on WiFi connection doesn't help at all. The Sensor needs to be polled twice before it's actually read correctly.

I had the idea about deactivating the Task "Enabled [ ]" and then manually call it via the rules. But that doesn't work.It only publishes the Task to "Controller 1" when it's Enabled.
Because my Controller 1 is not a MQTT but a Generic UDP InfluxDB i cannot use the Publish command :(

So my only option left is to create a dummy device and split all 4 into a new Task which is being sent...
Image

Code: Select all

on System#Boot do
 taskrun,1
 taskrun,1
 TaskValueSet,3,1,[BME#Temperature]
 TaskValueSet,3,2,[BME#Humidity]
 TaskValueSet,3,3,[BME#Pressure]
 TaskValueSet,3,4,[BME#Gas]
endon
Why is there 2 times TaskRun in there? Because directly after boot the normal TaskExecution hasn't happened yet... So it would copy 0 value otherwise.

But now it actually works as expected with Deep Sleep.... finally.

User avatar
Ath
Normal user
Posts: 571
Joined: 10 Jun 2018, 12:06
Location: NL

Re: BME 680 sensor

#30 Post by Ath » 19 Feb 2021, 07:50

Have you tried the 'official' BME680 that was added to the ESPEasy nightly build a couple of months ago?
TD-er moved that to the mega repo, after adjusting it to match the current state of ESPEasy development. You will need a 'test' build.
/Ton

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

Re: BME 680 sensor

#31 Post by TD-er » 19 Feb 2021, 11:05

I also made a test build 2 days ago containing the latest code of the mega branch:

https://www.dropbox.com/s/07vv1cspmtq4s ... 6.zip?dl=0
https://www.dropbox.com/s/mkekzbsli4h85 ... 6.zip?dl=0

Haldi_2
Normal user
Posts: 15
Joined: 24 Aug 2020, 18:10

Re: BME 680 sensor

#32 Post by Haldi_2 » 23 Feb 2021, 18:30

I used the Nightly if i downloaded and flashed the correct one. so that should have been the "official" one

Firmware
Build:⋄ 20111 - Mega32
System Libraries:⋄ ESP32 SDK v3.2.3-14-gd3e562907
Git Build:⋄
Plugin Count:⋄ 84 [Normal] [TEST ESP32]
Build Origin: Travis
Build Time:⋄ Dec 27 2020 11:40:13
Binary Filename:⋄ ESP_Easy_mega_20201227_test_ESP32_4M316k
Build Platform:⋄ Linux-4.19.104-microsoft-standard-x86_64-with-glibc2.29
Git HEAD:⋄ mega-20201227_b706392

But let me OTA that Newest one TD-er linked and see what it does.


P.S i see that there is now a "ESP_Easy_mega_20210217_test_ESP32_4M316k_lolin_d32_pro"
I use a Lolin D32 NOT Pro edition... would it be a bad idea to flash that ?
Not really sure what " [Build] Rename test_ESP32_4M316k_lolin_d32_pro to match build script checks" means.


Edit:
Jep still happening. Simply going into the Sensor (which had a proper Value) clicking Edit then Submit then CLose will cause it to go to Zero
Anmerkung 2021-02-23 183733.jpg
Anmerkung 2021-02-23 183733.jpg (71.66 KiB) Viewed 807 times
Do i need a reset after OTA ?

Some kind of Log that might help?

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

Re: BME 680 sensor

#33 Post by TD-er » 23 Feb 2021, 20:42

OK, I hope I do get the point you're trying to make here...

You're saying the plugin should "know" the first value of the BME680 is bogus and try to make a new call to make sure it will not return "success = true;" on the first PLUGIN_READ call?

Haldi_2
Normal user
Posts: 15
Joined: 24 Aug 2020, 18:10

Re: BME 680 sensor

#34 Post by Haldi_2 » 24 Feb 2021, 09:42

Yes.
But since I'm the only one reporting this issue I'm not fully confident that this is not a bug/hardware issue with my specific BME680 board.

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

Re: BME 680 sensor

#35 Post by TD-er » 24 Feb 2021, 10:29

Well the BME680 is rather expensive and since we're not allowed (!!!) to include the Bosch proprietary library for computing an AQI value, I honestly don't see the added value of the BME680 over the BME280.
Also it is a rather new plugin, so I guess not a lot of users have used it yet.

ollo
Normal user
Posts: 5
Joined: 28 Sep 2019, 10:43

Re: BME 680 sensor

#36 Post by ollo » 25 Feb 2021, 10:58

Hi TD-er,

there is a GitHub repository which mimics the TVOC functionality of the Bosch library - maybe worth to check out?

https://github.com/juergs/ESPEasy_BME680_TVOC

Thanks, ollo

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

Re: BME 680 sensor

#37 Post by TD-er » 25 Feb 2021, 16:25

Ah didn't know about that one.
Would be a good idea to have a look at it and it is already supposed to be working with ESPEasy, so should not be impossible to include :)

User avatar
Ath
Normal user
Posts: 571
Joined: 10 Jun 2018, 12:06
Location: NL

Re: BME 680 sensor

#38 Post by Ath » 25 Feb 2021, 17:02

TD-er wrote: 25 Feb 2021, 16:25 Would be a good idea to have a look at it and it is already supposed to be working with ESPEasy, so should not be impossible to include :)
I looked at that code for a few minutes, but as a coder, it makes me a bit unhappy :shock: (but that's probably not an objective view)
That doesn't mean it isn't fixable ;)
/Ton

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

Re: BME 680 sensor

#39 Post by TD-er » 25 Feb 2021, 17:30

It does seem to write directly to FHEM instead of using a controller for it.
But that's what I noticed in the first quick glance.
It also does allocate a lot of arrays on the stack, which is also a bit "moah"...

I'm only interested in the IAQ computation code, so I do hope it is in there.

Haldi_2
Normal user
Posts: 15
Joined: 24 Aug 2020, 18:10

Re: BME 680 sensor

#40 Post by Haldi_2 » 25 Feb 2021, 17:36

on another note...
I've switched from using Rules to simply polling the same sensor twice. (Seriously didn't expect that to work in the beginning^^)

The first half day was without Deepsleep. And polling every 5 Minutes. Battery drops rapidly.
The second part was with 300sec Deep sleep waking for 1 second and using the Rules stated above, polling sensor (additionaly) twice and then copying data into dummy task. You see this part disturbs the Analog Voltage Read quite a bit.
The third part was simply using 2 times the same sensor in Devices as different tasks and only sending the 2nd one which had correct values. Way easier on Battery ADC, but for some reason the BME680 Air Value is WAY lower and also doesn't peak anymore. It stays way more constant even though i did air out the room a few times. But on the Other hand it does look more "similar" to the first part which was always online.
Anmerkung 2021-02-25 172702.jpg
Anmerkung 2021-02-25 172702.jpg (64.85 KiB) Viewed 665 times
Anmerkung 2021-02-25 1727022.jpg
Anmerkung 2021-02-25 1727022.jpg (45.01 KiB) Viewed 665 times



So now i've tried with 3 times same sensor reading and only sending Task nr 4 to the Controller.
Anmerkung 2021-02-25 172509.jpg
Anmerkung 2021-02-25 172509.jpg (107.81 KiB) Viewed 665 times
This shouldn't be due to "low" battery voltage right? Normaly Most sensors should work without issues till 3.4V down. I'll test that later when i plug a new battery...

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

Re: BME 680 sensor

#41 Post by TD-er » 25 Feb 2021, 20:22

Bosch's other sensors like the BME280 do use a filter which just slowly iterates to the actual value.
So maybe you can test by calling the non-sending task multiple times before calling the sending task?

Haldi_2
Normal user
Posts: 15
Joined: 24 Aug 2020, 18:10

Re: BME 680 sensor

#42 Post by Haldi_2 » 25 Feb 2021, 23:35

After switching from 2 measurements to 3 measurements before sending the 3rd it goes back up to this:
Anmerkung 2021-02-25 233421.jpg
Anmerkung 2021-02-25 233421.jpg (55.33 KiB) Viewed 644 times
So let's run it like that for a few days.

ollo
Normal user
Posts: 5
Joined: 28 Sep 2019, 10:43

Re: BME 680 sensor

#43 Post by ollo » 26 Feb 2021, 21:39

Hi,

I'm using the lates build (ESP_Easy_mega_20210223_test_beta_ESP8266_4M1M) with the BME680 sensor.
Yes, first reading of the Gas value after editing the Device setup is always zero - so what?

Edit: just came across this - https://github.com/adafruit/Adafruit_BME680/issues/42. The Plugin uses the later (intermediate)?!

I noticed the "Altitude" variable is not wired up in the code?! No change of "Pressure" when changing the value in the Device settings.

Thanks
Last edited by ollo on 28 Feb 2021, 10:50, edited 1 time in total.

ollo
Normal user
Posts: 5
Joined: 28 Sep 2019, 10:43

Re: BME 680 sensor

#44 Post by ollo » 28 Feb 2021, 10:38

Hi TD-er,

one more issue - the BME680 temperature reading usually is off by 1..3C. Just offsetting the temperature reading in the device setting formula does not compensate the Humidity reading. While the BSEC lib from Bosch offers a temperature compensation, the BME680 lib from Adafruit does not?!
Yet I found the following "Issue" on GitHub how to implement the temperature offset:

https://github.com/pimoroni/bme680-python/issues/11
https://github.com/pimoroni/bme680-python/issues/13

Please add the temperature offset setting and calculations to the BME680 Plugin.

Thanks!

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

Re: BME 680 sensor

#45 Post by TD-er » 28 Feb 2021, 11:28

The BME280 plugin has an offset computation like that.
Is that also good enough?
It computes the dew point based on measured temp/hum, adjusts the temp and then computes the humidity using dew point and corrected temp.

ollo
Normal user
Posts: 5
Joined: 28 Sep 2019, 10:43

Re: BME 680 sensor

#46 Post by ollo » 28 Feb 2021, 13:29

Hi TD-er

... I'd guess so. Let's give it a try. Not sure how the correction is being done here, because if I compare the calculated dew point (same formula) of the BME680 unit with one nearby but using a DHT22 its matching pretty well.

I"m using a BME280 too. No temperature offset is applied. The temperature seems to be OK comparing to another thermometer nearby. Yet the Humidity is way off. For comparison I put a ESP32 unit using BME680 with the BSEC lib next to the unit with a BME280 running ESPEasy - see picture attached comparing rose line (ESP32_3Luftfeuchte) to dark blue line (DraussenLuftfeuchte). Also a 3rd sensor from a commercial weather station gives me another, even lower reading (not in the plot).

Thanks!
Attachments
Bild_2021-02-28_132425.png
Bild_2021-02-28_132425.png (54.24 KiB) Viewed 465 times

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

Re: BME 680 sensor

#47 Post by TD-er » 28 Feb 2021, 20:26

Problem with dew point calculation is that there appear to be several formulas for them.
Probably the one I use in the BME280 code is a bit computational expensive for really low power devices, so I guess the main difference between the existing formulas is more like a linear interpolation between 2 or more points on a curve.
So the differences are most likely not that big on the 'regular' interval of 40 - 70% relative humidity, but outside that range they may start to differ a lot.

My experience with the BME280 is that it may heat up quite fast, so it really surprises me to hear the BME280 does not show an offset in temperature.
Also the BME280 does need a number of readings to get a proper reading, so make sure to not compare the first measurement.
And always use the temp/hum measured in a single run.

Post Reply

Who is online

Users browsing this forum: No registered users and 8 guests