Weather Nokia LCD Display

WLC
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 Nokia-LCD library.

GDC
Google's Largest Server Farm is near a hydroelectric power plant in Oregon. It might wind up responding to your weather API call.

/media/uploads/4180_1/weatherchannel.jpg
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 Nokia LCD clock example, News Nokia LCD Display, and Geolocation Nokia LCD Display.

Ethernet Magjack Connector

MbedSparkfun 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.

Sparkfun Nokia LCD Breakout

Mbed pinsSparkfun Nokia LCD pins
GndGnd
p5 (mosi)DIO
p7 (sclk)SCK
p8CS
p9Reset
Vout (3.3V)3.3V
Vout (3.3V)Vbat

Note: There are two versions of the Sparkfun Nokia LCD breakout board. This code runs on the older version seen below. Look for the blue inductor near the center and note the arrangement of the two small pushbuttons.

/media/uploads/4180_1/_scaled_oldnokialcd.jpg
Older Sparkfun Nokia LCD Breakout board.

The newer version (Feb 2012) shown below needs a different version of the NokiaLCD driver code available at http://mbed.org/media/uploads/wasp/nokialcd.zip. I will update the code example and post both versions once I have a new one to try out on it.

/media/uploads/4180_1/_scaled_nokialcd.jpg
New Sparkfun Nokia LCD Breakout board.

Example Code

#include "mbed.h"
#include "EthernetNetIf.h"
#include "HTTPClient.h"
#include "spdomparser.hpp"
#include "spxmlnode.hpp"
#include "spxmlhandle.hpp"
// 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
#include "NokiaLCD.h"

NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type
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.locate(0,2);
    lcd.printf("LA:");
    if (condition) {
        lcd.printf("%s ",condition->getAttrValue("data"));
    }
    SP_XmlElementNode * tempf = handle.getChild( "temp_f" ).toElement();
    if (tempf) {
        lcd.printf(" %sF",tempf->getAttrValue("data"));
    }
    SP_XmlElementNode * humidity = handle.getChild( "humidity" ).toElement();
    if (humidity) {
        lcd.locate(0,3);
        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.locate(0,2);
    lcd.printf("net setup");
    lcd.locate(0,3);
    EthernetErr ethErr = eth.setup();
    if (ethErr) {
        lcd.printf("Error in setup");
        return -1;
    }
    lcd.printf("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();
    lcd.locate(0,2);
    if (result == HTTP_OK) {
        lcd.printf(" Read complete");
    } else {
        lcd. printf(" Error %d", 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_Nokia_LCD_display

Uses Google Weather API to display current conditions for a city on a Nokia LCD. See http://mbed.org/users/4180_1/notebook/weather-nokia-lcd-display/

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 LCD display 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.


1 comment on Weather Nokia LCD Display:

02 May 2013

http://mbed.org/users/lballiet91/notebook/nokia-lcd-weather-application/ has a version running on Yahoo's API. The Google weather API is no longer free.

Please log in to post comments.