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: }

IKE