Geolocation and NTP clock on uLCD-144-G2

Geolocation with new mbed Networking Library

After wiring properly, the following code is able to go to a geolocation database and return geographic information based on the IP address the user sends to the database. If no IP address is specified, the database defaults to using the user's IP address and sends back the information corresponding to the user's IP address. The Website we use is http://ip-api.com/. It provides multiple formats to return the geolocation data to the user. We use the CSV format to simplify parsing the data. If using the CSV format, the data is outputted in the following way.

Output from IP-API.com

success,COUNTRY,COUNTRY CODE,REGION CODE,REGION NAME,CITY,ZIP CODE,LATITUDE,LONGITUDE,TIME ZONE,ISP NAME,ORGANIZATION NAME,AS NUMBER / NAME,IP ADDRESS USED FOR QUERY

Therefore, one can simply parse through the string and extract any needed information. In our display, we extract all information but only display

  • Country Code (Ex. US)
  • Region Code (Ex. NY)
  • City (Ex. Buffalo)
  • Zip Code
  • Latitude & Longitude
  • Time Zone (Ex. Americas/New York)

One needs to use an HTTP GET request to *http://ip-api.com/csv* in order to get the data for the user's IP address. Refer to the mbeds pages on Ethernet and TCP/IP Protocol stack for information regarding HTTP, TCP and Ethernet for the mbed.

NTP Clock

The NTP Clock uses UDP instead of TCP to get the time from the NTP Server (refer to mbed networking pages for differences between protocols). This functionality is built into the NTPClient library. There are multiple domain names a user can use to get UTC time data from. The one we use in this demo is us.pool.ntp.org. The function setTime builtin to the NTPClient library allows the user to fetch the data from the server and update the mbed clock.

List of Steps in Program

  • Gets IP address through DHCP so the mbed can connect to the Internet
  • Issues an HTTP GET request to the Geolocation Database to receive Geolocation info
  • Parses the data received from the Geolocation Database
  • Issues request to the NTP Server to get the time from the server
  • Offsets the Time for the Eastern Time Zone (US) and updates every tenth of a second

Displays all results on the uLCD.

Code for both GeoLocation and NTP Clock on mbed

GeoLocation and NTP Clock main program

#include "mbed.h"
#include "NTPClient.h"
#include "uLCD_4DGL.h"
#include "EthernetInterface.h"
#include "HTTPClient.h"

//SET UP ULCD
EthernetInterface eth;
uLCD_4DGL uLCD(p9,p10,p11); // serial tx, serial rx, reset pin;
NTPClient ntpClient;
HTTPClient httpClient;
void parse(char buffer[], int *j, char *string); //FUNCTION TO PARSE HTTP GET DATA
char httpGetData[200]; //BUFFER TO HOLD DATA FROM HTTP GET REQUEST




