Mini Weather Station



  • This is a new mini weather station that I have been working on.

    It provides Temperature, Humidity, Pressure, and Battery Voltage.

    IMG_0207.JPG

    IMG_0208.JPG

    The case is designed to be printed without the need for any support, has vents in the front and sides. The front slides on to make it easy to replace the 9v battery. It is designed to take a 50x70mm prototype board. This gives heaps of room for the sensors.

    The 3d files can be found on http://www.thingiverse.com/thing:704715

    The code is mostly a refactor from the examples in the MySensors libraries, with a simplification of the forecast algorithm to reduce the amount of memory that it uses.

    #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 CHILD_ID_BARO 2
    #define CHILD_ID_BARO_TEMP 3
    
    #define HUMIDITY_SENSOR_DIGITAL_PIN 3
    int BATTERY_SENSE_PIN = A0;  // select the input pin for the battery sense point
    
    #define SLEEP_MINUTE 60000
    #define SLEEP_FIVE_MINUTES 300000
    
    MySensor gw;
    DHT dht;
    Adafruit_BMP085 bmp = Adafruit_BMP085();      // Digital Pressure Sensor 
    
    float   lastTemp = -1.0;
    float   lastHum = -1.0;
    float   lastBaroTemp = -1.0;
    int     lastForecast = -1;
    char    *weather[] = { "Stable", "Sunny", "Cloudy", "Unstable", "Thunderstorm",	"Unknown" };
    int     minutes;
    int     pressureSamples[5];
    float   lastPressureAvg = -1.0;
    int     lastPressure = -1;
    int     minuteCount = 0;
    float   pressureAvg;
    int     pressure;
    float   dP_dt;
    boolean metric = true;
    
    MyMessage msgHum(CHILD_ID_HUM, V_HUM);
    MyMessage msgTemp(CHILD_ID_TEMP, V_TEMP);
    MyMessage msgBaroTemp(CHILD_ID_BARO_TEMP, V_TEMP);
    MyMessage msgBaro(CHILD_ID_BARO, V_PRESSURE);
    MyMessage msgForecast(CHILD_ID_BARO, V_FORECAST);
    
    void setup() {
    	// use the 1.1 V internal reference
    	analogReference(INTERNAL);
    	gw.begin();
    	dht.setup(HUMIDITY_SENSOR_DIGITAL_PIN);
    	if (!bmp.begin()) {
    		Serial.println("Could not find a valid BMP085 sensor, check wiring!");
    	}
    	// Send the Sketch Version Information to the Gateway
    	gw.sendSketchInfo("Mini Weather Station", "3.2");
    
    	// 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_BARO, S_BARO);
    	gw.present(CHILD_ID_BARO_TEMP, S_TEMP);
    	metric = gw.getConfig().isMetric;
    }
    
    void loop() {
      
      	Serial.print("minuteCount = ");
    	Serial.println(minuteCount);
    
            // The pressure Sensor Stuff
    	int forecast = SamplePressure();
    
    
            if ( minuteCount > 4 ) { // only every 5 minutes
                    // Process the barometric sensor data 
            	float baro_temperature = bmp.readTemperature();
            	if (!metric) {    // Convert to fahrenheit
            		baro_temperature = baro_temperature * 9.0 / 5.0 + 32.0;
            	}
    
            	if (baro_temperature != lastBaroTemp) {
            		gw.send(msgBaroTemp.set(baro_temperature, 1));
            		lastBaroTemp = baro_temperature;
            	}
    
            	if (pressure != lastPressure) {
            		gw.send(msgBaro.set(pressure, 0));
                            //delay(1000);
    //        		gw.send(msgBaro.set(pressure));
            		lastPressure = pressure;
            	}
    
            	if (forecast != lastForecast) {
            		gw.send(msgForecast.set(weather[forecast]));
            		lastForecast = forecast;
            	}
    
    
                    // The humidity sensor stuff
          	        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("Temperature: ");
          		        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("Humidity: ");
            		Serial.println(humidity);
            	}
          
          
            	// get the battery Voltage
            	long sensorValue = analogRead(BATTERY_SENSE_PIN);
          
            	// 1M, 100K 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+100e3)/100e3)*1.1 = Vmax = 12.1 Volts
            	// 12.1/1023 = Volts per bit = 0.011827957
            	// sensor val at 9v = 9/0.011827957 = 760.909090217
            	// float batteryV  = sensorValue * 0.011827957;
            	long batteryValue = sensorValue * 100L;
            	int batteryPcnt = batteryValue / 761;
            	gw.sendBatteryLevel((batteryPcnt > 100 ? 100 : batteryPcnt)); // this allows for batteries that have slightly over 9v
          
            	Serial.print("Batt %:");
            	Serial.println(batteryPcnt);
            }
    
            if ( minuteCount < 5 )  // sleep a bit
    	        gw.sleep(SLEEP_MINUTE); //while pressure sampling
            else
    	        gw.sleep(SLEEP_FIVE_MINUTES); 
            
    }
    
    int SamplePressure() {
    	// This is a simplification of Algorithm found here to same memory
    	// http://www.freescale.com/files/sensors/doc/app_note/AN3914.pdf
    
    	pressure = bmp.readSealevelPressure(60) / 100; // 60 meters above sealevel
    
    	if (minuteCount > 9) { // we are going to test pressure change every 30 min (5*1min + 5*5min)
    		lastPressureAvg = pressureAvg;
    		minuteCount = 0;
    	}
    
    	if (minuteCount < 5) {
    		pressureSamples[minuteCount] = pressure; // Collect 5 minutes of samples every 30 min
                    Serial.print("  Sample(");
                    Serial.print(minuteCount);
                    Serial.print(") = ");
                    Serial.println(pressure);
            }
    
    	if (minuteCount == 4) { // the 5th minute
    		// Avg pressure in first 5 min, value averaged from 0 to 5 min.
    		pressureAvg = ((pressureSamples[0] + pressureSamples[1]
    				+ pressureSamples[2] + pressureSamples[3] + pressureSamples[4])
    				/ 5);
    		float change = pressureAvg - lastPressureAvg;
    		dP_dt = (((65.0 / 1023.0) * change) / 0.5); // divide by 0.5 as this is the difference in time from last sample 0.5 hours
    		Serial.print("dP_dt = ");
    		Serial.println(dP_dt);
    	}
    
    	minuteCount++;
    
    	if (lastPressureAvg < 0) // no previous pressure sample.
    		return 5; // Unknown, more time needed
    	else if (dP_dt < (-0.25))
    		return 4; // Quickly falling LP, Thunderstorm, not stable
    	else if (dP_dt > 0.25)
    		return 3; // Quickly rising HP, not stable weather
    	else if ((dP_dt > (-0.25)) && (dP_dt < (-0.05)))
    		return 2; // Slowly falling Low Pressure System, stable rainy weather
    	else if ((dP_dt > 0.05) && (dP_dt < 0.25))
    		return 1; // Slowly rising HP stable good weather
    	else if ((dP_dt > (-0.05)) && (dP_dt < 0.05))
    		return 0; // Stable weather
    	else
    		return 5; // Unknown
    
    }
    
    

  • Hero Member

    Nice!! I'm thinking about running a Nano + DHT22 with 9V block. What do you suppose, how long will the sensor run?


  • Admin

    The box is really cool!

    Might print it in some other color though.. 😉


  • Contest Winner

    @hek said:

    Might print it in some other color though.. 😉

    Are you kidding, all of the cool birdies would want to live there!

    @jtm312 Very nicely built!!



  • @TimO Its been running for about 2 weeks now, and used 5-6% of the battery. I have pulled the leds off of the nano to make it last longer (I was only getting 3 weeks with the leds on). It would be nice to think that I could get 20 weeks. I am also thinking of some more code changes to reduce them amount of power consumed.



  • I would like to print that one for my pet 😉


  • Contest Winner

    else if (temperature != lastTemp)
    

    @jtm312

    So I've been working with temperature sensors a while and I worry about comparing floats, and their notorious precision triggering a true here and superfluously affecting the rate of the radio updates. The DHT22 is accurate to about 1 Celsius degree, so it may be unnecessary to transmit a change if there is a change to temperature at any precision of less than 1.

    maybe try something like:

    if (temperature > lastTemp + 0.5 || temperature < lastTemp - 0.5)
    {
      doSomething();
      lastTemp = temperature;
    }
    

    Would reduce transmissions and save battery?

    same argument with your hygrometer and barometric pressure, but different level of precision. Not for the weather calculations, just for the decision to transmit updates, IMO.

    all easy to test with your serial monitor.


  • Hero Member

    @jtm312 Very Cool!



  • @BulldogLowell Thanks, that looks like it is worth a try, or just round to 0.5 degree. I am also going to cut down the sample interval. After the 1min samples to average for the pressure, the rest of the time 5min is probably good enough.


  • Contest Winner

    @jtm312

    maybe, but you may still have the same precision problem if you are using floats.

    maybe just round and cast it to an int... DHT22 isn't precise to half a degree F or C...

    int roundedTemperature = (int) floor(temperature + 0.5);
    if (roundedTemperature != lastTemperature)
    {
      doSomething();
      lastTemperature = roundedTemperature;
    }
    

    more on floats and their precision...

    Floating Point Numbers - Computerphile – 09:16
    — Computerphile



  • @raditv Gotta ask: what sort of pet lives in that??
    🙂
    C.



  • @ jtm312

    Dear..
    Great project!
    I print your station, very good quality!!!

    How is the battery?
    Do you have options to reduce the power?
    Is this sketch the best option?
    Do you have a list that i need to buy so i can build this nice station?

    Thanks!!!



  • @Dylano Thanks.

    I get 3-4 months from a battery by just removing the 2 LEDs from the arduino. Could probably do better running it from 2 AAA batteries and removing the voltage regulator as well. To save more power, you could also increase the interval between sending updates to the controller.

    To build it you need:

    • Arduino Pro Mini
    • Humidity Sensor – DHT22 Aliexpress
    • list itemPressure Sensor – BMP180 Aliexpress
    • Prototype board & Battery Connector

    Connections:



  • Think about to replace your DHT22 with a less current hungry sensor
    HTU21D cold be a good choice (But only running 3,3V)



  • @bjacobse Thanks, they look interesting. I will grab some and have a play.



  • ... and here's mine - in white:
    alt text
    alt text
    (now managed to upload pics in portrait!)

    I'm using a BME280 instead of a BMP180 and DHT22.



  • Really cool.

    Is it possible to get the 3D file for this?


  • Hero Member

    @flopp There is a link in the first post



  • @korttoma said:

    @flopp There is a link in the first post

    Thank you, I must have missed it 🙀



  • @flopp I have added the FreeCAD file to the Thingiverse post so that people can make any changes they want.

    http://www.thingiverse.com/thing:704715



  • I've now uploaded an external view - see my earlier post.



  • If you at some point redesign the nice looking weather station, I recommend:
    1)To place the battery in the top, to avoid battery corrosion

    1. Make a little hole in bottom for water condensation trip out hole


  • @bjacobse
    Hi
    anybody compile code for this station for 2.0 Mysensors ?
    Share the code please.
    Pro mini used 5volt ver ?
    I can't power 3 volt ver from 9 volt ? Correct ?
    Thank you
    Andrey


  • Mod

    You can use any voltage as far as you use the right voltage regulator



  • The pro minis have an onboard voltage regulator (raw input). The specs say that they are good for up to 12v for either the 5v or 3.3v version. I used a 3.3v version as it made the rest of the interface easier.



  • @jtm312
    Just try to connect Pro Mini 3volt to 9 volt GND and RAW - voltage regulator very hot - I think 60-80 C



  • I am curious what kind of battery life you are getting with the 9 volt battery? I tried a sensor with a 9 volt battery and the useful battery duration was less than ideal.


  • Hardware Contributor

    @dbemowsk said in Mini Weather Station:

    I am curious what kind of battery life you are getting with the 9 volt battery? I tried a sensor with a 9 volt battery and the useful battery duration was less than ideal.

    Typical capacity is around 550mAh for alcaline version. All extra voltage is wasted in the linear regulator so you end up with less than half the capacity of 2 AAA or about 20% of the capacity of 2 AA. Not a good choice imho, better switch to i2c sensors like si7021 or BME280 like MikeF did to have much lower power consumption and much lower voltage requirements and use 2 AAA. And the lower the voltage is, the lower the current consumption is for Arduino, radio and sensor so in the end instead of having 4 months of battery life you can get 2 or 3 years with 2 AAA.



  • I had tried a 9 volt when I was building my temp/humidity sensor node and the battery didn't last for crap. At that time I was using a DHT22 with a 5 volt pro mini. I have since switched to an HDC1080 and a 3.3 volt pro mini with 2 AA batteries and it works GREAT. Here is the project if anyone wants to look.
    https://forum.mysensors.org/topic/6485/hdc1080-battery-operated-temp-humidity-sensor-with-wall-box



  • @dbemowsk By cutting the LEDs off, I am getting 12 to 16 weeks.



  • @jtm312 I don't recall exactly how much I was getting on mine, but I don't think it was that much. Are you using 3.3 or 5 volt pro minis?



  • @dbemowsk I am using the 3.3V pro minis. It is the one pictured at the top of this thread. I started out by getting about a week. The big difference came after removing the LEDs, as they were using most of the power. Also sleeping most of the time.

    A good quality 9v also helped. Other humidity sensors can also cut the power drain.

    I have also built version using 2xAAA batteries, but I find that it doesn't take long before the voltages drops below the useful voltage for the radio and starts to cause a range problem. The next version I am planning on going back to using the onboard regulator with 4xAA batteries.



  • @jtm312 I am using 2 AA's on my humidity sensor and that is working very well. The radios are rated I believe down to 1.9 volts. Using the regulator is going to give you more power drain on your batteries. When using 2 AA batteries, there is no need for the regulator at all. Many people say to disconnect it because it can still cause power drain. In my project I just didn't connect to the RAW pin, thus the regulator is not being used. So far I have not seen any issues with the regulator affecting anything.



  • @dbemowsk The 2xbattery builds that I built didn't have the voltage regulator as you suggest. It was just a range problem as the voltage dropped. Moving it closer to the gateway everything was still working.


  • Hardware Contributor

    Yes NRF24 can run down to 1.9V. ATMega328 on the Arduino down to 2V. So problem is probably the BOD resetting below 2.7V.
    I advise to update bootloader to use a 1MHz version and remove BOD or set it to lower value. Using an arduino nano as a programmer (with ArduinoISP sketch) it is very easy.
    Then just use i2c sensors to allow low voltage and you just need to sleep all the time except a fraction of a second at every measurement. With that you get years of battery life.
    I use CR2032 for door and temp/hum/light sensors and my oldest sensor on my entrance door is nearly one year old and voltage of battery is less than 0.1V down, on a chinese low quality cell.



  • @Nca78 would this setup work with the rfm69 radio?


  • Hardware Contributor

    @mpp yes it does.
    But it's using much more power in TX mode so you need good reserve capacitors and also to minimize the sending time. For that it's better to run at 8MHz with the RFM.


  • Mod

    Supply voltage for rfm69 is 1.8V-2.4V 17dBm or 2.4V- 3.6V 20dBm (from datasheet)



  • @gohan so I'd need a 3.6v battery, I'm considering the BME280 or the HTU21d sensor.


  • Mod

    it depends if you want the high power version or use the standard rfm69w at 17dBm and you will be fine to use it down to 1.8V (of course it will work also a little over 3.3V too)



  • @gohan I have a bunch of HW



  • Great device. Why not use a solar power station, like in a solar garden light. Not very good at power equations. What else you going to hook to this? rain gauge, wind speed .... Thanks


 

293
Online

7.8k
Users

8.7k
Topics

93.0k
Posts