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.7k 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.
  • N Offline
    N Offline
    NBM
    wrote on last edited by
    #1

    Hi

    Im trying to make an node with BMP085, DHT22 and LM393. Barometer, Temp/hum and light.

    Can anyone help me to make the sketch work?

    Do the barometer have to be connected to A4 and A5?

    //Vejrstation - Temp, Fugt, Lux, Baro - V 1.0
    
    #include <SPI.h>
    #include <MySensor.h> 
    #include <DHT.h>
    #include <Wire.h>
    #include <Adafruit_BMP085.h>  
    
    #define CHILD_ID_HUM 0
    #define CHILD_ID_TEMP 1
    #define HUMIDITY_SENSOR_DIGITAL_PIN 3
    
    
    #define CHILD_ID_LIGHT 2
    #define LIGHT_SENSOR_ANALOG_PIN 1
    
    #define BARO_CHILD 2
    #define TEMP_CHILD 3
    
    //Temp
    
    MySensor gw;
    DHT dht;
    float lastTemp;
    float lastHum;
    boolean metric = true; 
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    
    float lastPressure = -1;
    float lastTemp = -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 forecast algorithm
    // 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;
    boolean metric;
    MyMessage tempMsg(TEMP_CHILD, V_TEMP);
    MyMessage pressureMsg(BARO_CHILD, V_PRESSURE);
    MyMessage forecastMsg(BARO_CHILD, V_FORECAST);
    
    unsigned long SLEEP_TIME = 900000;  // sleep time between reads (seconds * 1000 milliseconds)
    int oldBatteryPcnt = 0;
    
    MyMessage msg(CHILD_ID_LIGHT, V_LIGHT_LEVEL);
    int lastLightLevel;
    
    //Batteri
    
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    
    //Baro
    
    const float ALTITUDE = 34.691; // <-- adapt this value to your own location's altitude.
    
    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)
    };
    
    Adafruit_BMP085 bmp = Adafruit_BMP085();      // Digital Pressure Sensor 
    
    void setup()  
    {
       // use the 1.1 V internal reference
    #if defined(__AVR_ATmega2560__)
       analogReference(INTERNAL1V1);
    #else
       analogReference(INTERNAL);
    #endif
       gw.begin(incomingMessage, 9, true));
    
       // Send the sketch version information to the gateway and Controller
       gw.sendSketchInfo("Weather Station", "1.0");
    
       dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN); 
    
    
      // Register all sensors to gw (they will be created as child devices)
    	gw.present(CHILD_ID_HUM, S_HUM);
    	gw.present(CHILD_ID_TEMP, S_TEMP);
    	gw.present(CHILD_ID_LIGHT, S_LIGHT_LEVEL);
    	gw.present(BARO_CHILD, S_BARO);
    	gw.present(TEMP_CHILD, S_TEMP);
      
      metric = gw.getConfig().isMetric;
    
    }
    
    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;
       }
       gw.sleep(SLEEP_TIME);
    
    delay(dht.getMinimumSamplingPeriod());
    
      float temperature = dht.getTemperature();
      if (isnan(temperature)) {
          Serial.println("Failed reading temperature from DHT");
      } else if (temperature != lastTemp) {
        lastTemp = temperature;
        if (!metric) {
          temperature = dht.toFahrenheit(temperature);
        }
        gw.send(msgTemp.set(temperature, 1));
        Serial.print("T: ");
        Serial.println(temperature);
      }
      
      float humidity = dht.getHumidity();
      if (isnan(humidity)) {
          Serial.println("Failed reading humidity from DHT");
      } else if (humidity != lastHum) {
          lastHum = humidity;
          gw.send(msgHum.set(humidity, 1));
          Serial.print("H: ");
          Serial.println(humidity);
      }
    
      gw.sleep(SLEEP_TIME); //sleep a bit
    
    int lightLevel = (1023-analogRead(LIGHT_SENSOR_ANALOG_PIN))/10.23; 
      Serial.println(lightLevel);
      if (lightLevel != lastLightLevel) {
          gw.send(msg.set(lightLevel));
          lastLightLevel = lightLevel;
      }
    
    float pressure = bmp.readSealevelPressure(ALTITUDE) / 100.0;
    	float temperature = bmp.readTemperature();
    
    	if (!metric) 
    	{
    		// Convert to fahrenheit
    		temperature = temperature * 9.0 / 5.0 + 32.0;
    	}
    
    	int forecast = sample(pressure);
    
    	Serial.print("Temperature = ");
    	Serial.print(temperature);
    	Serial.println(metric ? " *C" : " *F");
    	Serial.print("Pressure = ");
    	Serial.print(pressure);
    	Serial.println(" hPa");
    	Serial.print("Forecast = ");
    	Serial.println(weather[forecast]);
    
    
    	if (temperature != lastTemp) 
    	{
    		gw.send(tempMsg.set(temperature, 1));
    		lastTemp = temperature;
    	}
    
    	if (pressure != lastPressure) 
    	{
    		gw.send(pressureMsg.set(pressure, 0));
    		lastPressure = pressure;
    	}
    
    	if (forecast != lastForecast)
    	{
    		gw.send(forecastMsg.set(weather[forecast]));
    		lastForecast = forecast;
    	}
    
    	gw.sleep(SLEEP_TIME);
    }
    
    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;
    
    }
    

    I get this error:

    Arduino: 1.6.5 (Mac OS X), Board: "Arduino Pro or Pro Mini, ATmega328 (3.3V, 8 MHz)"
    
    Vejrstation_v1.2:31: error: redefinition of 'float lastTemp'
    Vejrstation_v1.2:24: error: 'float lastTemp' previously declared here
    Vejrstation_v1.2:49: error: redefinition of 'boolean metric'
    Vejrstation_v1.2:26: error: 'boolean metric' previously defined here
    Vejrstation_v1.2.ino: In function 'void setup()':
    Vejrstation_v1.2:89: error: 'incomingMessage' was not declared in this scope
    Vejrstation_v1.2:89: error: expected ';' before ')' token
    Vejrstation_v1.2.ino: In function 'void loop()':
    Vejrstation_v1.2:175: error: redeclaration of 'float temperature'
    Vejrstation_v1.2:142: error: 'float temperature' previously declared here
    redefinition of 'float lastTemp'
    
      This report would have more information with
      "Show verbose output during compilation"
      enabled in File > Preferences.
    
    1 Reply Last reply
    0
    • 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

                          Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                          Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                          With your input, this post could be even better 💗

                          Register Login
                          Reply
                          • Reply as topic
                          Log in to reply
                          • Oldest to Newest
                          • Newest to Oldest
                          • Most Votes


                          14

                          Online

                          12.0k

                          Users

                          11.2k

                          Topics

                          113.4k

                          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