Skip to content
  • 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
  • Getting Started
  • Controller
  • Build
  • Hardware
  • Download/API
  • Forum
  • Store

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


                        5

                        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
                        • OpenHardware.io
                        • Categories
                        • Recent
                        • Tags
                        • Popular