Weather LCD Display
.
Using Google's Weather API to display the current weather conditions in Los Angeles on the LCD. Larger Image
This Internet of Things example displays the current weather conditions on a text LCD. It uses a Google Weather API to retrieve a web page containing XML with weather data for Los Angeles. The Simple Plain XML parser library ported to mbed is used to parse the XML and retrieve the desired data fields for the LCD display. It is based on an earlier XML parser example and the Text-LCD library.
Google's Largest Server Farm is near a hydroelectric power plant in Oregon. It might wind up responding to your weather API call.
The Weather Channel Studio in Atlanta.
The Weather Channel also has RSS feeds for many cities. The Weather Channel API is only available by paid subscription.
Wiring
The same hardware and wiring setup is used as the Internet LCD clock example, News LCD Display, and Geolocation LCD Display.
Ethernet Magjack Connector
Mbed | Sparkfun Ethernet Breakout |
---|---|
TD+ | P1 |
TD- | P2 |
RD+ | P7 |
RD- | P8 |
Note: Different magjack connectors can use different pin outs even though they look the same. These pins are for connectors from Sparkfun in 2011. If you are having trouble with your initial network setup, try this example code first. Once it works, it will confirm correct wiring on the connector (at least on the input side). Magjack Pinouts are posted for other common connectors. More connections to the unused pins including one to 3.3V and a capacitor should be added for long cables, but this setup works well with short cables. If you still get the net error message, make sure that DHCP service is enabled for your mbed. On some networks, you need to add the module's MAC address to enable the DHCP server to give it an IP address. It times out with an error, if no IP address is returned in about fifteen seconds. If the weather does not display on the LCD after seeing "net OK", you may have DNS problems or a very slow network.
Text LCD
Mbed pins | Text LCD pins |
---|---|
GND | GND |
5V or 3.3V* | VCC |
VO to GND via 1k resistor | |
P15 | RS |
GND | RW |
P16 | E |
N/C | D0 |
N/C | D1 |
N/C | D2 |
N/C | D3 |
P17 | D4 |
P18 | D5 |
P19 | D6 |
P20 | D7 |
Where N/C is not connected and the top left pin of the TextLCD’s header is GND and the right most pin is D7 in the LCD orientation shown in the images above. The resistor sets the contrast and some LCDs may need a different value or a contrast adjust potentiometer. See Text LCD for additional help, if needed.
(*) Note: some older LCDs may use 5V, but 3.3V is more common on current LCDs. If you cannot find a data sheet to confirm this, try 3.3V first and if the display is still blank (after double checking all other connections and code) it might need 5V. To save jumper wires, this setup uses the four bit interface to transfer ASCII characters to the LCD.
Example Code
#include "mbed.h" #include "EthernetNetIf.h" #include "HTTPClient.h" #include "spdomparser.hpp" #include "spxmlnode.hpp" #include "spxmlhandle.hpp" #include "TextLCD.h" // Internet of Things weather display example: LCD displays LA current weather via internet Google API // Adapted for LCD from http://mbed.org/users/hlipka/programs/spxmltest_weather/lif782 TextLCD lcd(p15, p16, p17, p18, p19, p20); // rs, e, d0-d3 EthernetNetIf eth; HTTPClient http; HTTPResult result; bool completed = false; void request_callback(HTTPResult r) { result = r; completed = true; } void parseWeather(SP_XmlElementNode *node) { //extracts current weather XML data fields for LCD SP_XmlHandle handle(node); SP_XmlElementNode * condition = handle.getChild( "condition" ).toElement(); lcd.cls(); lcd.printf("LA:"); if (condition) { lcd.printf("%s ",condition->getAttrValue("data")); } SP_XmlElementNode * tempf = handle.getChild( "temp_f" ).toElement(); if (tempf) { lcd.printf(" %sF\n",tempf->getAttrValue("data")); } SP_XmlElementNode * humidity = handle.getChild( "humidity" ).toElement(); if (humidity) { lcd.printf("%s",humidity->getAttrValue("data")); } } int main() { // the eth and HTTP code has be taken directly from the HTTPStream documentation page // see http://mbed.org/cookbook/HTTP-Client-Data-Containers lcd.cls(); lcd.printf("net setup"); EthernetErr ethErr = eth.setup(); if (ethErr) { lcd.printf("\n\rError in setup"); return -1; } lcd.printf("\n\r net ok"); SP_XmlDomParser parser; HTTPStream stream; char BigBuf[512 + 1] = {0}; stream.readNext((byte*)BigBuf, 512); //Point to buffer for the first read //Google Weather API for Los Angeles - get web page with XML HTTPResult r = http.get("http://www.google.com/ig/api?weather=Los+Angeles", &stream, request_callback); while (!completed) { Net::poll(); //Polls the Networking stack if (stream.readable()) { BigBuf[stream.readLen()] = 0; //Transform this buffer in a zero-terminated char* string parser.append( BigBuf, strlen(BigBuf)); // stream current buffer data to the XML parser stream.readNext((byte*)BigBuf, 512); //Buffer has been read, now we can put more data in it } } lcd.cls(); if (result == HTTP_OK) { lcd.printf(" Read complete\n\r"); } else { lcd. printf(" Error %d\n", result); return -1; } SP_XmlHandle rootHandle( parser.getDocument()->getRootElement() ); SP_XmlElementNode * child2 = rootHandle.getChild( "weather" ) .getChild( "current_conditions").toElement(); if ( child2 ) { parseWeather(child2); //parses XML "current-conditions" info } if ( NULL != parser.getError() ) { lcd.printf( "\n error: %s\n", parser.getError() ); } }
The code sets up networking and reads a special Google web page containing XML data with weather using http.get(). Data extracted from this XML web page is then displayed in the LCD using the TextLCD library lcd.printf() function. Here is a typical web page of XML data in response to http://www.google.com/ig/api?weather=Los+Angeles
Google_Weather_API_XML_page
<?xml version="1.0" ?> - <xml_api_reply version="1"> - <weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0"> - <forecast_information> <city data="Los Angeles, CA" /> <postal_code data="Los Angeles" /> <latitude_e6 data="" /> <longitude_e6 data="" /> <forecast_date data="2012-04-20" /> <current_date_time data="2012-04-21 00:47:00 +0000" /> <unit_system data="US" /> </forecast_information> - <current_conditions> <condition data="Clear" /> <temp_f data="65" /> <temp_c data="18" /> <humidity data="Humidity: 70%" /> <icon data="/ig/images/weather/sunny.gif" /> <wind_condition data="Wind: N at 5 mph" /> </current_conditions> - <forecast_conditions> <day_of_week data="Fri" /> <low data="61" /> <high data="73" /> <icon data="/ig/images/weather/mostly_sunny.gif" /> <condition data="Mostly Sunny" /> </forecast_conditions> - <forecast_conditions> <day_of_week data="Sat" /> <low data="55" /> <high data="72" /> <icon data="/ig/images/weather/mostly_sunny.gif" /> <condition data="Mostly Sunny" /> </forecast_conditions> - <forecast_conditions> <day_of_week data="Sun" /> <low data="57" /> <high data="68" /> <icon data="/ig/images/weather/mostly_sunny.gif" /> <condition data="Mostly Sunny" /> </forecast_conditions> - <forecast_conditions> <day_of_week data="Mon" /> <low data="57" /> <high data="68" /> <icon data="/ig/images/weather/mostly_sunny.gif" /> <condition data="Mostly Sunny" /> </forecast_conditions> </weather> </xml_api_reply>
Note that the data needed is found above under -<current_conditions>. After reading the web page and finding -<current_conditions> , the XML parser is used in parseWeather() to extract the data fields needed for use in the LCD display. Change the city at the end of the URL to obtain weather for another city. In this code, long XML web pages from other URLs containing several thousand characters can consume all of the available RAM memory on mbed and cause out of memory errors. In such cases, file I/O could be used. Another option is to process the XML data as read streams in each block of data and release the memory buffers (to avoid running out of memory) as it is parsed in sequential order.
Import programweather_LCD_display
Displays weather info on text LCD using Google API
Video of Demo Code
When the USB cable is plugged in, mbed powers up and contacts the DHCP server to get an IP address. It gets an IP address and responds with "net OK". It then reads the web page containing the XML with the current weather, parses the XML to extract the data, and displays it on the LCD.
More on Web APIs
There are a large number of other web APIs (also called web services) available. This web API directory has almost 6,000 listed. Some are free, free for non-profit use, require registration and a key, or perhaps free for a limited number of calls, but most require a license and a paid subscription fee. The availability of web APIs is changing rapidly and checking the directory could be useful to find new resources. Google has a history of offering new APIs for free and then charging for them later. Some examples include the Google speech recognition and translation APIs. This could happen in the future with the Google weather API.
Ideas for Further Enhancements
1. Display your cities weather by changing the URL suffix.
2. Automatically update weather info every few minutes.
3. In case of a network error, delay several seconds and automatically retry.
4. Alternate between current conditions and the forecast.
5. Alternate with the Weather Channel RSS feed for the city.
6. Investigate using the IP address or GPS to automatically guess the city.
7. Add a severe weather alert alarm feature with pushbuttons and a speaker. The speaker will likely need a driver circuit. In the USA, see http://www.nws.noaa.gov/rss/ and http://alerts.weather.gov/.
8. Use a wireless network connection with a WiFly module or other wireless device.
9. Use Power over Ethernet (PoE) to power the clock and avoid the extra wires for power. Sparkfun has one PoE option.
10. Instead of pushbuttons, use touch switch input.
11. Add a temperature sensor and add indoor temperature to the display.
12. Upgrade to a larger display such as a color LCD or VGA.
13. Try the Yahoo Weather API. Here is an example: http://xml.weather.yahoo.com/forecastrss?p=USCA1116. The last argument value is the country state and zipcode.
13. Investigate using some of the other weather web APIs.
5 comments on Weather LCD Display:
Please log in to post comments.
Dear Jim, very interesting program and it works very well on French cities, but it doesn't works if I upgrate the HTTPClient Library ; several input files from this library couldn't be open > every "core/" and "api/" files. What is the solution with the new library ? Thanks CTophe