Shop OBEX P1 Docs P2 Docs Learn Events
Considering a BME680 module — Parallax Forums

Considering a BME680 module

I am considering a BME680 module, but after checking the Learn site, I did not see anything in there that shows you how to use it with SimpleIDE. And I mean a wiring example plus some C code examples. It seems that not long ago their was quite a bit of material that dealt with SimpleIDE and plenty of useful C examples. Not sure where Parallax is going with all of this, is all the SimpleIDE C stuff being hidden, or just very difficult to find.

Ray

Comments

  • Most of the educational material is being provided in BlocklyProp. The good thing is that Blockly also produces C code which you can use with SimpleIDE.
  • Hi Ray !

    I can't answer about learn content/etc... but I know that BlocklyProp has an export function to download the blocks as a SimpleIDE project, and also BlocklyProp supports that new sensor.

    As I tried the module already in BlocklyProp, I would be happy to download and share here the code I used as a SimpleIDE project, and also provide the BlocklyProp code link.

    I'll make a note to do that on Monday, and hopefully that helps you take a look at the C libraries. You may need to update your SimpleIDE workspace too.
  • What a great opportunity to write a nice C library for the BME680 and share it with the community.
  • The latest Learn folder already has a C library for the BME680. Since the BME680 can be programmed using I2C or SPI or …, I am not sure how that would be wired or which one of the protocols you should use.

    The big question, has anybody used this module in the outdoors? Will it survive -10* F, my cm2302 did not, so I want something that will survive extreme cold and high humidity.

    Thanks

    Ray
  • I have used a BME280 for several years now it works just fine. Cold or Hot. Sitting on a pole above my roof.

    Mike
  • VonSzarvasVonSzarvas Posts: 3,492
    edited 2019-09-30 13:13
    Here's some sample code:

    BlocklyProp
    http://blocklyprop.com/blockly/projectlink?id=113355&key=a5bedeb1-4b7b-4b12-a913-e5f10c60d291

    SimpleIDE
    // ------ Libraries and Definitions ------
    #include "simpletools.h"
    #include "bme680.h"
    
    // ------ Global Variables and Objects ------
    bme680 *gas_sensor;
    
    int temperatureF;
    int pressuremmHg;
    int altitudeFeet;
    int gasSensor;
    int humidityRH;
    
    
    
    // ------ Main Program ------
    int main()
    {
      gas_sensor = bme680_openSPI(14, 13, 15, 12); // SCK, SDI, SDO, CS
    
      pause(100);
      while(1) {
        bme680_readSensor(gas_sensor);
        temperatureF = (int)(bme680_temperature(gas_sensor, FAHRENHEIT) );
        pressuremmHg = (int)(bme680_pressure(gas_sensor, MMHG) );
        altitudeFeet = (int)(bme680_altitude(gas_sensor, FEET) );
        gasSensor = (int)(bme680_gasResistance(gas_sensor) );
        humidityRH = (int)(bme680_humidity(gas_sensor) );
        term_cmd(CLS);
        print("BME680 Environmental Sensor");
        print("\r");
        print("===========================");
        print("\r");
        print("%s%d\r", "Temperature (F)   = ", temperatureF);
        print("%s%d\r", "Pressure (mmHg)   = ", pressuremmHg);
        print("%s%d\r", "Altitude (feet)   = ", altitudeFeet);
        print("%s%d\r", "Gas Sensor (ohms) = ", gasSensor);
        print("%s%d\r", "Humidity (RH)     = ", humidityRH);
        pause(3000);
      }
    
    }
    

    Edit the pin setting line to match your connections
    gas_sensor = bme680_openSPI(14, 13, 15, 12); // SCK, SDI, SDO, CS
    

    You can wire the BME680 pins direct to Propeller pins. Power the BME680 from 3.3V


  • Thank You VonSzarvas, I was not sure about that SPI stuff. Should there be a resistor anywhere, like you needed one with the cm2302?

    I went ahead and ordered a couple of BME680 modules, I always need a backup unit, never know what can happen to the first one that you work with for the first time.

    Looking at the code that VonSzarvas provided, is that what blocklyprop produced, or was it cleaned up a bit. I am considering, maybe learning blocklyprop, as a quick prototype language. But, I am not sure about always having to be signed in in order to use the software. My preference is always to have the software locally, like on my personal computer.

    I am also considering the new P2 eval, that will be available, maybe by the end of this month. Not sure if there is a workable language available to make use of the BME680 module.

    Ray
  • PublisonPublison Posts: 12,366
    edited 2019-09-30 17:21
    Rsadeika wrote: »

    Looking at the code that VonSzarvas provided, is that what blocklyprop produced, or was it cleaned up a bit. I am considering, maybe learning blocklyprop, as a quick prototype language. But, I am not sure about always having to be signed in in order to use the software. My preference is always to have the software locally, like on my personal computer.

    Ray

    This is the VonSzarvas blockly code that created the C code and the unmodified C code.

    This thread talks about running Blockly Prop offline. I think there is a newer client or system available, but I can not find it at this time.

    https://forums.parallax.com/discussion/168325/instructions-for-running-blocklyprop-offline

    640 x 454 - 111K
    640 x 633 - 129K
  • Thanks Publison. When I get the modules I will try running the generated code, straight up, in SimpleIDE, and see if it runs as is.

    Ray
  • I got my BME680 modules today and I started to work with it. Of course I am using SimpleIDE, and the code that was produced by BlocklyProp works as expected, when used in SimpleIDE.

    The one thing that is really confusing me is the value that you get for the gasSensor reading. The values are in ohms, how do you correlate that with anything. In the BOSCH data sheet they talk about the IAQ Index, but those values do not correspond to the ohms numbers. Anybody have any idea as to how to interpret the ohms numbers, for useful things.

    Ray
  • Google search terms "bosch bme680 iaq" give a lot of info on IAQ. In short it's a number produced by Bosch's closed source proprietary SensorTec library (I think that's the name) for various platforms. No one seems to know what the actual algorithm is outside of Bosch.
  • So, what to do with an ohms reading, anything useful?

    Ray
  • pmrobertpmrobert Posts: 677
    edited 2019-10-02 23:04
    It does seem to reflect overall air content - if I cook something in my home that emits detectable smells (let's say blackening mahi for example) the ohms reading does go down. After cooking and the AC filters clean the air up it comes back up. I live near very large sugar cane fields that burn them and smoke us coastal residents out when they are actively burning - down it goes. If you breathe on it, down it goes. If I ingest any alcohol and breathe on it, down it goes even more. I use the BME680 for quantifying temp, humidity and pressure to accurately determine the ambient speed of sound (ballistic chronograph) so I've only been semicurious about the IAQ function. My observation has been that the higher the reported resistance the cleaner the air - and the inverse. Hope that helps!
  • I did some internet searching, and it looks like, as far as the gasSensor is concerned, BOSCH has some kind of software package, BSEC software, available, for a price. There were some forums, where the discussion sounded like people were doing their own experiments to correlate ohms readings and different air exposure.

    In order to get some meaning for the ohms values, I guess you have to set up some controlled experiments. For example, expose the sensor to CO2, record the ohms number. So on and so forth. Since it has been a very long time ago that I spent some time in a lab, not sure if I am the person to do this stuff.

    For starters I guess I will have to move the sensor to different parts of the house to see what kind of readings I am getting. Then try to determine which area has the highest ohms value, and make the decision, that is the cleanest air. And then go from there. Now I have to figure out the best way to do the data collection for comparison purposes.

    Ray
  • First experiment:
    Since I bought two bme680 modules, I set one up on an Acitivity Board, and the other one on a breadboard using a FLiP. I am also using the exact same code for the two setups. I placed both units at the same level with the sensors within two inches of one another, facing each other.

    The readings are relatively close, but they are different, especially the gasSensor readings. The one unit - 107165 ohms, while the other unit - 132831 ohms. These two readings are quite different, not sure how to interpret the gasSensor values, if they are different for each sensor, when in the same location. Maybe introduce a tolerance level of some sort with such large numbers involved.

    The other fairly large difference is in the altitude readings. The one unit - 745 feet, while the other unit - 756 feet. So I guess the question is, which one is right.

    If I am going to place each unit in a different part of the house, how do I know if its reading the real air conditions. I guess, since these are $30 devices, and not $3000 devices, a fudge factor will have to be incorporated. At least the temp, humidity, and pressure are very, very close.

    Ray

  • I went ahead and replaced my cm2302, outside, with the brand spanking new BME680.

    The BME680 seems to be working as expected, I am getting some good results for the temperature, humidity, and pressure. The other two are somewhat baffling me. The altitude values keep changing, one time it was something like 645 feet, and today it is reading 440 feet. Is this part of the earth on a roller-coaster ride, sure does not feel like it, yet.

    The other value is the gas sensor, my readings outside are ~235313 ohms, not sure if that is good or bad. When I did a reading, inside of the house, it was ~110,000 ohms. Does this mean that the inside of my house is unfit for human breath? Still grappling with the gas sensor values interpretation.

    Ray
  • The changing altitude reading is curious; I thought that was derived from pressure, which I think you mentioned was fairly stable.

    Maybe the altitude calculation also relies on temperature, either directly or indirectly.... I wonder, do you seem to get similar altitude readings at the same time of day (especially when temperature and pressure conditions are similar)?

    Sea level is another factor usually; probably a reasonable constant was chosen for that though? (I guess if the Blocks don't ask for a sea-level parameter, then that questions is answered!)




  • Earlier I stated the altitude was 440 feet now the reading is 483 feet.

    I am going to set up a data logging program for the BME680. Now I am not sure what could be affecting the altitude, is it the pressure, or temperature or humidity or a combination of some of those items.

    Ray
  • For the pressure to read correctly, you must provide the current altitude. A pilot will obtain the current pressure from the airport where he is landing,so that he will have a correct altitude over the airport.
    Jim
  • Today, I did a re-test of the BME680 module. The results have not changed from a couple of days ago. I am using SimpleIDE, and running the original BlocklyProp C code that was generated.

    Temperature.
    At my desk, the temp reading, from the module, was 75* (F). I used a thermometer to get a reference temp, which was 72* (F). So, the module needs to calibrated in the C code, to bring the read out to actual temp.

    Humidity.
    At the desk, the humidity reading, from the module, was 58%. A reading from a humidity dial, near by, 64%. I do not intend on a calibration, for my purposes it is close enough.

    Pressure.
    This was very close to the barometer dial that I used as a reference read out. No calibration necessary.

    Altitude.
    For my location, the altitude is ~740 feet. The readings that I have been getting are between ~450 - 580 feet. not sure what the problem is. I am now wondering if their is an inconsistency in the 'bme680_altitude()' function, in the BME680 library. I guess Parallax will have to look into that one.

    Gas sensor.
    Again not sure of what to make of these numbers. On the internet, I did find a Bosch site that offered up the BSEC library, that has functions for converting the ohms value into something that is useful. Not sure why Parallax did not include those functions in the existing BME680 library. I guess Parallax will have to address that point.

    Overall, I am somewhat satisfied with the BME680 module. Once the altitude read out gets figured out, and the gas sensor readings get some logical meaning, this should be a very useful module.

    Ray
  • VonSzarvasVonSzarvas Posts: 3,492
    edited 2019-10-09 17:09
    Looking into the altitude code, there are some constants and unit-conversion values in use:

    float bme680_altitude(bme680_t *dev, char unit) {
      float calc_alt = 0.0;
    
      calc_alt = 44330.0 * (1.0 - pow((dev->pressure / 101325.0), 0.1903));
      
      if (unit == FEET) {
        calc_alt *= 3.28084;
      }
        
      return calc_alt;
    }
    


    I'm going to speculate that one of those values represents sea-level, and that you could improve your results by plumbing in your actual number.

    Anyway- I'll ask the question and report back !

  • Hi Ray,

    Reading some more, I see the air quality (gas) measurement requires an internal hot-plate, and maybe that could offset the other readings.

    The docs mention to run the sensor for 20 minutes first time, and then allow a couple minutes for readings to stabilize each time you start using it (apply power).
    Speculation:- Maybe that's because it needs to wait for the hot plate to warm up, and then figure out the offset to apply to temp/etc... so you get the correct readings.

    As a test, what about running the sensor with the "Air Quality heater" block set to disabled ? And don't read the gas sensor reading.
    Do you get more accurate results for temp, pressure and altitude like this ?

    If that is the case, maybe there just needs to be a small pause between reading those 3, and then the gas sensor. Perhaps read the "3" each 30 or 60 seconds, and the gas at the next 30 or 60 seconds, so you get a full set of readings each minute or two that hopefully don't impact each other?


    Attached is a snippet from the sensor manufacturer about the altitude calculation. It has that pressure-at-sea-level constant which might be different for your location.


    I'm still surprised your pressure reading is stable, yet altitude is changing. Looking at the algorithm it's based on the pressure and a constant, so you'd think they'd either both be right, or both be changing similarly. But maybe the pressure reading comes before the gas reading (heating), whereas the altitude calculation is being done in the Parallax library after the gas reading (and taking a second pressure reading at that moment),- could explain the difference, ; hence thinking that the above test may solve.

    Certainly this is an interesting thing to investigate; thanks for sharing your progress and findings.
    1745 x 1474 - 213K
  • Today I added some cm2302 code to the program below. Something is affecting the temperature result that the bme680 is showing.

    I first added the new code to the while(), that was showing the bme680 temperature at least 15 degrees above the actual temperature. Then I moved the cm2302 code to its own function, but the same thing is occurring. Not sure if there is a problem with dht22 lib or the bme680 lib, but running both at the same time, a problem is occurring. I might have to put the cm2302 code in its own COG, but that would be a waste of a COG, not sure if that would solve the problem. Not sure what the problem is.

    Ray

    /*
      flip_1.c
      http://learn.parallax.com/propeller-c-tutorials 
    */
    #include "simpletools.h"                      // Include simple tools
    #include "bme680.h"
    #include "dht22.h"
    
    bme680 *gas_sensor;
    double temperatureF;
    int humidityRH;
    double pressureinHg;
    int altitudeFeet;
    int gasSensor;
    
    void cm2302();
    
    int main()                                    // Main function
    {
      // Add startup code here.
      //float t1,h1,temp1,humid1;
      /*                          SCK, SDI, SDO, CS */
      gas_sensor = bme680_openSPI(3,    2,   1,   0);  
     
      while(1)
      {
        // Add main loop code here.
        bme680_readSensor(gas_sensor);
        temperatureF = (double)(bme680_temperature(gas_sensor, FAHRENHEIT) );
        pressureinHg = (double)(bme680_pressure(gas_sensor, INHG) );
        altitudeFeet = (int)(bme680_altitude(gas_sensor, FEET) );
        gasSensor = (int)(bme680_gasResistance(gas_sensor) );
        humidityRH = (int)(bme680_humidity(gas_sensor) );
        
       /* dht22_read(23);
        pause(150);
        t1 = dht22_getTemp(1);
        temp1 = ((t1 *.10)-1.10);
        h1 = dht22_getHumidity();
        humid1 = (h1*.10); */  
        
        term_cmd(CLS);
        print("***Outside readings.***\r");
        print("%s%.2f\r", "Temperature (F) = ",temperatureF);
        print("%s%d\r", "Humidity (RH) = ",humidityRH);
        print("%s%.2f\r", "Pressure (inHg) = ",pressureinHg);
        print("%s%d\r", "Altitude (feet) = ",altitudeFeet);
        print("%s%d\r", "Gas Sensor (ohms) = ",gasSensor);
        /*print("***Sun room readings.***\r");
        print("%.2f Temperature (F)\r",temp1);
        print("%.2f Humidity\r",humid1);*/
        cm2302();
        pause(3000);
      }  
    }
    
    
    void cm2302()
    {
      float t1,h1,temp1,humid1;
      
        dht22_read(23);
        pause(150);
        t1 = dht22_getTemp(1);
        temp1 = ((t1 *.10)-1.10);
        h1 = dht22_getHumidity();
        humid1 = (h1*.10); 
    
        print("***Sun room readings.***\r");
        print("%.2f Temperature (F)\r",temp1);
        print("%.2f Humidity\r",humid1);  
    }  
    
  • JRoarkJRoark Posts: 1,215
    edited 2019-11-14 22:32
    From memory: this sensor returns the data in 1/10 degrees CENTIGRADE units. I dont see where you are making that conversion in the DHT22 temperature call. Is the temp you are getting proper if you use the C scale? :)
  • From memory: this sensor returns the data in 1/10 degrees CENTIGRADE units. I dont see where you are making that conversion in the DHT22 temperature call.
        t1 = dht22_getTemp(1);    // (1) = (F)
        temp1 = ((t1 *.10)-1.10);  // t1*.10  conversion
    

    I am also doing a needed temperature calibration (-1.10), to show the correct temperature.

    Ray
  • In the program below, I put the cm2302 code in its own COG, that seems to have fixed the problem. Still not sure what was causing the problem in the first place.

    I am still scratching my head on how to fix, or use correctly, the gas_sensor and altitude parts of the bme680 module.

    Ray

    /*
      flip_1.c
      http://learn.parallax.com/propeller-c-tutorials 
    */
    #include "simpletools.h"                      // Include simple tools
    #include "bme680.h"
    #include "dht22.h"
    
    volatile float temp1,humid1;
    
    bme680 *gas_sensor;
    double temperatureF;
    int humidityRH;
    double pressureinHg;
    int altitudeFeet;
    int gasSensor;
    
    void cm2302();
    
    int main()                                    // Main function
    {
      // Add startup code here.
      //float t1,h1,temp1,humid1;
      cog_run(cm2302,128);
      pause(150);
      /*                          SCK, SDI, SDO, CS */
      gas_sensor = bme680_openSPI(3,    2,   1,   0);  
     
      while(1)
      {
        // Add main loop code here.
        bme680_readSensor(gas_sensor);
        temperatureF = (double)(bme680_temperature(gas_sensor, FAHRENHEIT) );
        pressureinHg = (double)(bme680_pressure(gas_sensor, INHG) );
        altitudeFeet = (int)(bme680_altitude(gas_sensor, FEET) );
        gasSensor = (int)(bme680_gasResistance(gas_sensor) );
        humidityRH = (int)(bme680_humidity(gas_sensor) );
        
       /* dht22_read(23);
        pause(150);
        t1 = dht22_getTemp(1);
        temp1 = ((t1 *.10)-1.10);
        h1 = dht22_getHumidity();
        humid1 = (h1*.10); */  
        
        term_cmd(CLS);
        print("***Outside readings.***\r");
        print("%s%.2f\r", "Temperature (F) = ",temperatureF);
        print("%s%d\r", "Humidity (RH) = ",humidityRH);
        print("%s%.2f\r", "Pressure (inHg) = ",pressureinHg);
        print("%s%d\r", "Altitude (feet) = ",altitudeFeet);
        print("%s%d\r", "Gas Sensor (ohms) = ",gasSensor);
        print("***Sun room readings.***\r");
        print("%.2f Temperature (F)\r",temp1);
        print("%.2f Humidity\r",humid1);
        //cm2302();
        pause(3000);
      }  
    }
    
    
    /* COGed */
    void cm2302()
    {
      float t1,h1;
    
      while(1)
      { 
        dht22_read(23);
        pause(150);
        t1 = dht22_getTemp(1);
        temp1 = ((t1 *.10)-.10);
        h1 = dht22_getHumidity();
        humid1 = (h1*.10);
        pause(1000); 
      }  
        //print("***Sun room readings.***\r");
       //print("%.2f Temperature (F)\r",temp1);
        //print("%.2f Humidity\r",humid1);  
    } 
    
  • The BME680, which was outside all winter, survived some zero degree temperatures. So far I am satisfied with most of the functionality of the unit.

    I have noticed that there is no Spin code, or a decent way of working with the C lib, for the BME680. Now, considering that a functional P2 board for the layman is not available, still there will be a need for some P2 code to operate the BME680 unit.

    Ray
  • I bought one months ago with the intention of writing a SPIN driver for it, but it's one on a short list of my drivers/projects that are stalled - simply because of the math involved. The math itself, IIRC wasn't very complicated - it's just difficult (for me, anyway) to write in SPIN. It'd need about a thousand checks and checks again to implement using something like Float32 to make sure all of the parentheses are matched up, and some of the calculations overflow signed longs, so trying to just scale up the calcs and do it fixed-point style isn't easy, either. Every once in awhile I go back and chisel a little pebble off it, but it's slow going. If spin at least had a 64-bit integer variable size, I think this would be much easier to do in fixed-point.
    The only intermediate solution I could think of would be to write the lower-level driver stuff in fastspin and just keep the math ops in C. This may work, but I don't know how big the driver would be...i.e., would it all fit in a cog.
Sign In or Register to comment.