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

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

BME280 temp/humidity/pressure sensor

Scheduled Pinned Locked Moved Hardware
31 Posts 13 Posters 32.6k Views 17 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    anno
    wrote on last edited by anno
    #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


                          17

                          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