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.
  • 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
                  • B Offline
                    B Offline
                    bluezr1
                    wrote on last edited by
                    #25

                    I used the last sketch posed by Yoshida and for some reason whenever the temp and humidity goes through a stretch where there isn't any change, it's as if the node goes into a deep sleep and doesn't come out of it until I hit the reset on a pro mini.

                    I have it plunged in and not on batteries, so no need for any deep sleep. Is there anything I can change in the sketch? I'm still fairly new at this, although I'm having a blast.

                    Thanks,

                    Y 1 Reply Last reply
                    0
                    • B bluezr1

                      I used the last sketch posed by Yoshida and for some reason whenever the temp and humidity goes through a stretch where there isn't any change, it's as if the node goes into a deep sleep and doesn't come out of it until I hit the reset on a pro mini.

                      I have it plunged in and not on batteries, so no need for any deep sleep. Is there anything I can change in the sketch? I'm still fairly new at this, although I'm having a blast.

                      Thanks,

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

                      @bluezr1 Interesting... :) I used it with a pro mini as well, and my problem was that it ate up the batteries in 2 weeks... :D So I would need more deep sleep for the same sketch :D

                      But for that 2 weeks, it was working well. Temp/Hum/Baro updated every minute.

                      mfalkviddM 1 Reply Last reply
                      0
                      • Y yoshida

                        @bluezr1 Interesting... :) I used it with a pro mini as well, and my problem was that it ate up the batteries in 2 weeks... :D So I would need more deep sleep for the same sketch :D

                        But for that 2 weeks, it was working well. Temp/Hum/Baro updated every minute.

                        mfalkviddM Offline
                        mfalkviddM Offline
                        mfalkvidd
                        Mod
                        wrote on last edited by mfalkvidd
                        #27

                        @yoshida did you do the modifications (remove led and regulator) recommended at https://www.mysensors.org/build/battery ?

                        My storage room sensor (https://forum.mysensors.org/topic/7227/esp8266-wifi-gateway-with-rssi-for-rfm69-and-wifi ) uses the bme280. Not sure if that sketch is any help, but you are welcome to use it. It is much much simpler than the sketch posted above though.

                        Y 1 Reply Last reply
                        0
                        • mfalkviddM mfalkvidd

                          @yoshida did you do the modifications (remove led and regulator) recommended at https://www.mysensors.org/build/battery ?

                          My storage room sensor (https://forum.mysensors.org/topic/7227/esp8266-wifi-gateway-with-rssi-for-rfm69-and-wifi ) uses the bme280. Not sure if that sketch is any help, but you are welcome to use it. It is much much simpler than the sketch posted above though.

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

                          @mfalkvidd good question, yes I have removed the two leds I found, but I am too lame to remove the voltage regulator :( I have read here that the most consuming part is the LED(s)

                          1 Reply Last reply
                          1
                          • S Offline
                            S Offline
                            scalpel
                            wrote on last edited by gohan
                            #29

                            @yoshida said in BME280 temp/humidity/pressure sensor:

                            > /**
                            >  * 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);
                            >   
                            > }
                            > }
                            

                            Added to sketch @yoshida battery state send, but its not sending it, please chek it:

                            /**
                             * 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
                            
                            int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
                            int oldBatteryPcnt = 0;
                            
                            const float ALTITUDE = 450; // <-- 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 = 300000; 
                            
                            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)
                              // use the 1.1 V internal reference
                              #if defined(__AVR_ATmega2560__)
                              analogReference(INTERNAL1V1);
                              #else
                              analogReference(INTERNAL);
                              #endif
                            }
                            
                            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;
                              }
                            
                                int sensorValue = analogRead(BATTERY_SENSE_PIN);
                                int batteryPcnt = sensorValue / 10;
                                if (oldBatteryPcnt != batteryPcnt) {
                                // Power up radio after sleep
                                sendBatteryLevel(batteryPcnt);
                                oldBatteryPcnt = batteryPcnt;
                                }
                                
                              sleep(SLEEP_TIME);
                              
                            }
                            }
                            
                            sundberg84S 1 Reply Last reply
                            0
                            • S scalpel

                              @yoshida said in BME280 temp/humidity/pressure sensor:

                              > /**
                              >  * 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);
                              >   
                              > }
                              > }
                              

                              Added to sketch @yoshida battery state send, but its not sending it, please chek it:

                              /**
                               * 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
                              
                              int BATTERY_SENSE_PIN = A0; // select the input pin for the battery sense point
                              int oldBatteryPcnt = 0;
                              
                              const float ALTITUDE = 450; // <-- 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 = 300000; 
                              
                              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)
                                // use the 1.1 V internal reference
                                #if defined(__AVR_ATmega2560__)
                                analogReference(INTERNAL1V1);
                                #else
                                analogReference(INTERNAL);
                                #endif
                              }
                              
                              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;
                                }
                              
                                  int sensorValue = analogRead(BATTERY_SENSE_PIN);
                                  int batteryPcnt = sensorValue / 10;
                                  if (oldBatteryPcnt != batteryPcnt) {
                                  // Power up radio after sleep
                                  sendBatteryLevel(batteryPcnt);
                                  oldBatteryPcnt = batteryPcnt;
                                  }
                                  
                                sleep(SLEEP_TIME);
                                
                              }
                              }
                              
                              sundberg84S Offline
                              sundberg84S Offline
                              sundberg84
                              Hardware Contributor
                              wrote on last edited by
                              #30

                              @scalpel - works great! Thank you!!
                              Downloaded the library from the link in your sketch and up and running i no time.
                              Here is my sketch, with some modifications:

                              • Lightsensor A0
                              • No sleep (might want to enable repeater function later)
                              • Sends every 5 minute regardless of prevoius value (I use Domoticz and want to avoid red nodes and combined nodes).
                              • Fixed node it
                              // Enable debug prints to serial monitor
                              //#define MY_DEBUG 
                              
                              // Enable and select radio type attached
                              #define MY_RADIO_NRF24
                              //#define MY_RADIO_RFM69
                              
                              //Fixed ID/Parent?
                              #define MY_NODE_ID 20                     //To set a fixed ID for your node
                              //#define MY_PARENT_NODE_ID 100             //To set a fixed parent for this node
                              
                              #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
                              
                              long interval = 300000;           // interval at which to send (milliseconds)
                              long previousMillis = interval;        // will store last time data was sent
                              
                              const float ALTITUDE = 135; // <-- adapt this value to your location's altitude (in m). Use your smartphone GPS to get an accurate value!
                              
                              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)
                              };
                              
                              
                              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);
                              
                              //Light
                              #define CHILD_ID_LIGHT 3
                              #define LIGHT_SENSOR_ANALOG_PIN A0
                              MyMessage light_Msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
                              
                              
                              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)
                                // use the 1.1 V internal reference
                                #if defined(__AVR_ATmega2560__)
                                analogReference(INTERNAL1V1);
                                #else
                                analogReference(INTERNAL);
                                #endif
                              }
                              
                              void presentation()  {
                                // Send the sketch version information to the gateway and Controller
                                sendSketchInfo("WeatherStation #20", "1.0");
                              
                                // 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);
                                present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
                              }
                              
                              // Loop
                              void loop() {
                              
                              unsigned long currentMillis = millis();  
                              
                              if(currentMillis - previousMillis > interval) {
                                  // save the last time sent the data
                                  previousMillis = currentMillis;
                              
                              
                                analogReference(DEFAULT);
                                wait(500);
                                 readLightLevel();   //Read Light
                              
                                analogReference(INTERNAL);
                                wait(500);
                                
                                // need to read the NVM compensation parameters
                                BME280.readCompensationParams();
                              
                                // 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);
                              
                                  // 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();
                              
                              
                                  send(tempMsg.set(temperature, 1));
                              wait(50);
                                  send(humMsg.set(humidity, 1));
                              wait(50);
                                  send(pressureMsg.set(pressure, 2));
                              wait(50);
                                  send(forecastMsg.set(weather[forecast]));
                              wait(50);
                              
                              }
                              }
                              
                              void readLightLevel()      {
                                Serial.println(analogRead(A0));  
                                int lightLevel = (1023 - analogRead(LIGHT_SENSOR_ANALOG_PIN)) / 10.23; //To get a value ranging from 0 (dark) to 100 (bright).
                              
                              #ifdef MY_DEBUG
                                Serial.print("Light: "); Serial.println(lightLevel);
                              #endif
                                send(light_Msg.set(lightLevel));
                              
                              }
                              

                              0_1506074720708_170922-IMG_20170922_103752.jpg

                              Controller: Proxmox VM - Home Assistant
                              MySensors GW: Arduino Uno - W5100 Ethernet, Gw Shield Nrf24l01+ 2,4Ghz
                              MySensors GW: Arduino Uno - Gw Shield RFM69, 433mhz
                              RFLink GW - Arduino Mega + RFLink Shield, 433mhz

                              1 Reply Last reply
                              0
                              • R Offline
                                R Offline
                                RickyTerzis
                                wrote on last edited by RickyTerzis
                                #31

                                Hi...i am a new user here. I built a RFM69 gateway and a node.I decided to place the RFM69 node in a basement storage room. The room has been flooded a few times historically, so being able to monitor humidity in the room seems like a good idea.The room has thick brick walls, which the RFM69-433MHz radio is much more capable to handle than the nrf24. Still, I wanted to keep an eye on the signal strength. Because of this, I added code to the gateway to report RSSI from the node.

                                circuit card assembly

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


                                20

                                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