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

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

BME280 temp/humidity/pressure sensor

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

    Was modified in 2.1.1, you need to change

    metric = getConfig().isMetric;
    

    to

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

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

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

    Z 1 Reply Last reply
    2
    • Y yoshida

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

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

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

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

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

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

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

          Zbigniew Ko:

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

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

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

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

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

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

              alexsh1A 1 Reply Last reply
              0
              • gohanG gohan

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

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

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

                1 Reply Last reply
                0
                • B Offline
                  B Offline
                  bluezr1
                  wrote on last edited by
                  #25

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

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

                  Thanks,

                  Y 1 Reply Last reply
                  0
                  • B bluezr1

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

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

                    Thanks,

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

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

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

                    mfalkviddM 1 Reply Last reply
                    0
                    • Y yoshida

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

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

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

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

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

                      Y 1 Reply Last reply
                      0
                      • mfalkviddM mfalkvidd

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                            • Lightsensor A0
                            • No sleep (might want to enable repeater function later)
                            • Sends every 5 minute regardless of prevoius value (I use Domoticz and want to avoid red nodes and combined nodes).
                            • Fixed node it
                            // Enable debug prints to serial monitor
                            //#define MY_DEBUG 
                            
                            // Enable and select radio type attached
                            #define MY_RADIO_NRF24
                            //#define MY_RADIO_RFM69
                            
                            //Fixed ID/Parent?
                            #define MY_NODE_ID 20                     //To set a fixed ID for your node
                            //#define MY_PARENT_NODE_ID 100             //To set a fixed parent for this node
                            
                            #include <SPI.h>
                            #include <MySensors.h>  
                            #include <Wire.h>
                            
                            // BME280 libraries and variables
                            // Bosch BME280 Embedded Adventures MOD-1022 weather multi-sensor Arduino code
                            // Written originally by Embedded Adventures
                            // https://github.com/embeddedadventures/BME280
                            #include <BME280_MOD-1022.h>
                            
                            #define BARO_CHILD 0
                            #define TEMP_CHILD 1
                            #define HUM_CHILD 2
                            
                            long interval = 300000;           // interval at which to send (milliseconds)
                            long previousMillis = interval;        // will store last time data was sent
                            
                            const float ALTITUDE = 135; // <-- adapt this value to your location's altitude (in m). Use your smartphone GPS to get an accurate value!
                            
                            const char *weather[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
                            enum FORECAST
                            {
                              STABLE = 0,     // "Stable Weather Pattern"
                              SUNNY = 1,      // "Slowly rising Good Weather", "Clear/Sunny "
                              CLOUDY = 2,     // "Slowly falling L-Pressure ", "Cloudy/Rain "
                              UNSTABLE = 3,   // "Quickly rising H-Press",     "Not Stable"
                              THUNDERSTORM = 4, // "Quickly falling L-Press",    "Thunderstorm"
                              UNKNOWN = 5     // "Unknown (More Time needed)
                            };
                            
                            
                            const int LAST_SAMPLES_COUNT = 5;
                            float lastPressureSamples[LAST_SAMPLES_COUNT];
                            
                            
                            // this CONVERSION_FACTOR is used to convert from Pa to kPa in the forecast algorithm
                            // get kPa/h by dividing hPa by 10 
                            #define CONVERSION_FACTOR (1.0/10.0)
                            
                            int minuteCount = 0;
                            bool firstRound = true;
                            // average value is used in forecast algorithm.
                            float pressureAvg;
                            // average after 2 hours is used as reference value for the next iteration.
                            float pressureAvg2;
                            
                            float dP_dt;
                            boolean metric;
                            MyMessage tempMsg(TEMP_CHILD, V_TEMP);
                            MyMessage humMsg(HUM_CHILD, V_HUM);
                            MyMessage pressureMsg(BARO_CHILD, V_PRESSURE);
                            MyMessage forecastMsg(BARO_CHILD, V_FORECAST);
                            
                            //Light
                            #define CHILD_ID_LIGHT 3
                            #define LIGHT_SENSOR_ANALOG_PIN A0
                            MyMessage light_Msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
                            
                            
                            float getLastPressureSamplesAverage()
                            {
                              float lastPressureSamplesAverage = 0;
                              for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
                              {
                                lastPressureSamplesAverage += lastPressureSamples[i];
                              }
                              lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
                            
                              return lastPressureSamplesAverage;
                            }
                            
                            
                            // Algorithm found here
                            // http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf
                            // Pressure in hPa -->  forecast done by calculating kPa/h
                            int sample(float pressure)
                            {
                              // Calculate the average of the last n minutes.
                              int index = minuteCount % LAST_SAMPLES_COUNT;
                              lastPressureSamples[index] = pressure;
                            
                              minuteCount++;
                              if (minuteCount > 185)
                              {
                                minuteCount = 6;
                              }
                            
                              if (minuteCount == 5)
                              {
                                pressureAvg = getLastPressureSamplesAverage();
                              }
                              else if (minuteCount == 35)
                              {
                                float lastPressureAvg = getLastPressureSamplesAverage();
                                float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
                                if (firstRound) // first time initial 3 hour
                                {
                                  dP_dt = change * 2; // note this is for t = 0.5hour
                                }
                                else
                                {
                                  dP_dt = change / 1.5; // divide by 1.5 as this is the difference in time from 0 value.
                                }
                              }
                              else if (minuteCount == 65)
                              {
                                float lastPressureAvg = getLastPressureSamplesAverage();
                                float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
                                if (firstRound) //first time initial 3 hour
                                {
                                  dP_dt = change; //note this is for t = 1 hour
                                }
                                else
                                {
                                  dP_dt = change / 2; //divide by 2 as this is the difference in time from 0 value
                                }
                              }
                              else if (minuteCount == 95)
                              {
                                float lastPressureAvg = getLastPressureSamplesAverage();
                                float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
                                if (firstRound) // first time initial 3 hour
                                {
                                  dP_dt = change / 1.5; // note this is for t = 1.5 hour
                                }
                                else
                                {
                                  dP_dt = change / 2.5; // divide by 2.5 as this is the difference in time from 0 value
                                }
                              }
                              else if (minuteCount == 125)
                              {
                                float lastPressureAvg = getLastPressureSamplesAverage();
                                pressureAvg2 = lastPressureAvg; // store for later use.
                                float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
                                if (firstRound) // first time initial 3 hour
                                {
                                  dP_dt = change / 2; // note this is for t = 2 hour
                                }
                                else
                                {
                                  dP_dt = change / 3; // divide by 3 as this is the difference in time from 0 value
                                }
                              }
                              else if (minuteCount == 155)
                              {
                                float lastPressureAvg = getLastPressureSamplesAverage();
                                float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
                                if (firstRound) // first time initial 3 hour
                                {
                                  dP_dt = change / 2.5; // note this is for t = 2.5 hour
                                }
                                else
                                {
                                  dP_dt = change / 3.5; // divide by 3.5 as this is the difference in time from 0 value
                                }
                              }
                              else if (minuteCount == 185)
                              {
                                float lastPressureAvg = getLastPressureSamplesAverage();
                                float change = (lastPressureAvg - pressureAvg) * CONVERSION_FACTOR;
                                if (firstRound) // first time initial 3 hour
                                {
                                  dP_dt = change / 3; // note this is for t = 3 hour
                                }
                                else
                                {
                                  dP_dt = change / 4; // divide by 4 as this is the difference in time from 0 value
                                }
                                pressureAvg = pressureAvg2; // Equating the pressure at 0 to the pressure at 2 hour after 3 hours have past.
                                firstRound = false; // flag to let you know that this is on the past 3 hour mark. Initialized to 0 outside main loop.
                              }
                            
                              int forecast = UNKNOWN;
                              if (minuteCount < 35 && firstRound) //if time is less than 35 min on the first 3 hour interval.
                              {
                                forecast = UNKNOWN;
                              }
                              else if (dP_dt < (-0.25))
                              {
                                forecast = THUNDERSTORM;
                              }
                              else if (dP_dt > 0.25)
                              {
                                forecast = UNSTABLE;
                              }
                              else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
                              {
                                forecast = CLOUDY;
                              }
                              else if ((dP_dt > 0.05) && (dP_dt < 0.25))
                              {
                                forecast = SUNNY;
                              }
                              else if ((dP_dt >(-0.05)) && (dP_dt < 0.05))
                              {
                                forecast = STABLE;
                              }
                              else
                              {
                                forecast = UNKNOWN;
                              }
                            
                              // uncomment when debugging
                              //Serial.print(F("Forecast at minute "));
                              //Serial.print(minuteCount);
                              //Serial.print(F(" dP/dt = "));
                              //Serial.print(dP_dt);
                              //Serial.print(F("kPa/h --> "));
                              //Serial.println(weather[forecast]);
                            
                              return forecast;
                            }
                            
                            
                            void setup() {
                              metric = getControllerConfig().isMetric;  // was getConfig().isMetric; before MySensors v2.1.1
                              Wire.begin(); // Wire.begin(sda, scl)
                              // use the 1.1 V internal reference
                              #if defined(__AVR_ATmega2560__)
                              analogReference(INTERNAL1V1);
                              #else
                              analogReference(INTERNAL);
                              #endif
                            }
                            
                            void presentation()  {
                              // Send the sketch version information to the gateway and Controller
                              sendSketchInfo("WeatherStation #20", "1.0");
                            
                              // Register sensors to gw (they will be created as child devices)
                              present(BARO_CHILD, S_BARO);
                              present(TEMP_CHILD, S_TEMP);
                              present(HUM_CHILD, S_HUM);
                              present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
                            }
                            
                            // Loop
                            void loop() {
                            
                            unsigned long currentMillis = millis();  
                            
                            if(currentMillis - previousMillis > interval) {
                                // save the last time sent the data
                                previousMillis = currentMillis;
                            
                            
                              analogReference(DEFAULT);
                              wait(500);
                               readLightLevel();   //Read Light
                            
                              analogReference(INTERNAL);
                              wait(500);
                              
                              // need to read the NVM compensation parameters
                              BME280.readCompensationParams();
                            
                              // Normal mode for regular automatic samples
                              BME280.writeStandbyTime(tsb_0p5ms);         // tsb = 0.5ms
                              BME280.writeFilterCoefficient(fc_16);       // IIR Filter coefficient 16
                              BME280.writeOversamplingPressure(os16x);    // pressure x16
                              BME280.writeOversamplingTemperature(os8x);  // temperature x8
                              BME280.writeOversamplingHumidity(os8x);     // humidity x8
                              
                              BME280.writeMode(smNormal);
                            
                                // Just to be sure, wait until sensor is done mesuring  
                                while (BME280.isMeasuring()) {
                              }
                            
                              // Read out the data - must do this before calling the getxxxxx routines
                              BME280.readMeasurements();
                            
                              float temperature = BME280.getTemperatureMostAccurate();                    // must get temp first
                              float humidity = BME280.getHumidityMostAccurate();
                              float pressure_local = BME280.getPressureMostAccurate();                    // Get pressure at current location
                              float pressure = pressure_local/pow((1.0 - ( ALTITUDE / 44330.0 )), 5.255); // Adjust to sea level pressure using user altitude
                              int forecast = sample(pressure);
                            
                              if (!metric) 
                              {
                                // Convert to fahrenheit
                                temperature = temperature * 9.0 / 5.0 + 32.0;
                              }
                            
                              Serial.println();
                              Serial.print("Temperature = ");
                              Serial.print(temperature);
                              Serial.println(metric ? " °C" : " °F");
                              Serial.print("Humidity = ");
                              Serial.print(humidity);
                              Serial.println(" %");
                              Serial.print("Pressure = ");
                              Serial.print(pressure);
                              Serial.println(" hPa");
                              Serial.print("Forecast = ");
                              Serial.println(weather[forecast]);
                              Serial.println();
                            
                            
                                send(tempMsg.set(temperature, 1));
                            wait(50);
                                send(humMsg.set(humidity, 1));
                            wait(50);
                                send(pressureMsg.set(pressure, 2));
                            wait(50);
                                send(forecastMsg.set(weather[forecast]));
                            wait(50);
                            
                            }
                            }
                            
                            void readLightLevel()      {
                              Serial.println(analogRead(A0));  
                              int lightLevel = (1023 - analogRead(LIGHT_SENSOR_ANALOG_PIN)) / 10.23; //To get a value ranging from 0 (dark) to 100 (bright).
                            
                            #ifdef MY_DEBUG
                              Serial.print("Light: "); Serial.println(lightLevel);
                            #endif
                              send(light_Msg.set(lightLevel));
                            
                            }
                            

                            0_1506074720708_170922-IMG_20170922_103752.jpg

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

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

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

                              circuit card assembly

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


                              16

                              Online

                              11.7k

                              Users

                              11.2k

                              Topics

                              113.0k

                              Posts


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

                              • Don't have an account? Register

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