Skip to content
  • MySensors
  • OpenHardware.io
  • Categories
  • Recent
  • Tags
  • Popular
Skins
  • Light
  • Brite
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Brand Logo
  1. Home
  2. Hardware
  3. BME280 temp/humidity/pressure sensor

BME280 temp/humidity/pressure sensor

Scheduled Pinned Locked Moved Hardware
31 Posts 13 Posters 32.6k Views 17 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • signal15S signal15

    Has anyone built a node that uses the BME280 temp/humidity/pressure sensor?

    I'm guessing if I build it from scratch, the HumiditySensor example would probably be the best one to use. One thing I saw was that someone is working on an ESP8266 weather station gateway with this sensor, and in his comments, it appears that you have to do some funky stuff with moving the CE pin somewhere else or it interferes with the I2C communication for this chip. I would be doing this on a Nano, not an ESP. Are the pin changes the same?

    alexsh1A Offline
    alexsh1A Offline
    alexsh1
    wrote on last edited by
    #5

    @signal15
    I have this sensor working on Arduino Mini Pro. I am sure you can make it work under ESP8266

    1 Reply Last reply
    0
    • E emc2

      This should work, it removes the 2-3 ESP8266 config lines:

      /**
       * The MySensors Arduino library handles the wireless radio link and protocol
       * between your home built sensors/actuators and HA controller of choice.
       * The sensors forms a self healing radio network with optional repeaters. Each
       * repeater and gateway builds a routing tables in EEPROM which keeps track of the
       * network topology allowing messages to be routed to nodes.
       *
       * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
       * Copyright (C) 2013-2015 Sensnology AB
       * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
       *
       * Documentation: http://www.mysensors.org
       * Support Forum: http://forum.mysensors.org
       *
       * This program is free software; you can redistribute it and/or
       * modify it under the terms of the GNU General Public License
       * version 2 as published by the Free Software Foundation.
       *
       *******************************
       *
       * REVISION HISTORY
       * Version 1.0 - Henrik Ekblad
       * 
       * DESCRIPTION
       * Pressure sensor example using BMP085 module  
       * http://www.mysensors.org/build/pressure
       *
       */
      
      // Enable debug prints to serial monitor
      #define MY_DEBUG 
      
      // Enable and select radio type attached
      #define MY_RADIO_NRF24
      //#define MY_RADIO_RFM69
      
      #include <SPI.h>
      #include <MySensor.h>  
      #include <Wire.h>
      
      // BME280 libraries and variables
      // Bosch BME280 Embedded Adventures MOD-1022 weather multi-sensor Arduino code
      // Written originally by Embedded Adventures
      // https://github.com/embeddedadventures/BME280
      #include <BME280_MOD-1022.h>
      
      #define BARO_CHILD 0
      #define TEMP_CHILD 1
      #define HUM_CHILD 2
      
      const float ALTITUDE = 23; // <-- adapt this value to your location's altitude (in m). Use your smartphone GPS to get an accurate value!
      
      // Sleep time between reads (in ms). Do not change this value as the forecast algorithm needs a sample every minute.
      const unsigned long SLEEP_TIME = 60000; 
      
      const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
      enum FORECAST
      {
        STABLE = 0,     // "Stable Weather Pattern"
        SUNNY = 1,      // "Slowly rising Good Weather", "Clear/Sunny "
        CLOUDY = 2,     // "Slowly falling L-Pressure ", "Cloudy/Rain "
        UNSTABLE = 3,   // "Quickly rising H-Press",     "Not Stable"
        THUNDERSTORM = 4, // "Quickly falling L-Press",    "Thunderstorm"
        UNKNOWN = 5     // "Unknown (More Time needed)
      };
      
      float lastPressure = -1;
      float lastTemp = -1;
      float lastHum = -1;
      int lastForecast = -1;
      
      const int LAST_SAMPLES_COUNT = 5;
      float lastPressureSamples[LAST_SAMPLES_COUNT];
      
      
      // this CONVERSION_FACTOR is used to convert from Pa to kPa in the forecast algorithm
      // get kPa/h by dividing hPa by 10 
      #define CONVERSION_FACTOR (1.0/10.0)
      
      int minuteCount = 0;
      bool firstRound = true;
      // average value is used in forecast algorithm.
      float pressureAvg;
      // average after 2 hours is used as reference value for the next iteration.
      float pressureAvg2;
      
      float dP_dt;
      boolean metric;
      MyMessage tempMsg(TEMP_CHILD, V_TEMP);
      MyMessage humMsg(HUM_CHILD, V_HUM);
      MyMessage pressureMsg(BARO_CHILD, V_PRESSURE);
      MyMessage forecastMsg(BARO_CHILD, V_FORECAST);
      
      
      float getLastPressureSamplesAverage()
      {
        float lastPressureSamplesAverage = 0;
        for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
        {
          lastPressureSamplesAverage += lastPressureSamples[i];
        }
        lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
      
        return lastPressureSamplesAverage;
      }
      
      
      // Algorithm found here
      // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf
      // Pressure in hPa -->  forecast done by calculating kPa/h
      int sample(float pressure)
      {
        // Calculate the average of the last n minutes.
        int index = minuteCount % LAST_SAMPLES_COUNT;
        lastPressureSamples[index] = pressure;
      
        minuteCount++;
        if (minuteCount > 185)
        {
          minuteCount = 6;
        }
      
        if (minuteCount == 5)
        {
          pressureAvg = getLastPressureSamplesAverage();
        }
        else if (minuteCount == 35)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change * 2; // note this is for t = 0.5hour
          }
          else
          {
            dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value.
          }
        }
        else if (minuteCount == 65)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) //first time initial 3 hour
          {
            dP_dt = change; //note this is for t = 1 hour
          }
          else
          {
            dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value
          }
        }
        else if (minuteCount == 95)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change / 1.5; // note this is for t = 1.5 hour
          }
          else
          {
            dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value
          }
        }
        else if (minuteCount == 125)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          pressureAvg2 = lastPressureAvg; // store for later use.
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change / 2; // note this is for t = 2 hour
          }
          else
          {
            dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value
          }
        }
        else if (minuteCount == 155)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change / 2.5; // note this is for t = 2.5 hour
          }
          else
          {
            dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value
          }
        }
        else if (minuteCount == 185)
        {
          float lastPressureAvg = getLastPressureSamplesAverage();
          float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
          if (firstRound) // first time initial 3 hour
          {
            dP_dt = change / 3; // note this is for t = 3 hour
          }
          else
          {
            dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value
          }
          pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past.
          firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop.
        }
      
        int forecast = UNKNOWN;
        if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval.
        {
          forecast = UNKNOWN;
        }
        else if (dP_dt < (-0.25))
        {
          forecast = THUNDERSTORM;
        }
        else if (dP_dt > 0.25)
        {
          forecast = UNSTABLE;
        }
        else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
        {
          forecast = CLOUDY;
        }
        else if ((dP_dt > 0.05) && (dP_dt < 0.25))
        {
          forecast = SUNNY;
        }
        else if ((dP_dt >(-0.05)) && (dP_dt < 0.05))
        {
          forecast = STABLE;
        }
        else
        {
          forecast = UNKNOWN;
        }
      
        // uncomment when debugging
        //Serial.print(F("Forecast at minute "));
        //Serial.print(minuteCount);
        //Serial.print(F(" dP/dt = "));
        //Serial.print(dP_dt);
        //Serial.print(F("kPa/h --> "));
        //Serial.println(weather[forecast]);
      
        return forecast;
      }
      
      
      void setup() {
        metric = getConfig().isMetric;
        Wire.begin(); // Wire.begin(sda, scl)
      }
      
      void presentation()  {
        // Send the sketch version information to the gateway and Controller
        sendSketchInfo("BME280 Sensor", "1.6");
      
        // Register sensors to gw (they will be created as child devices)
        present(BARO_CHILD, S_BARO);
        present(TEMP_CHILD, S_TEMP);
        present(HUM_CHILD, S_HUM);
      }
      
      // Loop
      void loop() {
        
        // need to read the NVM compensation parameters
        BME280.readCompensationParams();
      
        /* After taking the measurement the chip goes back to sleep, use when battery powered.
        // Oversampling settings (os1x, os2x, os4x, os8x or os16x).
        BME280.writeFilterCoefficient(fc_16);       // IIR Filter coefficient, higher numbers avoid sudden changes to be accounted for (such as slamming a door)
        BME280.writeOversamplingPressure(os16x);    // pressure x16
        BME280.writeOversamplingTemperature(os8x);  // temperature x8
        BME280.writeOversamplingHumidity(os8x);     // humidity x8
      
        BME280.writeMode(smForced);                 // Forced sample.  After taking the measurement the chip goes back to sleep
        */
      
        // Normal mode for regular automatic samples
        BME280.writeStandbyTime(tsb_0p5ms);         // tsb = 0.5ms
        BME280.writeFilterCoefficient(fc_16);       // IIR Filter coefficient 16
        BME280.writeOversamplingPressure(os16x);    // pressure x16
        BME280.writeOversamplingTemperature(os8x);  // temperature x8
        BME280.writeOversamplingHumidity(os8x);     // humidity x8
        
        BME280.writeMode(smNormal);
        
        while (1) {
          // Just to be sure, wait until sensor is done mesuring  
          while (BME280.isMeasuring()) {
        }
        
        // Read out the data - must do this before calling the getxxxxx routines
        BME280.readMeasurements();
      
        float temperature = BME280.getTemperatureMostAccurate();                    // must get temp first
        float humidity = BME280.getHumidityMostAccurate();
        float pressure_local = BME280.getPressureMostAccurate();                    // Get pressure at current location
        float pressure = pressure_local/pow((1.0 - ( ALTITUDE / 44330.0 )), 5.255); // Adjust to sea level pressure using user altitude
        int forecast = sample(pressure);
        
        if (!metric) 
        {
          // Convert to fahrenheit
          temperature = temperature * 9.0 / 5.0 + 32.0;
        }
      
        Serial.println();
        Serial.print("Temperature = ");
        Serial.print(temperature);
        Serial.println(metric ? " °C" : " °F");
        Serial.print("Humidity = ");
        Serial.print(humidity);
        Serial.println(" %");
        Serial.print("Pressure = ");
        Serial.print(pressure);
        Serial.println(" hPa");
        Serial.print("Forecast = ");
        Serial.println(weather[forecast]);
        Serial.println();
      
      
        if (temperature != lastTemp) 
        {
          send(tempMsg.set(temperature, 1));
          lastTemp = temperature;
        }
      
      
        if (humidity != lastHum) 
        {
          send(humMsg.set(humidity, 1));
          lastHum = humidity;
        }
      
        if (pressure != lastPressure) 
        {
          send(pressureMsg.set(pressure, 2));
          lastPressure = pressure;
        }
      
        if (forecast != lastForecast)
        {
          send(forecastMsg.set(weather[forecast]));
          lastForecast = forecast;
        }
        
        sleep(SLEEP_TIME);
        
      }
      }```
      signal15S Offline
      signal15S Offline
      signal15
      wrote on last edited by
      #6

      @emc2

      I'm getting some problems compiling the code you provided above. Is this for 1.6 or something? I'm on 1.5, do I need to change some function names?

      Arduino/Mysensors_BME280/Mysensors_BME280.ino: In function 'void setup()':
      Mysensors_BME280:252: error: 'getConfig' was not declared in this scope
         metric = getConfig().isMetric;
                            ^
      /Users/jay.austad/Documents/Arduino/Mysensors_BME280/Mysensors_BME280.ino: In function 'void presentation()':
      Mysensors_BME280:258: error: 'sendSketchInfo' was not declared in this scope
         sendSketchInfo("BME280 Sensor", "1.6");
                                              ^
      Mysensors_BME280:261: error: 'present' was not declared in this scope
         present(BARO_CHILD, S_BARO);
                                   ^
      /Users/jay.austad/Documents/Arduino/Mysensors_BME280/Mysensors_BME280.ino: In function 'void loop()':
      Mysensors_BME280:328: error: 'send' was not declared in this scope
           send(tempMsg.set(temperature, 1));
                                           ^
      Mysensors_BME280:335: error: 'send' was not declared in this scope
           send(humMsg.set(humidity, 1));
                                       ^
      Mysensors_BME280:341: error: 'send' was not declared in this scope
           send(pressureMsg.set(pressure, 2));
                                            ^
      Mysensors_BME280:347: error: 'send' was not declared in this scope
           send(forecastMsg.set(weather[forecast]));
                                                  ^
      Mysensors_BME280:351: error: 'sleep' was not declared in this scope
         sleep(SLEEP_TIME);
                         ^
      exit status 1
      'getConfig' was not declared in this scope```
      1 Reply Last reply
      0
      • signal15S Offline
        signal15S Offline
        signal15
        wrote on last edited by signal15
        #7

        Ah, looks like I just need to add "gw." in front of all of these functions and "MySensor gw;" just after the includes.

        1 Reply Last reply
        0
        • E Offline
          E Offline
          emc2
          Hardware Contributor
          wrote on last edited by
          #8

          Ah yes sorry, it's for the dev branch (1.6 or now called 2.0)

          signal15S 1 Reply Last reply
          0
          • E emc2

            Ah yes sorry, it's for the dev branch (1.6 or now called 2.0)

            signal15S Offline
            signal15S Offline
            signal15
            wrote on last edited by
            #9

            @emc2

            Eh, looks like there's a lot more that I have to do to get this working, like moving the presentation into the setup() function.

            1 Reply Last reply
            0
            • E Offline
              E Offline
              emc2
              Hardware Contributor
              wrote on last edited by
              #10

              If you are using 1.5 probably a lot more.

              Easier to install 2.0, compile and upload. It will be compatible with your 1.5 gateway anyway.

              signal15S 1 Reply Last reply
              0
              • E emc2

                If you are using 1.5 probably a lot more.

                Easier to install 2.0, compile and upload. It will be compatible with your 1.5 gateway anyway.

                signal15S Offline
                signal15S Offline
                signal15
                wrote on last edited by
                #11

                @emc2

                Oh, I thought that you had to upgrade the gateway as well. If that's the case, then I'll grab 2.0. Do I just go to the dev branch in github and hit download ZIP?

                1 Reply Last reply
                0
                • signal15S Offline
                  signal15S Offline
                  signal15
                  wrote on last edited by signal15
                  #12

                  Do you have to upgrade the files on the controller to 2.0b as well? I have a vera, and when I added this new sensor on 2.0b, all of my nodes stopped updating and the tiles for them on the Devices screen doesn't list anything about the sensor like it normally does.

                  I get these errors in the Vera logs:

                  02	05/06/16 18:54:40.167	Device_Service::MatchupUpnpServices no upnp service for urn:upnp-arduino-cc:serviceId:arduino1 <0x2ac17000>
                  02	05/06/16 18:54:40.170	Device_Service::MatchupUpnpServices no upnp service for urn:upnp-arduino-cc:serviceId:arduinonode1 <0x2ac17000>
                  02	05/06/16 18:54:40.171	Device_Service::MatchupUpnpServices no upnp service for urn:upnp-arduino-cc:serviceId:arduinonode1 <0x2ac17000>```
                  

                  Also, the MySensors parent device disappeared from my Devices page in Vera. If I telnet to my gateway on port 5003, I only see the new sensor reporting as well, not any of my other sensors. Did the 2.0b sensor do something bad to my gateway or the Vera plugin?

                  Update: I deleted the new devices created from the 2.0b sensor in my Vera. This fixed it so the other node information showed up again, and the MySensors parent device showed up. But, my 1.5 sensors were no longer updating. I restarted them, and they started updating.

                  If 2.0 sensors are designed to be backwards compatible with a 1.5 gateway and 1.5 controller code, then there's a problem somewhere. Maybe it's with the Vera code. But, like I said, I telneted to port 5003 on my gateway, and the only thing that the gateway was receiving was the data from my 2.0b sensor. Either the gateway was ignoring the 1.5 sensors, or the 1.5 sensors stopped sending for some reason.

                  Thoughts?

                  1 Reply Last reply
                  0
                  • hekH Offline
                    hekH Offline
                    hek
                    Admin
                    wrote on last edited by
                    #13

                    Hmm.. I wonder if this change might have interfered with the Vera plugin.

                    https://github.com/mysensors/Arduino/commit/bbc6a221f4c153f41993207e521f5531ba853d1a

                    https://github.com/mysensors/Arduino/pull/420

                    signal15S 1 Reply Last reply
                    0
                    • hekH hek

                      Hmm.. I wonder if this change might have interfered with the Vera plugin.

                      https://github.com/mysensors/Arduino/commit/bbc6a221f4c153f41993207e521f5531ba853d1a

                      https://github.com/mysensors/Arduino/pull/420

                      signal15S Offline
                      signal15S Offline
                      signal15
                      wrote on last edited by
                      #14

                      @hek

                      Let me know if you make a change and need me to test.

                      1 Reply Last reply
                      0
                      • signal15S signal15

                        Awesome. I just got it working with a test sketch like 2 minutes ago. If I get a working sketch for MySensors, how can I get it uploaded to the site as an example?

                        Also, if anyone has done it before, I'd appreciate any code you might have to save some time. I only get like 5 minutes here an there to work on this.

                        Y Offline
                        Y Offline
                        yoshida
                        wrote on last edited by
                        #15

                        @emc2 or anybody:

                        Does anyone have a working BME280 mysensors arduino sketch? The code above states include mysensor.h now it is mysensorS.h, so I have renamed, but it won't compile, it says:

                        In function 'void setup()':
                        
                        bme280:252: error: 'getConfig' was not declared in this scope
                        

                        I have a MySensors Gateway USB
                        Version: 2.1.1 (arduino nano) with Domoticz, and I would like to use the bme280 for a battery powered outdoor temp/humidity/barometer (as DHT22 does not like battery level below 3.3V, and I would run on 2x1.5V AA)

                        Thanks

                        1 Reply Last reply
                        0
                        • E Offline
                          E Offline
                          emc2
                          Hardware Contributor
                          wrote on last edited by
                          #16

                          Was modified in 2.1.1, you need to change

                          metric = getConfig().isMetric;
                          

                          to

                          metric = getControllerConfig().isMetric;  // was getConfig().isMetric; before MySensors v2.1.1
                          
                          Y 1 Reply Last reply
                          1
                          • A Offline
                            A Offline
                            anno
                            wrote on last edited by anno
                            #17

                            Still a lot of errors in this sketch, did take some out but this is still in it:

                            In file included from C:\Users\x\Documents\Arduino\BME280_sensor\BME280_sensor.ino:48:0:

                            C:\Users\x\Documents\Arduino\libraries\BME280/BME280_MOD-1022.h:41:21: warning: extra tokens at end of #ifndef directive

                            #ifndef __BME280_MOD-1022_H

                                             ^
                            

                            C:\Users\x\Documents\Arduino\libraries\BME280/BME280_MOD-1022.h:42:21: warning: ISO C99 requires whitespace after the macro name

                            #define __BME280_MOD-1022_H

                                             ^
                            

                            In file included from C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.cpp:40:0:

                            C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.h:41:21: warning: extra tokens at end of #ifndef directive

                            #ifndef __BME280_MOD-1022_H

                                             ^
                            

                            C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.h:42:21: warning: ISO C99 requires whitespace after the macro name

                            #define __BME280_MOD-1022_H

                                             ^
                            

                            C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.cpp: In member function 'BME280Class::readCompensationParams()':

                            C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.cpp:276:45: warning: iteration 20 invokes undefined behavior [-Waggressive-loop-optimizations]

                            compParams.compArray[count] = Wire.read();
                            
                                                                     ^
                            

                            C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.cpp:275:3: note: containing loop

                            for (count = 0; count < 28; count++) { // first 28 bytes we can process like this

                            ^

                            C:\Users\x\Documents\Arduino\BME280_sensor\BME280_sensor.ino: In function 'loop':

                            C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.cpp:276:45: warning: iteration 20 invokes undefined behavior [-Waggressive-loop-optimizations]

                            compParams.compArray[count] = Wire.read();
                            
                                                                     ^
                            

                            C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.cpp:275:3: note: containing loop

                            for (count = 0; count < 28; count++) { // first 28 bytes we can process like this

                            1 Reply Last reply
                            0
                            • E emc2

                              Was modified in 2.1.1, you need to change

                              metric = getConfig().isMetric;
                              

                              to

                              metric = getControllerConfig().isMetric;  // was getConfig().isMetric; before MySensors v2.1.1
                              
                              Y Offline
                              Y Offline
                              yoshida
                              wrote on last edited by
                              #18

                              @emc2 Thanks! With this modification the sketch compiled successfully. Today I had time, so put everything together, and the BME280 works with the 2.4GH radio, temp/hum/pressure all reporting like they should.

                              Using arduino pro mini, bme280, nrf24, 2XAA Batteries. It reports to the mysensors serial gw, and then shown in domoticz.

                              Z 1 Reply Last reply
                              2
                              • Y yoshida

                                @emc2 Thanks! With this modification the sketch compiled successfully. Today I had time, so put everything together, and the BME280 works with the 2.4GH radio, temp/hum/pressure all reporting like they should.

                                Using arduino pro mini, bme280, nrf24, 2XAA Batteries. It reports to the mysensors serial gw, and then shown in domoticz.

                                Z Offline
                                Z Offline
                                Zbigniew Ko
                                wrote on last edited by
                                #19

                                @yoshida Hello
                                You can share your sketch.
                                Please
                                I can not make modifications.
                                I still have a lot of errors.

                                Y 1 Reply Last reply
                                0
                                • A Offline
                                  A Offline
                                  anno
                                  wrote on last edited by anno
                                  #20
                                  This post is deleted!
                                  1 Reply Last reply
                                  0
                                  • Z Zbigniew Ko

                                    @yoshida Hello
                                    You can share your sketch.
                                    Please
                                    I can not make modifications.
                                    I still have a lot of errors.

                                    Y Offline
                                    Y Offline
                                    yoshida
                                    wrote on last edited by
                                    #21

                                    Zbigniew Ko:

                                    (2.1.1 mysensors compatible, but first you need to install the BME280_MOD-1022.h library in arduino IDE)

                                    /**
                                     * The MySensors Arduino library handles the wireless radio link and protocol
                                     * between your home built sensors/actuators and HA controller of choice.
                                     * The sensors forms a self healing radio network with optional repeaters. Each
                                     * repeater and gateway builds a routing tables in EEPROM which keeps track of the
                                     * network topology allowing messages to be routed to nodes.
                                     *
                                     * Created by Henrik Ekblad <henrik.ekblad@mysensors.org>
                                     * Copyright (C) 2013-2015 Sensnology AB
                                     * Full contributor list: https://github.com/mysensors/Arduino/graphs/contributors
                                     *
                                     * Documentation: http://www.mysensors.org
                                     * Support Forum: http://forum.mysensors.org
                                     *
                                     * This program is free software; you can redistribute it and/or
                                     * modify it under the terms of the GNU General Public License
                                     * version 2 as published by the Free Software Foundation.
                                     *
                                     *******************************
                                     *
                                     * REVISION HISTORY
                                     * Version 1.0 - Henrik Ekblad
                                     * 
                                     * DESCRIPTION
                                     * Pressure sensor example using BMP085 module  
                                     * http://www.mysensors.org/build/pressure
                                     *
                                     */
                                    
                                    // Enable debug prints to serial monitor
                                    #define MY_DEBUG 
                                    
                                    // Enable and select radio type attached
                                    #define MY_RADIO_NRF24
                                    //#define MY_RADIO_RFM69
                                    
                                    #include <SPI.h>
                                    #include <MySensors.h>  
                                    #include <Wire.h>
                                    
                                    // BME280 libraries and variables
                                    // Bosch BME280 Embedded Adventures MOD-1022 weather multi-sensor Arduino code
                                    // Written originally by Embedded Adventures
                                    // https://github.com/embeddedadventures/BME280
                                    #include <BME280_MOD-1022.h>
                                    
                                    #define BARO_CHILD 0
                                    #define TEMP_CHILD 1
                                    #define HUM_CHILD 2
                                    
                                    const float ALTITUDE = 184; // <-- adapt this value to your location's altitude (in m). Use your smartphone GPS to get an accurate value!
                                    
                                    // Sleep time between reads (in ms). Do not change this value as the forecast algorithm needs a sample every minute.
                                    const unsigned long SLEEP_TIME = 60000; 
                                    
                                    const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
                                    enum FORECAST
                                    {
                                      STABLE = 0,     // "Stable Weather Pattern"
                                      SUNNY = 1,      // "Slowly rising Good Weather", "Clear/Sunny "
                                      CLOUDY = 2,     // "Slowly falling L-Pressure ", "Cloudy/Rain "
                                      UNSTABLE = 3,   // "Quickly rising H-Press",     "Not Stable"
                                      THUNDERSTORM = 4, // "Quickly falling L-Press",    "Thunderstorm"
                                      UNKNOWN = 5     // "Unknown (More Time needed)
                                    };
                                    
                                    float lastPressure = -1;
                                    float lastTemp = -1;
                                    float lastHum = -1;
                                    int lastForecast = -1;
                                    
                                    const int LAST_SAMPLES_COUNT = 5;
                                    float lastPressureSamples[LAST_SAMPLES_COUNT];
                                    
                                    
                                    // this CONVERSION_FACTOR is used to convert from Pa to kPa in the forecast algorithm
                                    // get kPa/h by dividing hPa by 10 
                                    #define CONVERSION_FACTOR (1.0/10.0)
                                    
                                    int minuteCount = 0;
                                    bool firstRound = true;
                                    // average value is used in forecast algorithm.
                                    float pressureAvg;
                                    // average after 2 hours is used as reference value for the next iteration.
                                    float pressureAvg2;
                                    
                                    float dP_dt;
                                    boolean metric;
                                    MyMessage tempMsg(TEMP_CHILD, V_TEMP);
                                    MyMessage humMsg(HUM_CHILD, V_HUM);
                                    MyMessage pressureMsg(BARO_CHILD, V_PRESSURE);
                                    MyMessage forecastMsg(BARO_CHILD, V_FORECAST);
                                    
                                    
                                    float getLastPressureSamplesAverage()
                                    {
                                      float lastPressureSamplesAverage = 0;
                                      for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
                                      {
                                        lastPressureSamplesAverage += lastPressureSamples[i];
                                      }
                                      lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
                                    
                                      return lastPressureSamplesAverage;
                                    }
                                    
                                    
                                    // Algorithm found here
                                    // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf
                                    // Pressure in hPa -->  forecast done by calculating kPa/h
                                    int sample(float pressure)
                                    {
                                      // Calculate the average of the last n minutes.
                                      int index = minuteCount % LAST_SAMPLES_COUNT;
                                      lastPressureSamples[index] = pressure;
                                    
                                      minuteCount++;
                                      if (minuteCount > 185)
                                      {
                                        minuteCount = 6;
                                      }
                                    
                                      if (minuteCount == 5)
                                      {
                                        pressureAvg = getLastPressureSamplesAverage();
                                      }
                                      else if (minuteCount == 35)
                                      {
                                        float lastPressureAvg = getLastPressureSamplesAverage();
                                        float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
                                        if (firstRound) // first time initial 3 hour
                                        {
                                          dP_dt = change * 2; // note this is for t = 0.5hour
                                        }
                                        else
                                        {
                                          dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value.
                                        }
                                      }
                                      else if (minuteCount == 65)
                                      {
                                        float lastPressureAvg = getLastPressureSamplesAverage();
                                        float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
                                        if (firstRound) //first time initial 3 hour
                                        {
                                          dP_dt = change; //note this is for t = 1 hour
                                        }
                                        else
                                        {
                                          dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value
                                        }
                                      }
                                      else if (minuteCount == 95)
                                      {
                                        float lastPressureAvg = getLastPressureSamplesAverage();
                                        float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
                                        if (firstRound) // first time initial 3 hour
                                        {
                                          dP_dt = change / 1.5; // note this is for t = 1.5 hour
                                        }
                                        else
                                        {
                                          dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value
                                        }
                                      }
                                      else if (minuteCount == 125)
                                      {
                                        float lastPressureAvg = getLastPressureSamplesAverage();
                                        pressureAvg2 = lastPressureAvg; // store for later use.
                                        float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
                                        if (firstRound) // first time initial 3 hour
                                        {
                                          dP_dt = change / 2; // note this is for t = 2 hour
                                        }
                                        else
                                        {
                                          dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value
                                        }
                                      }
                                      else if (minuteCount == 155)
                                      {
                                        float lastPressureAvg = getLastPressureSamplesAverage();
                                        float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
                                        if (firstRound) // first time initial 3 hour
                                        {
                                          dP_dt = change / 2.5; // note this is for t = 2.5 hour
                                        }
                                        else
                                        {
                                          dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value
                                        }
                                      }
                                      else if (minuteCount == 185)
                                      {
                                        float lastPressureAvg = getLastPressureSamplesAverage();
                                        float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
                                        if (firstRound) // first time initial 3 hour
                                        {
                                          dP_dt = change / 3; // note this is for t = 3 hour
                                        }
                                        else
                                        {
                                          dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value
                                        }
                                        pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past.
                                        firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop.
                                      }
                                    
                                      int forecast = UNKNOWN;
                                      if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval.
                                      {
                                        forecast = UNKNOWN;
                                      }
                                      else if (dP_dt < (-0.25))
                                      {
                                        forecast = THUNDERSTORM;
                                      }
                                      else if (dP_dt > 0.25)
                                      {
                                        forecast = UNSTABLE;
                                      }
                                      else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
                                      {
                                        forecast = CLOUDY;
                                      }
                                      else if ((dP_dt > 0.05) && (dP_dt < 0.25))
                                      {
                                        forecast = SUNNY;
                                      }
                                      else if ((dP_dt >(-0.05)) && (dP_dt < 0.05))
                                      {
                                        forecast = STABLE;
                                      }
                                      else
                                      {
                                        forecast = UNKNOWN;
                                      }
                                    
                                      // uncomment when debugging
                                      //Serial.print(F("Forecast at minute "));
                                      //Serial.print(minuteCount);
                                      //Serial.print(F(" dP/dt = "));
                                      //Serial.print(dP_dt);
                                      //Serial.print(F("kPa/h --> "));
                                      //Serial.println(weather[forecast]);
                                    
                                      return forecast;
                                    }
                                    
                                    
                                    void setup() {
                                      metric = getControllerConfig().isMetric;  // was getConfig().isMetric; before MySensors v2.1.1
                                      Wire.begin(); // Wire.begin(sda, scl)
                                    }
                                    
                                    void presentation()  {
                                      // Send the sketch version information to the gateway and Controller
                                      sendSketchInfo("BME280 Sensor", "1.6");
                                    
                                      // Register sensors to gw (they will be created as child devices)
                                      present(BARO_CHILD, S_BARO);
                                      present(TEMP_CHILD, S_TEMP);
                                      present(HUM_CHILD, S_HUM);
                                    }
                                    
                                    // Loop
                                    void loop() {
                                      
                                      // need to read the NVM compensation parameters
                                      BME280.readCompensationParams();
                                    
                                      /* After taking the measurement the chip goes back to sleep, use when battery powered.
                                      // Oversampling settings (os1x, os2x, os4x, os8x or os16x).
                                      BME280.writeFilterCoefficient(fc_16);       // IIR Filter coefficient, higher numbers avoid sudden changes to be accounted for (such as slamming a door)
                                      BME280.writeOversamplingPressure(os16x);    // pressure x16
                                      BME280.writeOversamplingTemperature(os8x);  // temperature x8
                                      BME280.writeOversamplingHumidity(os8x);     // humidity x8
                                    
                                      BME280.writeMode(smForced);                 // Forced sample.  After taking the measurement the chip goes back to sleep
                                      */
                                    
                                      // Normal mode for regular automatic samples
                                      BME280.writeStandbyTime(tsb_0p5ms);         // tsb = 0.5ms
                                      BME280.writeFilterCoefficient(fc_16);       // IIR Filter coefficient 16
                                      BME280.writeOversamplingPressure(os16x);    // pressure x16
                                      BME280.writeOversamplingTemperature(os8x);  // temperature x8
                                      BME280.writeOversamplingHumidity(os8x);     // humidity x8
                                      
                                      BME280.writeMode(smNormal);
                                      
                                      while (1) {
                                        // Just to be sure, wait until sensor is done mesuring  
                                        while (BME280.isMeasuring()) {
                                      }
                                      
                                      // Read out the data - must do this before calling the getxxxxx routines
                                      BME280.readMeasurements();
                                    
                                      float temperature = BME280.getTemperatureMostAccurate();                    // must get temp first
                                      float humidity = BME280.getHumidityMostAccurate();
                                      float pressure_local = BME280.getPressureMostAccurate();                    // Get pressure at current location
                                      float pressure = pressure_local/pow((1.0 - ( ALTITUDE / 44330.0 )), 5.255); // Adjust to sea level pressure using user altitude
                                      int forecast = sample(pressure);
                                      
                                      if (!metric) 
                                      {
                                        // Convert to fahrenheit
                                        temperature = temperature * 9.0 / 5.0 + 32.0;
                                      }
                                    
                                      Serial.println();
                                      Serial.print("Temperature = ");
                                      Serial.print(temperature);
                                      Serial.println(metric ? " °C" : " °F");
                                      Serial.print("Humidity = ");
                                      Serial.print(humidity);
                                      Serial.println(" %");
                                      Serial.print("Pressure = ");
                                      Serial.print(pressure);
                                      Serial.println(" hPa");
                                      Serial.print("Forecast = ");
                                      Serial.println(weather[forecast]);
                                      Serial.println();
                                    
                                    
                                      if (temperature != lastTemp) 
                                      {
                                        send(tempMsg.set(temperature, 1));
                                        lastTemp = temperature;
                                      }
                                    
                                    
                                      if (humidity != lastHum) 
                                      {
                                        send(humMsg.set(humidity, 1));
                                        lastHum = humidity;
                                      }
                                    
                                      if (pressure != lastPressure) 
                                      {
                                        send(pressureMsg.set(pressure, 2));
                                        lastPressure = pressure;
                                      }
                                    
                                      if (forecast != lastForecast)
                                      {
                                        send(forecastMsg.set(weather[forecast]));
                                        lastForecast = forecast;
                                      }
                                      
                                      sleep(SLEEP_TIME);
                                      
                                    }
                                    }
                                    
                                    
                                    1 Reply Last reply
                                    0
                                    • Z Offline
                                      Z Offline
                                      Zbigniew Ko
                                      wrote on last edited by Zbigniew Ko
                                      #22

                                      @yoshida Thank you very much.
                                      As soon as I find time I will check it out.

                                      Yes checked, sketch works.
                                      Thanks yoshida.
                                      Please note that the library BME_MOD-1022.h consists of two parts: file-h, and file cpp.

                                      1 Reply Last reply
                                      0
                                      • gohanG Offline
                                        gohanG Offline
                                        gohan
                                        Mod
                                        wrote on last edited by
                                        #23

                                        I am using the one from adafruit : what's the difference with this other library?

                                        alexsh1A 1 Reply Last reply
                                        0
                                        • gohanG gohan

                                          I am using the one from adafruit : what's the difference with this other library?

                                          alexsh1A Offline
                                          alexsh1A Offline
                                          alexsh1
                                          wrote on last edited by
                                          #24

                                          @gohan I have been using both libraries with a chinese module I bought from Aliexpress. I did not notice any differences apart from size and maybe a module address, which you can change in either library.

                                          1 Reply Last reply
                                          0
                                          Reply
                                          • Reply as topic
                                          Log in to reply
                                          • Oldest to Newest
                                          • Newest to Oldest
                                          • Most Votes


                                          12

                                          Online

                                          11.7k

                                          Users

                                          11.2k

                                          Topics

                                          113.0k

                                          Posts


                                          Copyright 2019 TBD   |   Forum Guidelines   |   Privacy Policy   |   Terms of Service
                                          • Login

                                          • Don't have an account? Register

                                          • Login or register to search.
                                          • First post
                                            Last post
                                          0
                                          • MySensors
                                          • OpenHardware.io
                                          • Categories
                                          • Recent
                                          • Tags
                                          • Popular