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.
  • E Offline
    E Offline
    emc2
    Hardware Contributor
    wrote on last edited by
    #16

    Was modified in 2.1.1, you need to change

    metric = getConfig().isMetric;
    

    to

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

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

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

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

      #ifndef __BME280_MOD-1022_H

                       ^
      

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

      #define __BME280_MOD-1022_H

                       ^
      

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

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

      #ifndef __BME280_MOD-1022_H

                       ^
      

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

      #define __BME280_MOD-1022_H

                       ^
      

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

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

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

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

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

      ^

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

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

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

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

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

      1 Reply Last reply
      0
      • E emc2

        Was modified in 2.1.1, you need to change

        metric = getConfig().isMetric;
        

        to

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

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

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

        Z 1 Reply Last reply
        2
        • Y yoshida

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

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

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

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

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

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

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

              Zbigniew Ko:

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

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

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

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

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

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

                  alexsh1A 1 Reply Last reply
                  0
                  • gohanG gohan

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

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

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

                    1 Reply Last reply
                    0
                    • 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