How to make your own cheap weather station

image

Though the prices for personal weather station have dramatically dropped (around $100) over the past few years, I decided to work on making my own. The primary measurement I wanted was temperature given this is the specific one that could be dramatically different from my neighbors (or neighborhood weather station) given the many unique microclimates your yard can have.

Step 1: Create an account and weather station at Weather Underground. This will allow you a place to view your weather station results as well as a permanent storage location for your data. After you have created your account it is really easy to create a weather station after clicking this link you just need to enter some basic information such as address and time zone click “Submit” and you have yourself a weather station. Now this is not very exciting unless data is being updated so we will look at this next.

image Step 2: Get some data. Hear is a point where you can go all out with every weather measurement sensor imaginable, though if this was your intent I would recommend saving some money and getting a personal weather station, but in my case all I really wanted to track was the outdoor temperature. To get this temperature I used a DirectTemp USB waterproof temperature probe from Quality Thermistor, Inc. All you need to do is plug this into an open USB port and with some simple serial communication you can start getting temperature results. This can easily be done using a language like C# with just a few lines of code:

SerialPort serialPort = new SerialPort(“COM5”, 9600); serialPort.Open(); serialPort.WriteLine(“2”); double responseValue = Convert.ToDouble(serialPort.ReadLine()); serialPort.Close();

You could also use something similar to my homemade waterproof digital thermometer and an arduino to get your outside temperature.

Step 3: Log your results. WeatherUnderground makes submitting data to them very easy. All that is required is a specially formatted query string request which you could do in any internet browser…though updating this manually every 5 minutes would be very tedious this is how can do this also using C#. All that is required is to replace the “ID” with your weather station created in Step 1 and your password used when you created your account.

string submitUrl = “http://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?action=updateraw&ID=KWAREDMO38&PASSWORD=[password]&”; submitUrl += “dateutc=” + DateTime.UtcNow.ToString(“yyyy-MM-dd hh:mm:ss”) + “&”; submitUrl += “tempf=” + GetOutdoorTemp(); // Using code above WebClient webClient = new WebCLient(); webClient.DownloadString(submitUrl);

Now by calling the above code every 5 minutes using an infinite loop with some delay you can now log your temperature results and have current and historical data to have some better info to better guess your first/last frost dates or when it is safe to bring out your tender seedlings you are growing indoors.

Step 4 (optional): Leverage external weather data. As you may have noticed my weather station has more weather data than just temperature. I did this by leveraging (nicer word than stealing) some data from a weather station at a school in my neighborhood. Now this is not quite as accurate as if I was getting this information from my backyard…it is pretty safe to assume that the humidity, rain, and wind velocity and direction should be pretty much in the same ballpark. The process is pretty simple here where I extract this from a request to the external weather station and include these into my submission, which you can see in the code sample below.

   1: using System;

   2: using System.IO.Ports;

   3: using System.Xml;

   4: using System.Net;

   5:

   6: namespace WeatherStation

   7: {

   8:     class Program

   9:     {

  10:         private static WebClient webClient = new WebClient();

  11:

  12:         static void Main(string[] args)

  13:         {

  14:             while (true)

  15:             {

  16:                 SubmitWeatherInfo();

  17:

  18:                 System.Threading.Thread.Sleep(300000);

  19:             }

  20:         }

  21:

  22:         public static void SubmitWeatherInfo()

  23:         {

  24:                 string submitUrl = "http://weatherstation.wunderground.com/weatherstation/updateweatherstation.php?action=updateraw&ID=KWAREDMO38&PASSWORD=[password]&";

  25:                 submitUrl += "dateutc=" + DateTime.UtcNow.ToString("yyyy-MM-dd hh:mm:ss") + "&";

  26:                 submitUrl += "tempf=" + GetOutdoorTemp() + "&";

  27:                 submitUrl += GetExternalWeatherData();

  28:

  29:                 webClient.DownloadString(submitUrl);

  30:         }

  31:

  32:         private static double GetOutdoorTemp()

  33:         {

  34:             SerialPort serialPort = new SerialPort("COM5", 9600);

  35:             serialPort.Open();

  36:             serialPort.WriteLine("2");

  37:             double responseValue = Convert.ToDouble(serialPort.ReadLine());

  38:

  39:             serialPort.Close();

  40:

  41:             return CelsiusToFahrenheit(responseValue);

  42:         }

  43:

  44:         public static double CelsiusToFahrenheit(double temperatureCelsius)

  45:         {

  46:             return (temperatureCelsius * 9 / 5) + 32;

  47:         }

  48:

  49:

  50:         private static string GetExternalWeatherData()

  51:         {

  52:             string externalWeatherStation = "http://api.wunderground.com/weatherstation/WXCurrentObXML.asp?";

  53:             externalWeatherStation += "ID=[ExternalWeatherStationId]";

  54:

  55:             XmlDocument xmlDoc = new XmlDocument();

  56:             xmlDoc.LoadXml(webClient.DownloadString(externalWeatherStation));

  57:

  58:             string externalData = "&winddir=" + xmlDoc.SelectSingleNode("//wind_degrees").InnerText;

  59:             externalData += "&windspeedmph=" + xmlDoc.SelectSingleNode("//wind_mph").InnerText;

  60:             externalData += "&windgustmph=" + xmlDoc.SelectSingleNode("//wind_gust_mph").InnerText;

  61:             externalData += "&baromin=" + xmlDoc.SelectSingleNode("//pressure_in").InnerText;

  62:             externalData += "&humidity=" + xmlDoc.SelectSingleNode("//relative_humidity").InnerText;

  63:             externalData += "&dewptf=" + xmlDoc.SelectSingleNode("//dewpoint_f").InnerText;

  64:             externalData += "&rainin=" + xmlDoc.SelectSingleNode("//precip_1hr_in").InnerText;

  65:             externalData += "&dailyrainin=" + xmlDoc.SelectSingleNode("//precip_today_in").InnerText;

  66:

  67:             return externalData;

  68:         }

  69:     }

  70: }

