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

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

BME280 temp/humidity/pressure sensor

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

    Awesome. I just got it working with a test sketch like 2 minutes ago. If I get a working sketch for MySensors, how can I get it uploaded to the site as an example?

    Also, if anyone has done it before, I'd appreciate any code you might have to save some time. I only get like 5 minutes here an there to work on this.

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

    @emc2 or anybody:

    Does anyone have a working BME280 mysensors arduino sketch? The code above states include mysensor.h now it is mysensorS.h, so I have renamed, but it won't compile, it says:

    In function 'void setup()':
    
    bme280:252: error: 'getConfig' was not declared in this scope
    

    I have a MySensors Gateway USB
    Version: 2.1.1 (arduino nano) with Domoticz, and I would like to use the bme280 for a battery powered outdoor temp/humidity/barometer (as DHT22 does not like battery level below 3.3V, and I would run on 2x1.5V AA)

    Thanks

    1 Reply Last reply
    0
    • E Offline
      E Offline
      emc2
      Hardware Contributor
      wrote on last edited by
      #16

      Was modified in 2.1.1, you need to change

      metric = getConfig().isMetric;
      

      to

      metric = getControllerConfig().isMetric;  // was getConfig().isMetric; before MySensors v2.1.1
      
      Y 1 Reply Last reply
      1
      • A Offline
        A Offline
        anno
        wrote on last edited by anno
        #17

        Still a lot of errors in this sketch, did take some out but this is still in it:

        In file included from C:\Users\x\Documents\Arduino\BME280_sensor\BME280_sensor.ino:48:0:

        C:\Users\x\Documents\Arduino\libraries\BME280/BME280_MOD-1022.h:41:21: warning: extra tokens at end of #ifndef directive

        #ifndef __BME280_MOD-1022_H

                         ^
        

        C:\Users\x\Documents\Arduino\libraries\BME280/BME280_MOD-1022.h:42:21: warning: ISO C99 requires whitespace after the macro name

        #define __BME280_MOD-1022_H

                         ^
        

        In file included from C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.cpp:40:0:

        C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.h:41:21: warning: extra tokens at end of #ifndef directive

        #ifndef __BME280_MOD-1022_H

                         ^
        

        C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.h:42:21: warning: ISO C99 requires whitespace after the macro name

        #define __BME280_MOD-1022_H

                         ^
        

        C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.cpp: In member function 'BME280Class::readCompensationParams()':

        C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.cpp:276:45: warning: iteration 20 invokes undefined behavior [-Waggressive-loop-optimizations]

        compParams.compArray[count] = Wire.read();
        
                                                 ^
        

        C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.cpp:275:3: note: containing loop

        for (count = 0; count < 28; count++) { // first 28 bytes we can process like this

        ^

        C:\Users\x\Documents\Arduino\BME280_sensor\BME280_sensor.ino: In function 'loop':

        C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.cpp:276:45: warning: iteration 20 invokes undefined behavior [-Waggressive-loop-optimizations]

        compParams.compArray[count] = Wire.read();
        
                                                 ^
        

        C:\Users\x\Documents\Arduino\libraries\BME280\BME280_MOD-1022.cpp:275:3: note: containing loop

        for (count = 0; count < 28; count++) { // first 28 bytes we can process like this

        1 Reply Last reply
        0
        • E emc2

          Was modified in 2.1.1, you need to change

          metric = getConfig().isMetric;
          

          to

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

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

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

          Z 1 Reply Last reply
          2
          • Y yoshida

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

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

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

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

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

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

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

                Zbigniew Ko:

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

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

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

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

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

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

                    alexsh1A 1 Reply Last reply
                    0
                    • gohanG gohan

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

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

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

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

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

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

                        Thanks,

                        Y 1 Reply Last reply
                        0
                        • B bluezr1

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

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

                          Thanks,

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

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

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

                          mfalkviddM 1 Reply Last reply
                          0
                          • Y yoshida

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

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

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

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

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

                            Y 1 Reply Last reply
                            0
                            • mfalkviddM mfalkvidd

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

                                  0_1506074720708_170922-IMG_20170922_103752.jpg

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

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

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

                                    circuit card assembly

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


                                    13

                                    Online

                                    11.7k

                                    Users

                                    11.2k

                                    Topics

                                    113.0k

                                    Posts


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

                                    • Don't have an account? Register

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