Geolocation Nokia LCD Display

geolcd

Geolocation API used to determine the location of mbed based on the IP address. The city is displayed on the LCD. Larger Image

Geolocation is the geographic location of an object such as a computer or cell phone. This is typically accomplished using the IP address, WiFi signal strength, or GPS data. If latitude and longitude are available from a GPS, Yahoo’s Placefinder API will convert it into a city and address or vice versa. AskGeo has a timezone API using the latitude and longitude that is free for non-commercial use. Many web browsers and cell phones have geolocation apps. Not every device has a GPS and GPS will not work inside large buildings and urban canyons.

IP-based Geolocation

When GPS data is not available and a device has a network connection, the IP address can be used to estimate location. It is a complex near random mapping and only a very large database can be used to determine the location.

/media/uploads/4180_1/ipv4-assignments-07.png
IP4 address map from ICANN 2007.

In the map above, blue is North America, yellow is Europe, purple is Asia-Pacific, green is Latin America/Caribbean, and orange is Africa. Dark grey is space that, for protocol reasons cannot be assigned, and black is the space for a special kind of assignment called Multicast. Without a large data base, it would be difficult to even get the continent correct. Commercial data bases are available from several vendors to map IP addresses to cities and time zones. There is even a new geolocation API standard, W3C Geolocation API. Web sites often use geolocation to adjust content for each locale and to detect fraud in ecommerce transactions. The time zone setting can come in handy for local time settings.

Google has a Latitude API used on many smartphones such as Android and iPhone, but a special key is needed along with a prior user authorization step to disclose location. Some social networking apps use it to determine the location of your friends. As one would imagine, disclosing a precise location raises privacy concerns on devices such as cell phones. Skyhook also works off a database of Wi Fi and cell tower locations, but a license is required. Commercial APIs are also available from Quova and Fraud Labs. iPInfoDB also has a free API but registration is required to obtain a key used in the URL. The iPinfoDB API returns the location of an IP address (country, region, city, zipcode, latitude, longitude) and the associated time zone in a simple text format and is easier to use. There are also a number of web pages that will use a device’s external IP address and report the device’s location at least to perhaps the city level. A device can access them free to determine location (at least a few times a day before it gets locked out). Here are some sites to try:

http://www.ip2location.com
http://www.maxmind.com/app/locate_my_ip
http://www.ipligence.com/geolocation
http://whatismyipaddress.com

For a quick geolocation demo with mbed (without a user key), the web page from one of these sites can be read, and by parsing the web page’s HTML the data can be used for display in the LCD. In a web browser, use view source to examine the HTML to find the data fields of interest and search for the strings that can be used to locate and recover the data in a program. Of course the problem with this approach is that any changes to their IP location web page will require a program update, unlike something like the Google Latitude API or the iPInfoDB API. In most cases, it would likely require a change in the search strings. For the demo, the iPInfoDB API was used after getting a free key via email.

Wiring

The same hardware and wiring setup is used as the Internet Nokia LCD Clock, Weather Nokia LCD Display and News 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 location 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

Note

To run the demo code you need to obtain a free key by filling out a short web form at iPInfoDB. Then click on the link in the email. This code must be added as a suffix to the URL in the source code to run it on your mbed. Find http://api.ipinfodb.com/v3/ip-city/?key=PUT_YOUR_API_KEY_HERE in the source code after downloading it.


Import programGeoLocation_Nokia_LCD_Display

Geolocation demo using Nokia LCD. See http://mbed.org/users/4180_1/notebook/geolocation-nokia-lcd-display/


#include "mbed.h"
#include "EthernetNetIf.h"
#include "HTTPClient.h"
//Geolocation using IP address - get web page with location data
// displays location fields on LCD  from web page ";....location text...;"
// see http://mbed.org/users/4180_1/notebook/geolocation-lcd-display/
#include "NokiaLCD.h"

NokiaLCD lcd(p5, p7, p8, p9, NokiaLCD::LCD6610); // mosi, sclk, cs, rst, type
EthernetNetIf eth;
HTTPClient http;

void parse(char buffer[], int *j, char *string) {
//extracts next location string data item from buffer
    int i=0;
    for (i=0; i<=strlen(buffer); i++) {
        if ((buffer[*j+i] == ';')||(buffer[*j+i] == '\0' )) {
            //semicolon is the string field delimiter
            string[i]=0;
            *j=*j+i+1;
            break;
        } else string[i]=buffer[*j+i];
    }
}