Homemade waterproof digital thermometer

057

Now I am playing with hydroponics in my grow box I want to monitor the temperature of my nutrient tank.  This is important too hot it can bread disease too cold it can shock your plants.  I also want to use the data to identify how ebb/flow cycles affect ambient and solution temperature (for my own nerd curiosity)

I have been thoroughly impressed with the Dallas DS18S20 temperature sensor so decided this would be a great component to use for this project and this is how you can make your own.

Materials:

  • DS18S20 temperature sensor
  • 1/2 inch plastic tubing (could go smaller but had some lying around)
  • Aquarium/food grade silicone
  • 18 gauge solid core wire (long enough to get from arduino to what you want to measure)
  • Glue gun with glue
  • Soldering iron with solder

 

Construction

Step 1: Solder the two wires to pins 1 and 2 of the DS18S20 and apply a little dab of hot glue to all of the exposed metal.  This is not entirely necessary but a small safety precaution so you don’t discover you shorted the connection during assembly.

image

052

Step 2: Cut approximately 1 inch length of plastic tubing using a utility knife

Step 3: Apply liberal amount of silicone to one end of the tubing cut in step 2.

053

Step 4: Allow silicone to set for 15 minutes and do a visual inspection for leaks. You may also try blowing very gently into the tube to check for leaks, though not too hard to create a hole in the process.

055

Step 5: Attach the DS18S20 to the tube using a drop of hot glue.  This is not entirely necessary but when trying to get a perfect watertight seal the less moving parts the better.

056

Step 6: Again apply a liberal amount of silicone to seal the top paying special attention to the area around the wires

058

Step 7: Give the silicone at least 24 hours to completely set.

Step 8: Testing.  First off the sensor may be buoyant, if this is the case carefully attach a 1/2 hose clamp or something else to help tether it down.  Next suspend in a glass of water (preferably clear) and watch for a few minutes for leaks and or bubbles. If you see bubbles try to get an much water as you can out and apply a more silicone and let set for another 24 hours

Hooking it up

This part is pretty straightforward.  Pin 1 is your ground and pin 2 is your DQ which for most people doesn’t make much sense but it is a combination power source and bus output.  To get this to work you hook up your ground (black wire) to your ground on your arduino and the red wire to digital in and 5v with 4.7K resistor between.  Sure that is very confusing so hopefully the breadboard visual below is much more helpful.

image

Writing the Code

Since I am planning on using this with my grow box controller, I will show how to use this with arduino to get some numbers.  You could look at my arduino code in the grow box controller post to get the values but in my case I need to get values from two DS18S20 temperature sensors so I found a great OneWire library which helps make your arduino code very simply.  Simple extract the two folders in the zip archive to [ArduinoPath]\hardware\libraries and enter the following code into the arduino UI:

#include <OneWire.h> #include <DallasTemperature.h> 
OneWire oneWire(8); // on pin 8 DallasTemperature sensors(&oneWire);

void setup()
{  
  Serial.begin(9600);
  // Initialize sensors
  sensors.begin();
}

void loop()
{
    sensors.requestTemperatures();
    Serial.print(“Sensor #0: “);    
    Serial.println(sensors.getTempCByIndex(0));

    Serial.print(“Sensor #1: “);
    Serial.println(sensors.getTempCByIndex(1))

    delay(100);  // wait a little time
}
 

If all goes well you should see output similar to the following (values in Celsius):

 Sensor #0: 20.3
 Sensor #1: 30.4
 Sensor #0: 20.3
 Sensor #1: 30.4
 Sensor #0: 20.3
 Sensor #1: 30.4

 

For people like me who are used to Fahrenheit you can simply use the following equation to convert Celsius to Fahrenheit:
°F = °C  x  9/5 + 32

Though I am using this for my grow box controller there are many other uses you could use this for:

  • Aquarium temperature monitoring
  • Brewing temperature monitoring
  • Weather station
  • Soil thermometer
IKE