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 35.8k 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 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);
                            
                          }
                          }
                          
                          S 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);
                              
                            }
                            }
                            
                            S Offline
                            S 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

                              Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                              Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                              With your input, this post could be even better 💗

                              Register Login
                              Reply
                              • Reply as topic
                              Log in to reply
                              • Oldest to Newest
                              • Newest to Oldest
                              • Most Votes


                              14

                              Online

                              12.0k

                              Users

                              11.2k

                              Topics

                              113.4k

                              Posts


                              Copyright 2025 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