Anyone have a BME680?

Posted on
  • They're really neat sensors that measure temperature, pressure, humidity, but also the air quality.

    https://ae-bst.resource.bosch.com/media/­_tech/media/datasheets/BST-BME680-DS001-­00.pdf

    Pimoroni sell breakouts here: https://shop.pimoroni.com/products/bme68­0

    I've attached some test code I'm using for it, which is almost there... Humidity works, and the other values move around - it's just I think they're a bit questionable - possibly caused by integer overflows after converting from the typed C code :(

    Anyway, for the moment I've run out of time to spend on it, but I thought I'd post it up in case anyone else was interested.


    1 Attachment

  • BME680 is used in uRadMonitor https://www.uradmonitor.com/bosch-bme680­/ a project made by a guy in my town which went global (800 units deployed)

    I hope BME680 is more accurate than the sensors in my Nordic Thingy ;)

  • Hi! I have changed getInt16 () and getUint16 (xx, true), according to Doc

    function DataView.getUint16 (byteOffset, littleEndian)
    byteOffset - The offset in bytes to read from
    littleEndian - (optional) Whether to read in little endian - if false or undefined data is read as big endian
    
    

    So now, temperature, pressure and humidity show the same as my Ruuvitag.
    Gas resistance is very high so I do not know if it is correct! 12,535,991.64395217411.
    If I try with upython on a Wipy, the number is negative.
    The next thing I want to try is on a RaspberryPi.

    BME680.prototype.get_calib_data = function() {
      var coefs = new Uint8Array(C.COEFF_ADDR1_LEN+C.COEFF_ADD­R2_LEN);
      coefs.set(this.r(C.COEFF_ADDR1,C.COEFF_A­DDR1_LEN));
      coefs.set(this.r(C.COEFF_ADDR2,C.COEFF_A­DDR2_LEN),C.COEFF_ADDR1_LEN);
      var vc = new DataView(coefs.buffer);
      // everything is little endian
      this.cal={};
      /* Temperature related coefficients */
      this.cal.par_t = [,vc.getUint16(C.T1_LSB_REG, true) // PB
                        ,vc.getInt16(C.T2_LSB_REG, true)  // PB
                        ,vc.getInt8(C.T3_REG)];
    
      /* Pressure related coefficients */
      this.cal.par_p = [,vc.getUint16(C.P1_LSB_REG, true) // PB
                        ,vc.getInt16(C.P2_LSB_REG, true) // PB
                        ,vc.getInt8(C.P3_REG)
                        ,vc.getInt16(C.P4_LSB_REG, true) // PB
                        ,vc.getInt16(C.P5_LSB_REG, true) // PB
                        ,vc.getInt8(C.P6_REG)
                        ,vc.getInt8(C.P7_REG)
                        ,vc.getInt16(C.P8_LSB_REG, true) // PB
                        ,vc.getInt16(C.P9_LSB_REG, true) // PB
                        ,vc.getUint8(C.P10_REG)];
    
      /* Humidity related coefficients */
      this.cal.par_h = [,(vc.getUint8(C.H1_MSB_REG) << C.HUM_REG_SHIFT_VAL) |
                         (vc.getUint8(C.H1_LSB_REG) & C.BIT_H1_DATA_MSK)
                        ,(vc.getUint8(C.H2_MSB_REG) << C.HUM_REG_SHIFT_VAL) |
                         (vc.getUint8(C.H2_LSB_REG) >> C.HUM_REG_SHIFT_VAL)
                        ,vc.getInt8(C.H3_REG)
                        ,vc.getInt8(C.H4_REG)
                        ,vc.getInt8(C.H5_REG)
                        ,vc.getUint8(C.H6_REG)
                        ,vc.getInt8(C.H7_REG)];
    
      /* Gas heater related coefficients */
      this.cal.par_gh = [,vc.getInt8(C.GH1_REG)
                        ,vc.getInt16(C.GH2_LSB_REG, true) // PB
                        ,vc.getInt8(C.GH3_REG)];
      /* Other coefficients */  
      this.cal.res_heat_range = (this.r(C.ADDR_RES_HEAT_RANGE_ADDR,1)[0]­&C.RHRANGE_MSK)/16;
      this.cal.res_heat_val = this.r(C.ADDR_RES_HEAT_VAL_ADDR,1)[0];
      this.cal.range_sw_err = (this.r(C.ADDR_RANGE_SW_ERR_ADDR,1)[0]&C­.RSERROR_MSK)/16;
    };
    
    
  • @Frida that's amazing - thanks! I can't believe I messed that up! :)

    I'll update my original post, and will make a note to create a proper module on the Espruino site with it.

    If I try with upython on a Wipy, the number is negative.

    That sounds wrong to me for a resistance measurement. Pimoroni has a bit of info on https://learn.pimoroni.com/tutorial/sand­yj/getting-started-with-bme680-breakout

    The sensor produces gas resistance readings in Ohms. These will range from the low thousands up to several hundred thousand Ohms. Every time that you use the sensor, it will take a few minutes (or more if it's the first time you've used it) to stabilise; you'll see the readings creeping upwards. When the readings stabilise, this will be your background reference reading.

    So we'd expect the value to be pretty high, but not that high :)

  • Yes, that's the one I'm looking at, I've soldered the plug on Raspi and connected the sensor.
    The gas resistance is now around 180,000 Ohm, after several hours of operation, and falls to
    about 100,000 Ohm, when I breathe on it.
    I can see in the C program that 64 bit variables are used, can Pico calculate 64 bit?

  • Espruino kind of does 64 bit - when you do something with two 32 bit integers it's done in 64 bits and then if it doesn't fit in a 32 bit int, a 64 bit double is used - so you won't get overflow.

    In the calculations they're using ints because they don't want to use floating point, but we don't care. A lot of that random multiply/divide stuff could actually be taken out since it's only there to preserve accuracy when done on an integer system.

    I guess it's possible that the calculations are actually relying on the fact that 32 bit integers will clip the number? Do you think it's possible that you could find the calibration and gas_res_adc/gas_range values that the Python code uses to get a certain result - and then we could feed those into the Espruino module and see where it goes wrong.

  • Hi, I have found the last mistakes, so now the gas sensor works.
    There was a calculation of calc_heater_resistance and calc_heater_duration missing.
    I'm still working on adding some features.
    I tried to turn it into a module, but I do not have enough knowledge yet.
    I hope you can use it. I moved the tables under "C".
    If you are looking for PB, you can see where I have made changes.


    1 Attachment

  • That's amazing - thanks! It's pretty much a module already (typing exports=BME680 at the end would allow you to use it) - but when things calm down a bit I'll add it properly with a bit of documentation.

  • And it's online: http://www.espruino.com/BME680

    Thanks for your help!

  • What a cool sensor. Air quality - measured in ohms! Maybe in the next version they can tell us the humidity in lux, and the temperature in ounces?

  • Glad to help

  • Very cool, just ordered one at the german site of Pimoroni .

  • You can read more of it on: https://learn.adafruit.com
    The BME680 takes those sensors to the next step in that it contains a small MOX sensor. The heated metal oxide changes resistance based on the volatile organic compounds (VOC) in the air, so it can be used to detect gasses & alcohols such as Ethanol, Alcohol and Carbon Monoxide and perform air quality measurements. Note it will give you one resistance value, with overall VOC content, it cannot differentiate gasses or alcohols.

  • Got mine up and running attached to a Pico.

    Not sure how to read/interpret the gas_resistance

        {
          "new": true,
          "temperature": 22.87837751771,
          "pressure": 1006.94,
          "humidity": 33.623,
          "gas_resistance": 189334.44260170066
         }
    

    Is there ca context between Indoor air quality (IAQ) (page 9) and gas_resistance?

    Ok, have to wait some time....

    Gas is returned as a resistance value in ohms. This value takes up to 30 minutes to stabilize! Once it stabilizes, you can use that as your baseline reading. Higher concentrations of VOC will make the resistance lower. (Source)


    1 Attachment

    • Indoor_air_quality_classification.JPG
  • Thanks to all of you for this great implementation of BME680!

  • This could be a way to get IAQ values for gas_resistor values

    https://github.com/pimoroni/bme680/blob/­master/examples/indoor-air-quality.py#L4­5-L91

  • Post a reply
    • Bold
    • Italics
    • Link
    • Image
    • List
    • Quote
    • code
    • Preview
About

Anyone have a BME680?

Posted by Avatar for Gordon @Gordon

Actions