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.
  • 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


                            19

                            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