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
Video of Finished Project
Wiring
Ethernet Magjack Connector
uLCD-144-G2
Please log in to post comments.