int main() {
    char result [4]={0};
    char ip [17]={0};
    char country_abbr[10]={0};
    char country[60]={0};
    char region[40]={0};
    char city[60]={0};
    char zipcode[10]={0};
    char latitude[10]={0};
    char longitude[10]={0};
    char timezone[7]={0};
    char buffer[256]={0};
    float flatitude=0.0;
    float flongitude=0.0;
    float ftimezone=0.0;
    int j=0;

    //Setup network - get IP address using DHCP
    lcd.cls();
    lcd.locate(0,2);
    lcd.printf("Net setup");
    lcd.locate(0,3);
    EthernetErr ethErr = eth.setup();
    if (ethErr) {
        lcd.printf("Error %d", ethErr);
        return -1;
    }
    lcd.printf(" Net OK");
    wait(.5);
    lcd.cls();
    lcd.locate(0,2);
    lcd.printf("IP Address");
    lcd.locate(0,3);
    lcd.printf("Geolocation API");
    HTTPText txt;
    //iPinfoDB API  - get web page with location data
    //Insert your free key from www.ipinfo.com for the API in the URL below
    HTTPResult r = http.get("http://api.ipinfodb.com/v3/ip-city/?key=<PUT_YOUR_API_KEY_HERE>", &txt);
    if (r==HTTP_OK) {
        //got web page text data OK
        strcpy(buffer,txt.gets());
        wait(1);
        while (1) {
            j=0;
            //parse and display each of the API's location information strings on the LCD
            parse(buffer, &j, result);
            lcd.cls();
            lcd.locate(0,2);
            lcd.printf("result: %s", result);
            if (result[0]!='O') { //needs valid key
                wait(1);
                lcd.cls();
                lcd.locate(0,2);
                lcd.printf("Get Free API key");
                lcd.printf("www.iPinfoDB.com");
                return(-1);
            }
            wait(1);
            j++;
            parse(buffer, &j, ip);
            lcd.locate(0,2);
            lcd.printf("IP address:");
            lcd.locate(0,3);
            lcd.printf(" %s", ip);
            parse(buffer, &j, country_abbr);
            lcd.locate(0,4);
            lcd.printf("Country code:");
            lcd.locate(0,5);
            lcd.printf(" %s", country_abbr);
            parse(buffer, &j, country);
            lcd.locate(0,6);
            lcd.printf("Country:");
            lcd.locate(0,7);
            lcd.printf(" %s", country);
            parse(buffer, &j, region);
            lcd.locate(0,8);
            lcd.printf("Region or State:");
            lcd.locate(0,9);
            lcd.printf(" %s", region);
            parse(buffer, &j, city);
            lcd.locate(0,10);
            lcd.printf("City:");
            lcd.locate(0,11);
            lcd.printf(" %s", city);
            parse(buffer, &j, zipcode);
            lcd.locate(0,12);
            lcd.printf("Zipcode:");
            lcd.locate(0,13);
            lcd.printf("  %s", zipcode);
            wait(5);
            parse(buffer, &j, latitude);
            sscanf(latitude,"%f",&flatitude);
            lcd.cls();
            lcd.locate(0,2);
            lcd.printf("Latitude:");
            lcd.locate(0,3);
            lcd.printf(" %f", flatitude);
            parse(buffer, &j, longitude);
            sscanf(longitude,"%f",&flongitude);
            lcd.locate(0,4);
            lcd.printf("Longitude:");
            lcd.locate(0,5);
            lcd.printf(" %f", flongitude);
            parse(buffer, &j, timezone);
            sscanf(timezone,"%f",&ftimezone);
            lcd.locate(0,6);
            lcd.printf("Timezone:");
            lcd.locate(0,7);
            lcd.printf(" %f", ftimezone);
            wait(4);
        }
    } else {
        lcd.cls();
        lcd.locate(0,2);
        lcd.printf("HTTP Error %d", r);
        return -1;
    }
}

Example Geolocation API Data from web

The data returned by the API contains several string fields terminated by a semicolon (and not a space), so it is very easy to parse.

Example_Location_Data

OK;;98.88.128.174;US;UNITED STATES;GEORGIA;ATLANTA;30324;33.809;-84.3548;-05:00

As seen above, the API returns the location of the external IP address (country, region, city, zipcode, latitude, longitude) and the associated timezone. Accuracy is very high on country and a bit lower on the city. If the city is incorrect, it is typically another city located within a few miles. The database is updated every month and some ISPs report changes quicker than others. Some city names require the use of UTF-8 coding. The API key code is free for non-commercial use, but the terms of use require that each user signup for his own key.

Here is another example in a different country of the API response for mbed.org (IP=217.140.96.42 from nslookup).

Example_Data_for_mbed.org

OK;;217.140.96.42;UK;UNITED KINGDOM;ENGLAND;CAMBRIDGE;-;52.205;0.144;+00:00

Demo Video


Geolocation using the IP address to determine where mbed is located.

More on Time Zones

If longitude data was available a rough estimate would be timezone=int(longitude/(360/24)) but it is a bit more complex than that. A large database needs to be checked and the timezone value is not always an integer!

/media/uploads/4180_1/time-zone.png
Time zone map from AskGeo API database.

"The vertical stripes in the open ocean are the natural time zones implied solely by the longitude. Time zones that don't observe Daylight Savings Time (DST) are colored the same as their corresponding natural time zone; those that do are colored slightly darker but with the same hue. Time zones that do not use an offset from UTC that is an integer number of hours have a color that is a proportional mixture of the colors of the bracketing natural time zones (e.g., Iran and India)."

As an example, here is the geolocation API response from an IP address at the Indian Institute of Technolgy. Note the timezone of 5:30 at the end.

OK;;202.141.68.2;IN;INDIA;DELHI;NEW DELHI;-;28.6328;77.2195;+05:30

Ideas for further enhancements

1. Register at iPInfoDB, get a key, and run the code on your mbed to check your location.
2. Use the time zone information to set the local time on the Internet LCD clock.
3. Use the city information for a local weather forecast in the Weather LCD display.
4. Fix the code that scans the time zone so that it works for non-integer timezone values.
5. Register at Google, get a key, and develop code to use Google’s Latitude API.
6. Add a GPS and use Yahoo’s Placefinder API to display the local address.
7. Add a GPS and use AskGeo's timezone API to set the time zone on the Internet LCD clock.


Please log in to post comments.