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