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. Troubleshooting
  3. Weather station

Weather station

Scheduled Pinned Locked Moved Troubleshooting
12 Posts 3 Posters 5.1k Views 2 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.
  • HeinzH Offline
    HeinzH Offline
    Heinz
    Hero Member
    wrote on last edited by
    #2

    Wiring is shown here
    http://www.mysensors.org/build/pressure

    The child ids of BARO and LIGHT are both 2 in your sketch.

    N 1 Reply Last reply
    0
    • HeinzH Offline
      HeinzH Offline
      Heinz
      Hero Member
      wrote on last edited by
      #3

      The BMP085 and the DHT have both a temperature: lastTemp of both sketches collide!
      Have a look at this sketch which is a merge of a BMP085 and a DHT
      https://github.com/windkh/mysensors/blob/master/WeatherStationSensor/WeatherStationSensor.ino

      1 Reply Last reply
      0
      • HeinzH Heinz

        Wiring is shown here
        http://www.mysensors.org/build/pressure

        The child ids of BARO and LIGHT are both 2 in your sketch.

        N Offline
        N Offline
        NBM
        wrote on last edited by
        #4

        @Heinz I know. But is it possible to use A2 and A3?

        HeinzH 1 Reply Last reply
        0
        • N NBM

          @Heinz I know. But is it possible to use A2 and A3?

          HeinzH Offline
          HeinzH Offline
          Heinz
          Hero Member
          wrote on last edited by
          #5

          @NBM said:

          @Heinz I know. But is it possible to use A2 and A3?

          I don't know.

          1 Reply Last reply
          0
          • HeinzH Offline
            HeinzH Offline
            Heinz
            Hero Member
            wrote on last edited by Heinz
            #6

            A function is missing in your case:

            void incomingMessage(const MyMessage &message){}
            
            N D 2 Replies Last reply
            0
            • HeinzH Heinz

              A function is missing in your case:

              void incomingMessage(const MyMessage &message){}
              
              N Offline
              N Offline
              NBM
              wrote on last edited by
              #7

              @Heinz Thank you.

              I have made this sketch without errors.

              // DHT-Sensor
              // BMP085 Sensor
              
              #include <SPI.h>
              #include <MySensor.h>
              #include <Wire.h>
              #include <Adafruit_BMP085_U.h>
              #include <Adafruit_Sensor.h>
              #include <DHT.h>  
              
              
              const bool sendAlways = true;
              
              const float SEALEVEL = 688; // Westendorf
              const float SEALEVEL_PRESSURE = 1013.25;
              
              // ----------------------------------------------------------------------------
              #define CHILD_ID_HUM 2
              #define CHILD_ID_TEMP 3
              #define HUMIDITY_SENSOR_DIGITAL_PIN 3
              #define CHILD_ID_LIGHT 1
              #define LIGHT_SENSOR_ANALOG_PIN 1
              
              DHT dht;
              float lastTemp;
              float lastHum;
              boolean metric = true;
              MyMessage msgHum(CHILD_ID_HUM, V_HUM);
              MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
              
              
              // ----------------------------------------------------------------------------
              #define BARO_CHILD 0
              #define TEMP_CHILD 1
              
              unsigned long SLEEP_TIME = 30000; // Sleep time between reads (in milliseconds)
              unsigned long SLEEP_TIME1 = 30000; // 1 minute required for forecast algorithm
              unsigned long SLEEP_TIME2 = 30000; // 1 minute required for forecast algorithm
              unsigned long SLEEP_TIME3 = 900000;  // sleep time between reads (seconds * 1000 milliseconds)
              
              
              Adafruit_BMP085_Unified bmp = Adafruit_BMP085_Unified(1);    // Digital Pressure Sensor 
              MySensor gw;
              
              MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
              int lastLightLevel;
              int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
              int oldBatteryPcnt = 0;
              
              /*
              DP/Dt explanation
              0 = "Stable Weather Pattern"
              1 = "Slowly rising Good Weather", "Clear/Sunny "
              2 = "Slowly falling L-Pressure ", "Cloudy/Rain "
              3 = "Quickly rising H-Press",     "Not Stable"
              4 = "Quickly falling L-Press",    "Thunderstorm"
              5 = "Unknown (More Time needed)
              */
              
              const char *weatherStrings[] = { "stable", "sunny", "cloudy", "unstable", "thunderstorm", "unknown" };
              enum FORECAST
              {
                STABLE = 0,     // Stable weather
                SUNNY = 1,      // Slowly rising HP stable good weather
                CLOUDY = 2,     // Slowly falling Low Pressure System, stable rainy weather
                UNSTABLE = 3,   // Quickly rising HP, not stable weather
                THUNDERSTORM = 4, // Quickly falling LP, Thunderstorm, not stable
                UNKNOWN = 5     // Unknown, more time needed
              };
              
              const char *situationStrings[] = { "very low", "low", "normal", "high", "very high" };
              enum WEATHER_SITUATION
              {
                VERY_LOW_PRESSURE = 0,    // Tiefdruck p>-7.5hPa
                LOW_PRESSURE = 1,     // Tiefdruck p>-2.5hPa
                NORMAL_PRESSURE = 2,    // Normal  p <+/-02.5hPa  
                HIGH_PRESSURE = 3,      // Hochdruck p>2.5hPa
                VERY_HIGH_PRESSURE = 4,   // Hochdruck p>7.5hPa
              };
              
              float lastPressure = -1;
              float lastPressureTemp = -1;
              int lastForecast = -1;
              int lastSituation = NORMAL_PRESSURE;
              
              const int LAST_SAMPLES_COUNT = 5;
              float lastPressureSamples[LAST_SAMPLES_COUNT];
              
              // get kPa/h be 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;
              
              MyMessage tempMsg(TEMP_CHILD, V_TEMP);
              MyMessage pressureMsg(BARO_CHILD, V_PRESSURE);
              MyMessage forecastMsg(BARO_CHILD, V_FORECAST);
              MyMessage situationMsg(BARO_CHILD, V_VAR1);
              MyMessage forecastMsg2(BARO_CHILD, V_VAR2);
              
              void displaySensorDetails(void)
              {
                sensor_t sensor;
                bmp.getSensor(&sensor);
                Serial.println(F("------------------------------------"));
                Serial.print(F("Sensor:       ")); Serial.println(sensor.name);
                Serial.print(F("Driver Ver:   ")); Serial.println(sensor.version);
                Serial.print(F("Unique ID:    ")); Serial.println(sensor.sensor_id);
                Serial.print(F("Max Value:    ")); Serial.print(sensor.max_value); Serial.println(F(" hPa"));
                Serial.print(F("Min Value:    ")); Serial.print(sensor.min_value); Serial.println(F(" hPa"));
                Serial.print(F("Resolution:   ")); Serial.print(sensor.resolution); Serial.println(F(" hPa"));
                Serial.println(F("------------------------------------"));
                Serial.println(F(""));
                delay(500);
              }
              
              void initPressureSensor()
              {
                if (!bmp.begin())
                {
                  Serial.println(F("Could not find a valid BMP085 sensor, check wiring!"));
                  while (1) {}
                }
              
                displaySensorDetails();
              }
              
              void initHumiditySensor()
              {
                dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
              }
              
              void setup() 
              {
                   // use the 1.1 V internal reference
                #if defined(__AVR_ATmega2560__)
                 analogReference(INTERNAL1V1);
                #else
                 analogReference(INTERNAL);
                #endif
                gw.begin();
                gw.sendSketchInfo("Weather Station Sensor", "2.1");
              
                initPressureSensor();
                initHumiditySensor();
              
                gw.present(BARO_CHILD, S_BARO);
                gw.present(TEMP_CHILD, S_TEMP);
                gw.present(CHILD_ID_HUM, S_HUM);
                gw.present(CHILD_ID_TEMP, S_TEMP);
                gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
              
                metric = gw.getConfig().isMetric;
              
               int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23; 
                Serial.println(lightLevel);
                if (lightLevel != lastLightLevel) {
                    gw.send(msg.set(lightLevel));
                    lastLightLevel = lightLevel;
                }
                 gw.sleep(SLEEP_TIME);  
              }
              
              int getWeatherSituation(float pressure)
              {
                int situation = NORMAL_PRESSURE;
              
                float delta = pressure - SEALEVEL_PRESSURE;
                if (delta > 7.5)
                {
                  situation = VERY_HIGH_PRESSURE;
                }
                else if (delta > 2.5)
                {
                  situation = HIGH_PRESSURE;
                }
                else if (delta < -7.5)
                {
                  situation = VERY_LOW_PRESSURE;
                }
                else if (delta < -2.5)
                {
                  situation = LOW_PRESSURE;
                }
                else
                {
                  situation = NORMAL_PRESSURE;
                }
              
                return situation;
              }
              
              bool updatePressureSensor()
              {
                bool changed = false;
              
                sensors_event_t event;
                bmp.getEvent(&event);
              
                if (event.pressure)
                {
                  float absolutePressure = event.pressure;
                  Serial.print(F("abs Pressure = "));
                  Serial.print(absolutePressure);
                  Serial.println(F(" hPa"));
                  
                  //float altitude = bmp.pressureToAltitude(SEALEVEL_PRESSURE, pressure);
                  //Serial.print(F("Altitude = "));
                  //Serial.print(altitude);
                  //Serial.println(F(" m"));
              
                  //sealevel pressure p0 from absolute pressure.
                  float pressure = bmp.seaLevelForAltitude(SEALEVEL, absolutePressure);
              
                  float pressureTemperature;
                  bmp.getTemperature(&pressureTemperature);
              
                  if (!metric) 
                  {
                    // Convert to fahrenheit
                    pressureTemperature = pressureTemperature * 9.0 / 5.0 + 32.0;
                  }
              
                  int forecast = sample(pressure);
                  int situation = getWeatherSituation(pressure);
              
              
                  if (sendAlways || (pressureTemperature != lastPressureTemp))
                  {
                    changed = true;
                    lastPressureTemp = pressureTemperature;
                    Serial.print(F("Temperature = "));
                    Serial.print(pressureTemperature);
                    Serial.println(metric ? F(" *C") : F(" *F"));
                    if (!gw.send(tempMsg.set(lastPressureTemp, 1)))
                    {
                      lastPressureTemp = -1.0;
                    }
                  }
              
              
                  if (sendAlways || (pressure != lastPressure))
                  {
                    changed = true;
                    lastPressure = pressure;
                    Serial.print(F("sealevel Pressure = "));
                    Serial.print(pressure);
                    Serial.println(F(" hPa"));
                    if (!gw.send(pressureMsg.set(lastPressure, 1)))
                    {
                      lastPressure = -1.0;
                    }
                  }
              
              
                  if (sendAlways || (forecast != lastForecast))
                  {
                    changed = true;
                    lastForecast = forecast;
                    Serial.print(F("Forecast = "));
                    Serial.println(weatherStrings[forecast]);
                    if (gw.send(forecastMsg.set(weatherStrings[lastForecast])))
                    {
                      if (!gw.send(forecastMsg2.set(lastForecast)))
                      {
                      }
                    }
                    else
                    {
                      lastForecast = -1.0;
                    }
                  }
              
              
                  if (sendAlways || (situation != lastSituation))
                  {
                    changed = true;
                    lastSituation = situation;
                    Serial.print(F("Situation = "));
                    Serial.println(situationStrings[situation]);
                    if (!gw.send(situationMsg.set(lastSituation, 0)))
                    {
                      lastSituation = -1.0;
                    }
                  }
                }
              
                return changed;
              }
              
              bool updateHumiditySensor()
              {
                bool changed = false;
              
                float temperature = dht.getTemperature();
                float humidity = dht.getHumidity();
              
                if (!isnan(temperature))
                {
              #ifdef SEND_WHEN_CHANGED
                  if (temperature != lastTemp)
              #endif
                  {
                    lastTemp = temperature;
                    if (!metric)
                    {
                      temperature = dht.toFahrenheit(temperature);
                    }
                    changed = true;
                    Serial.print(F("T: "));
                    Serial.println(temperature);
                    if (!gw.send(msgTemp.set(temperature, 1)))
                    {
                      lastTemp = -1.0;
                    }
                  }
                }
                else
                {
                  Serial.println(F("Failed reading temperature from DHT"));
                }
                
                
                if (!isnan(humidity))
                {
              #ifdef SEND_WHEN_CHANGED
                  if (humidity != lastHum)
              #endif
                  {
                    lastHum = humidity;
                    changed = true;
                    Serial.print(F("H: "));
                    Serial.println(humidity);
                    if (!gw.send(msgHum.set(lastHum, 1)))
                    {
                      lastHum = -1.0;
                    }
                  }
                }
                else
                {
                  Serial.println(F("Failed reading humidity from DHT"));
                }
                
                return changed;
              }
              
              void loop() 
              {
                 // get the battery Voltage
                 int sensorValue = analogRead(BATTERY_SENSE_PIN);
                 #ifdef DEBUG
                 Serial.println(sensorValue);
                 #endif
                 
                 // 1M, 470K divider across battery and using internal ADC ref of 1.1V
                 // Sense point is bypassed with 0.1 uF cap to reduce noise at that point
                 // ((1e6+470e3)/470e3)*1.1 = Vmax = 3.44 Volts
                 // 3.44/1023 = Volts per bit = 0.003363075
                 float batteryV  = sensorValue * 0.003363075;
                 int batteryPcnt = sensorValue / 10;
              
                 #ifdef DEBUG
                 Serial.print("Battery Voltage: ");
                 Serial.print(batteryV);
                 Serial.println(" V");
              
                 Serial.print("Battery percent: ");
                 Serial.print(batteryPcnt);
                 Serial.println(" %");
                 #endif
              
                 if (oldBatteryPcnt != batteryPcnt) {
                   // Power up radio after sleep
                   gw.sendBatteryLevel(batteryPcnt);
                   oldBatteryPcnt = batteryPcnt;
                 }
                updatePressureSensor();
                gw.sleep(SLEEP_TIME1);
                updateHumiditySensor();
                gw.sleep(SLEEP_TIME2);
              
                gw.sleep(SLEEP_TIME3);
              }
              
              
              float getLastPressureSamplesAverage()
              {
                float lastPressureSamplesAverage = 0;
                for (int i = 0; i < LAST_SAMPLES_COUNT; i++)
                {
                  lastPressureSamplesAverage += lastPressureSamples[i];
                }
                lastPressureSamplesAverage /= LAST_SAMPLES_COUNT;
              
                //Serial.print(F("### 5min-Average:"));
                //Serial.print(lastPressureSamplesAverage);
                //Serial.println(F(" hPa"));
              
                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;
                }
              
                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(weatherStrings[forecast]);
              
                return forecast;
              }```
              1 Reply Last reply
              1
              • HeinzH Heinz

                A function is missing in your case:

                void incomingMessage(const MyMessage &message){}
                
                D Offline
                D Offline
                Dylano
                wrote on last edited by
                #8

                @Heinz

                Is this sketch working great now?
                And how is the battery?
                How long can work this sketch, on what type battery?

                Domoticz, with a lot of working hardware, include mysensors :-)
                OpenPLI, RuneAudio, Solarmeter, etc......

                Not a great builder of software and hardware, more a user...
                Only i try to do my best :-(

                1 Reply Last reply
                0
                • HeinzH Offline
                  HeinzH Offline
                  Heinz
                  Hero Member
                  wrote on last edited by
                  #9

                  @Dylano the sketch in this thread is from @NBM, if you mean
                  https://github.com/windkh/mysensors/blob/master/WeatherStationSensor/WeatherStationSensor.ino
                  then this one is working very well.

                  This one is the official mysensors example
                  https://github.com/mysensors/Arduino/blob/development/libraries/MySensors/examples/WeatherStationSensor/WeatherStationSensor.ino

                  1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    Dylano
                    wrote on last edited by
                    #10

                    still got an error:
                    C:\Users\DM_PC\Desktop\Mysensors 23-2-2015\Sketches Werkend\sketch_mar05a\sketch_mar05a.ino:8:29: fatal error: Adafruit_Sensor.h: No such file or directory

                    #include <Adafruit_Sensor.h>

                    Only where can i download the adafruit library?

                    Domoticz, with a lot of working hardware, include mysensors :-)
                    OpenPLI, RuneAudio, Solarmeter, etc......

                    Not a great builder of software and hardware, more a user...
                    Only i try to do my best :-(

                    HeinzH 1 Reply Last reply
                    0
                    • D Dylano

                      still got an error:
                      C:\Users\DM_PC\Desktop\Mysensors 23-2-2015\Sketches Werkend\sketch_mar05a\sketch_mar05a.ino:8:29: fatal error: Adafruit_Sensor.h: No such file or directory

                      #include <Adafruit_Sensor.h>

                      Only where can i download the adafruit library?

                      HeinzH Offline
                      HeinzH Offline
                      Heinz
                      Hero Member
                      wrote on last edited by
                      #11

                      @Dylano

                      https://github.com/adafruit/Adafruit_Sensor
                      https://github.com/adafruit/Adafruit_BMP085_Unified

                      D 1 Reply Last reply
                      0
                      • HeinzH Heinz

                        @Dylano

                        https://github.com/adafruit/Adafruit_Sensor
                        https://github.com/adafruit/Adafruit_BMP085_Unified

                        D Offline
                        D Offline
                        Dylano
                        wrote on last edited by
                        #12

                        @Heinz said:

                        @Dylano

                        https://github.com/adafruit/Adafruit_Sensor
                        https://github.com/adafruit/Adafruit_BMP085_Unified

                        Thanks!!!

                        Domoticz, with a lot of working hardware, include mysensors :-)
                        OpenPLI, RuneAudio, Solarmeter, etc......

                        Not a great builder of software and hardware, more a user...
                        Only i try to do my best :-(

                        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.1k

                        Posts


                        Copyright 2025 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