Phidgets Weather Display
by Lucas
Introduction
In this project, we will be using the online weather service with Phidgets to display the local weather and time on a LCD1100. We will be using C# to create this project, however, it can be easily ported to your preferred programming language.
Hardware
Software
Libraries and Drivers
This project assumes that you are somewhat familiar with the basic operation of Phidgets (i.e. attaching and opening devices, reading data, etc) and with running examples in the Phidget Control Panel . If this is your first time building a Phidgets project with C#, please refer to the C# page for instructions on how to setup your environment and get started.
Overview
A simple C# console application will perform the following tasks:
- Get information from an online weather service and update the LCD1100 every 15 minutes.
- Get local time and display every second.
Create PhidgetLCD & Enable Logging
The first step, as always, is enabling Phidget logging and creating the required Phidgets.
static void Main(string[] args){
...
Phidget.EnableLogging(LogLevel.Info, "LCDWeatherDisplay.log");
try
{
LCD lcd = new LCD();
lcd.DeviceSerialNumber = 370229;
lcd.Open(2000);
lcd.Contrast = 0.25;//Contrast and backlight both have default values, so setting them is not required
lcd.Backlight = 0.8;
...
}catch (PhidgetException ex){
Phidget.Log(LogLevel.Error, ex.Description);
}
}
Accessing weather data
In order to display weather data, we need to access weather data. Fortunately, there are many resources available for obtaining weather forecasts. We ended up using OpenWeatherMap which provides free access to weather forecasts in over 200,000 cities. Weather data is available in multiple formats including:
- JSON
- XML
- HTML
For this project, we used the XML format along with the XmlTextReader class.
We made a request using the following URL:
http://api.openweathermap.org/data/2.5/weather?q=Calgary&APPID=YOUR_APP_ID&units=metric&mode=xml
In
order to get an APPID you must
sign up for a free
account at OpenWeatherMap.
You can see an example of the returned XML
below:
Parsing XML
Parsing the returned XML is extremely simple in C#. Using the XmlTextReader class,
we can quickly access the information we need. The code for parsing is shown below:
static string readXML(string arg1, string arg2){
String URLString = "http://api.openweathermap.org/data/2.5/weather?q=Calgary&APPID=YOUR_APP_ID&units=metric&mode=xml";
XmlTextReader reader = new XmlTextReader(URLString);
reader.ReadToFollowing(arg1);
reader.MoveToAttribute(arg2);
return reader.Value;
}
static void updateWeather(LCD lcd){
...
string temperature = readXML( "temperature", "value");
string humidity = readXML( "humidity", "value");
string windspeed = readXML( "speed", "value");
string descript = readXML( "weather", "value");
string iconID = readXML( "weather", "icon");
...
}
Done! Now we have up-to-date values for the following:
- Temperature
- Humidity
- Wind speed
- Temperature description
- Icon ID - more on this below
OpenWeatherMap Icons
You may have noticed that we stored the iconID
above.
This value represents an image describing the current weather.
You can view the icons here. Seeing as the LCD1100 is capable of displaying bitmaps,
we can easily implement these icons in our program!
There are many pixel art programs available online, we used Piskel. It was
easy to recreate the OpenWeatherMap icons because of the simple Export to C File
option.
Getting local time
You can access the local time in C# using the following line of code:
DateTime.Now.ToString(" ddd, MMM d hh:mm:ss tt")
If you would like to format the date differently, check out this page by Microsoft.
Outputting to LCD1100
Now that we have the local weather, weather icon bitmaps, and local time, we can output all
of the information to the LCD1100.
static void updateWeather(LCD lcd)
{
string city = readXML("city", "name");
string temperature = readXML("temperature", "value");
string humidity = readXML("humidity", "value");
string windspeed = readXML("speed", "value");
string descript = readXML("weather", "value");
string iconID = readXML("weather", "icon");
//Temperature box
int x = (43 - ((temperature.Length * 6) + 12)) / 2; //find where we should start so temp is centered
lcd.WriteText(LCDFont.Dimensions_6x12, x, 15, temperature);
lcd.WriteText(LCDFont.User1, x + temperature.Length * 6 + 2, 15, "0");//write bitmap for degree symbol created previously
lcd.WriteText(LCDFont.Dimensions_6x12, x + temperature.Length * 6 + 8, 15, "C");
//Weather image + descript box
byte[] temp;
if (iconID == "01d")
temp = _01d;
else if (iconID == "02d")
temp = _02d;
else if (iconID == "03d")
temp = _03d;
else if (iconID == "04d")
temp = _04d;
else if (iconID == "09d")
temp = _09d;
else if (iconID == "10d")
temp = _10d;
else if (iconID == "11d")
temp = _11d;
else if (iconID == "13d")
temp = _13d;
else if (iconID == "50d")
temp = _50d;
else if (iconID == "01n")
temp = _01n;
else if (iconID == "02n")
temp = _02n;
else if (iconID == "10n")
temp = _10n;
else
temp = unknown;
//Weather image and description
lcd.WriteBitmap(2, 31, 32, 32, temp);
lcd.WriteText(LCDFont.Dimensions_5x8, 40, 42, descript);
//Extra info box
lcd.WriteText(LCDFont.Dimensions_5x8, 50, 11, "Humidity: " + humidity + "%");
lcd.WriteText(LCDFont.Dimensions_5x8, 50, 20, "Wind: " + windspeed + "km/h");
}
static void redraw(LCD lcd)
{
lcd.Clear();
//draw outside borders
lcd.DrawLine(0, 0, 127, 0);
lcd.DrawLine(0, 0, 0, 63);
lcd.DrawLine(127, 0, 127, 63);
lcd.DrawLine(0, 63, 127, 63);
//draw inside borders
lcd.DrawLine(0, 10, 128, 10);
lcd.DrawLine(43, 10, 43, 30);
lcd.DrawLine(1, 30, 127, 30);
//update time and weather information
lcd.WriteText(LCDFont.Dimensions_5x8, 1, 1, DateTime.Now.ToString(" ddd, MMM d hh:mm:ss tt"));
updateWeather(lcd);
//Flush all to screen
lcd.Flush();
}
Below is the main loop that utilizes the two functions shown above.
int count = 0;
...
while (true){
Thread.Sleep(1000);
if (count++ == 900){ //900 seconds = 15 minutes
count = 0;
redraw(lcd);
}
else{
//Date & time with underline
lcd.WriteText(LCDFont.Dimensions_5x8, 1, 1, DateTime.Now.ToString(" ddd, MMM d hh:mm:ss tt"));
lcd.Flush();
}
}
Here is the C# project in case you want to try running it yourself.
Conclusion
The weather & time display is complete. If you have any ideas on how to make the project better, let us know!