int main() {
    time_t ctTime; //system time structure
    uLCD.baudrate(2000000); //Crank up Baudrate
    uLCD.cls();    //Clear uLCD screen
    uLCD.background_color(WHITE); //SET BACKGROUND COLOR TO WHITE
    //SETS THE BACKGROUND COLOR OF TEXT TO WHITE ON THE ULCD
    uLCD.textbackground_color(WHITE);
    uLCD.locate(0,0);  //Start printing on col0, row0
    uLCD.printf("Getting IP Address\n"); //Print to uLCD
    eth.init(); //USE DHCP to get local IP address
    eth.connect(); //Connect to the network
    uLCD.printf("IP ADDRESS is %s\n",eth.getIPAddress()); //Get Ethernet Address and display It on ULCD
    wait(3.0);
    char success[10]={0};  //success first
    char countryFull[20]={0}; //Full Country Name
    char countryAbrv[5]={0}; //Abbreviated Country Name or country Code
    char stateAbrv[5]={0}; //Abbreviated State or region code
    char stateFull[15]={0}; //Full State Name
    char city[15]={0}; //City Name
    char zip[6]={0}; //ZIP CODE
    char latitude[10]={0}; //latitude
    char longitude[10]={0}; //longitude
    char timeZone[30]={0}; //timeZone
    int j=0;
    uLCD.printf("Getting Geolocation Data\n");
    //HANDLES THE HTTP GET REQUEST THE WAY THE FUNCTION IS CALLED HERE IS THE FOLLOWING
    // get(DOMAIN_NAME,BUFFER,TIMEOUT_VAL)
    //DOMAIN_NAME= domain name that get request is sent to
    //BUFFER= buffer to store data returned from the server
    //TIMEOUT_VAL= Time before the request times out
    HTTPResult r = httpClient.get("http://ip-api.com/csv",httpGetData,128); //GET GEOLOCATION DATA (CSV)
    
    if (r==HTTP_OK) { //IF THE DATA WAS RECIEVED
        j=0;
        //parse and display each of the API's location information strings on the LCD
        parse(httpGetData, &j, success); 
        parse(httpGetData,&j,countryFull);
        parse(httpGetData,&j,countryAbrv);
        parse(httpGetData,&j,stateAbrv);
        parse(httpGetData,&j,stateFull);
        parse(httpGetData,&j,city);
        parse(httpGetData,&j,zip);
        parse(httpGetData,&j,latitude);
        parse(httpGetData,&j,longitude);
        parse(httpGetData,&j,timeZone);
        uLCD.cls();
        uLCD.printf("GEOLOCATION DATA RECIEVED\n");  
    } 
    else { //HTTP GET REQUEST ERRORED
        uLCD.cls();
        uLCD.printf("HTTP Error %d", r);
        return -1;
    }
    uLCD.printf("Reading Time...\n");
    char* domainName="us.pool.ntp.org"; //SET TO DOMAIN NAME OF SERVER GETTING TIME FROM
    //GETS THE TIME FROM THE SERVER
    //setTime(DOMAIN_NAME,PORT_NUMBER,TIME_OUT)
    //DOMAIN_NAME= domain name
    //PORT NUMBER=port number (123 for NTP)
    //TIME_OUT= timeout value for request
    ntpClient.setTime(domainName,123,0x00005000);
    uLCD.printf("Time Set\n");
    //Delay for human time to read LCD display
    wait(3.0);
    uLCD.cls();
    //SETS THE BACKGROUND COLOR OF TEXT TO WHITE ON THE ULCD
    uLCD.textbackground_color(WHITE);
    char buffer[80]; //BUFFER TO HOLD FORMATTED TIME DATA
    uLCD.color(BLUE);//SET TEXT COLOR TO BLUE
    uLCD.locate(0,8);
    uLCD.printf("%s, %s %s\n",city,stateAbrv,zip); //PRINT CITY STATE AND ZIP INFORMATION
    uLCD.printf("%s\nLAT:%s\nLONG:%s\n",countryAbrv,latitude,longitude); //PRINT COUNTRY and LATITUDE AND LONGITUDE 
    uLCD.printf("Timezone:\n%s",timeZone); //PRINT TIMEZONE
    uLCD.color(RED);
    eth.disconnect(); //DISCONNECT FROM THE NETWORK 
    uLCD.text_height(2); //2x Text Height
    while (1) {
        // loop and periodically update the LCD's time display
        uLCD.locate(0,0);
        ctTime = time(NULL)-(3600*4);  //TIME with offset for eastern time US
        //FORMAT TIME FOR DISPLAY AND STORE FORMATTED RESULT IN BUFFER
        strftime(buffer,80,"%a %b %d\n%T %p %z\n %Z\n",localtime(&ctTime));
        uLCD.printf("Univ Time Clock\n%s", buffer);
        wait(.1);
    }  
}






//SET FOR CSV FORMAT: NEEDS TO BE EDITED IF DIFFERENT FORMAT
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++) {  //TOTAL SIZE OF RETURNED DATA
        if ((buffer[*j+i] == ',')||(buffer[*j+i] == '\0' )) { //IF comma or end of string
            //comma is the string field delimiter
            string[i]=0; //SETS END OF SRTRING TO 0
            *j=*j+i+1; //UPDATES to 1 after comma seperated value
            break;
        } else string[i]=buffer[*j+i]; //Keep adding to the string
    }
}

Picture of Finished Project

/media/uploads/tlisowski3/img_1291.jpg

Video of Finished Project

Wiring

Ethernet Magjack Connector

/media/uploads/tlisowski3/screen_shot_2014-03-18_at_8.24.53_pm.png

uLCD-144-G2

/media/uploads/tlisowski3/screen_shot_2014-03-18_at_8.19.37_pm.png


Please log in to post comments.