Weather station



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

  • Hero Member

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

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


  • Hero Member

    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



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


  • Hero Member

    @NBM said:

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

    I don't know.


  • Hero Member

    A function is missing in your case:

    void incomingMessage(const MyMessage &message){}


  • @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;
    }```


  • @Heinz

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


  • Hero Member



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


  • Hero Member




Log in to reply
 

Suggested Topics

  • 3
  • 24
  • 4
  • 10
  • 2
  • 3

25
Online

11.2k
Users

11.1k
Topics

112.5k
Posts