Microcontroller Based City Locator using GPS and LCD
[nextpage title=”Description” ]The GPS receiver is used to get accurate geographical location by receiving information from satellites. It receives information from satellites and gives location information in terms of latitude and longitude. It gives latitude and longitudes with accuracy of degree-minute-second. Using this latitude and longitude co-ordinates one can easily trace out the location on entire globe. The GPS receivers have enormous applications. Some of are listed here.
GPS receivers are used in
· All aircrafts, ships, see vessels, vehicles etc for navigation purpose
· In smart phones with maps (like Google map) to find a way to the destination or to spot any landmark/restaurant/hospital/hotel
· Autonomous vehicles to find proper path to destination
· In missile or bomb to locate and hit the target
The GPS receiver gives output serially in form of strings with NMEA (National Marine Electronics Association) 0183 protocol. These strings are received serially by host computer or host processor/controller for display or to take any decision or action. The following figure shows the output of GPS receiver on hyper terminal of desktop computer.
NMEA Protocol:
The NEMA protocol gives standard and messages given by GPS receiver. Some of the standard messages output from NMEA are GGA, ZDA, VTC, RMC, GSA, GSV etc. There are 50 messages from NMEA but only some are applied to GPS receiver. The maximum length of every message is limited to 79 characters. The format of NMEA is given and explained as under
$IDMSG,D1,D2……Dn*CS,(CR)(LF)
- $ – indicates start of each message
- ID – indicates source of navigation information. In this case it will be GP because of GPS
- MSG – describes message contents like GGA, GSV, GSA etc
- , – it’s a separation between data
- D1 – Dn – they are data fields separated by comma
- *– it is used to separate checksum
- CS – its checksum value in HEX
- (CR)(LF) – Its carriage returns + line feed that indicates end of message
From the start tag notation it can be identified that what kind of information will be available in following string. Like
· The string starts with $GPGGA tag gives time, latitude, longitude, altitude, GPS quality and some other information
· The string starts with $GPZDA tag gives date and time information
The given project demonstrates how to get location (latitude and longitude) information from GPS receiver and if that received co-ordinates corresponds to any Indian city then it also displays name of the city. It uses 8 bit micro controller AT89C51 to get data from GPS receiver and display it on LCD. The latitude and longitude co-ordinates are given in two different strings that start with $GPRMC tag or $GPGGA tag. This strings are highlighted in above figure and also in the string where is latitude-longitude co-ordinates that is also highlighted. One can extract these co-ordinates from any of the string. I have extracted it from GPRMC string. RMC stands for recommended minimum GNSS data. GPRMC string is explained in more detail below.
GPRMC string format:
The complete string is of 65 to 70 characters including start tag. The string starts with $ and start tag GPRMC. After the start tag next is time in GMT. Then there is location information that includes latitude with direction and longitude with direction. There are 9 characters in latitude. First two represents degree (33o in this case) second represents minute (54’ here) and after decimal point last 4 represents seconds (1133” here). Latitude direction follows latitude and can be ‘N’ or ‘S’. Longitude is represented by next 10 characters. It is similar to latitude but there are three digits (characters) in degree (151o in this case). The micro controller extracts this string from GPS output, extracts location information details and display them on LCD in proper format. Then it matches the co-ordinates with co-ordinates of different Indian cites. If it found any match then the name of city is displayed as “its a Ahmedabad” or “its a Delhi”.
System block diagram:
There are only four major building blocks of the system.
GPS receiver – it collects information from satellite and generates output in form of different strings. It gives these strings as output to micro controller
MAX232 – it is a level converter chip. It converts RS232 level signals given by GPS receiver into TTL level signals that can be given to micro controller.
AT89C51 micro controller – it receives all the strings from GPS receiver but extracts only one string. It extracts location information from string and displays them on LCD in proper format
LCD panel – it is used to display location information and name of city
System circuit diagram:
(See the circuit diagram tab for microcontroller based city locator using GPS & LCD)
Circuit description
As shown in figure, the circuit is build using three major components only, RS232 level convertor chip MAX232, 89C51 micro controller and 16×2 LCD panel.
· The GPS module has three terminal for interfacing named Tx, Rx and Gnd. It gives series of strings as serial output through its Tx pin. So Tx pin is connected to RS232 level side input pin R2IN (pin 8)
· The output is taken from TTL level side output pin R2OUT (pin no 9) and that is given to serial receive pin Rx (pin 10) of AT89C51
· Capacitors C1 – C4 are connected with MAX232 chip as per its suggested circuit in its datasheet
· PORT2 pins P2.0 – P2.7 drives data pins of LCD D0 – D7. The control pins Rs, RW and En of LCD are connected to PORT3 pins P3.7, P3.6 and P3.5 respectively
· A 1 KΩ pot is connected to pin 3 of LCD as shown to vary its brightness
· A 12 MHz crystal along with two 22 pF capacitors is connected to crystal input pins 18 and 19 of AT89C51 as shown
· The complete circuit works on 5 V supply
Circuit operation:
Complete circuit operation depends upon GPS receiver module. GPS receiver module gives 10 different strings as output that contains various information like longitude, latitude, altitude, date, time, speed, number of satellite in visibility, validity of received signal, signal strength etc. It gives all 10 strings one by one – character by character to micro controller.
Micro controller AT89C51 is the heart of complete circuit. It performs following tasks
· It receives series of strings from GPS module
· It extracts require string from bunch of string received in real time
· From the extracted string, further it extracts location information
· At last it displays this information on LCD panel
· It continuously receives data from GPS module in real time and updates LCD after every 4 second
AT89C51 will receive all strings character by character. Out of these 10 strings, it extracts the string that starts with $GPRMC. All other strings it just simply discards. From the string following $GPRMC tag, the micro controller will extract only latitude and longitude along with its direction.
After extracting information it displays them on LCD panel as
- Latitude – latitude direction and degree-minute-second
- Longitude – longitude direction and degree-minute-second
These Latitude and longitude are compared with latitude-longitude of major cities of INDIA like Mumbai, Delhi, Ahmedabad, channai, Kolkata, Bangluru, Bhopal, Pune, Jaipur etc. When there is a perfect match between co-ordinates (received co-ordinates and city co-ordinates) the message is displayed on LCD as “It’s a Ahmedabad”. The city name is displayed for around 5 seconds and again the latitude and longitude are displayed. So if GPS receiver is steady at one location in city it will display city name again and again.
Note: in this project, for demonstration I have used lat-long co-ordinates of most of the metro cities of INDIA like Mumbai, Delhi, Bangaluru, Ahmedabad, Jaipur etc. Their co-ordinates are as per the data available on internet. The name of the city will be only displayed when received co-ordinate matches with the specified co-ordinates exactly in degree and minute. One can change the co-ordinates in the program for same city or enters completely new co-ordinates for any other city. It may be better to enter co-ordinates of cities of any one state only. For just a slight modification if any one enters co-ordinates of different land-marks of city-town with name of places instead of name of cities then this project can be used to locate different landmarks of city.
Software program:
The functionalities of micro controller is due to the program embedded into its internal FLASH. The software program is written in C language using KEIL (IDE) software. The program is compiled using keil cross compiler. When program is compiled successfully it generates HEX file. This HEX file is loaded into AT89C51 using suitable EEPROM programmer.
The C program is made up of 9 different functions described as follows
LCD handling functions
- LCD_cmd – this function sends 8 bit command (character) to LCD to initialize or configure it
- LCD_data – this function sends 8 bit data (character) to LCD that will be displayed on screen
- LCD_write_string – this function displays complete string (message) on LCD screen
- Init_LCD – this function initializes LCD in 8 bit mode, 8×5 dots/character etc
USART handling function
- Init_usart – it initializes built in USART and set baud rate to 4800 bps
- usart_getch – it returns one character (8-bit data) received from serial port
Display functions
- display_latitude – it displays received latitude on LCD in degree-minute-second format
- display_longitude – it displays received longitude on LCD in degree-minute-second format
- get_city_name() – it calculates co-ordinate value, matches it with city co-ordinates and when match found displays name of city
Along with these 9 user defined functions there is one main function. It initializes ports as input or output. Then it initializes LCD and USART and enters into continuous loop. It this continuous loop it first wait until it gets first 5 characters as $, G, P, R, M and C. When it gets all these 5 characters in sequence, that means it’s the required string with $GPRMC tag. From this string, one by one, it extracts latitude and longitude. In the standard format of GPS string, the required values are given between two comas. So the program will start collecting characters (data) from one coma and continue it till next coma. Here is complete software program with necessary comments
#include <reg51.h>
//#define LCD_DATA_PORT P2 //LCD data port
sbit rs = P3^7; //enable signal
sbit rw = P3^6; //read/write signal
sbit en = P3^5 ; //resister select signal
unsigned char value,lati_value[10],lati_dir, longi_value[11], longi_dir;
unsigned int t;
void lcd_busy()
{
int p;
for(p=0;p<2000;p++);
}
void LCD_cmd(unsigned char cmd)
{
lcd_busy();
rw=0;
rs=0;
P2 = cmd;
en=1;
en=0;
}
void LCD_data(unsigned char dat)
{
lcd_busy();
rw=0;
rs=1;
P2 = dat;
en=1;
en=0;
}
void init_LCD()
{
LCD_cmd(0x38); //initialization of 16X2 LCD in 8bit mode
LCD_cmd(0x0E); //cursor ON
LCD_cmd(0x01);
LCD_cmd(0x80); // —8 go to first line and –0 is for 0th position
}
void init_USART()
{
TMOD=0x20;
SCON=0x40;
TH1=0xFD;
TL1=0xFD;
TR1=1;
REN=1;
}
unsigned char usart_getch()
{
while(RI==0);
RI=0;
return(SBUF);
}
void LCD_write_string(char *str) //take address vaue of the string in pionter *str
{
int i=0;
while(str[i]!=’\0′) // loop will go on till the NULL charaters
{
LCD_data(str[i]); // sending data on CD byte by byte
i++;
}
return;
}
void display_lat()
{
LCD_cmd(0x80);
LCD_write_string(“lt:”);
LCD_data(lati_dir);
LCD_data(0x20);
LCD_data(lati_value[0]);
LCD_data(lati_value[1]);
LCD_data(0xDF);
LCD_data(lati_value[2]);
LCD_data(lati_value[3]);
LCD_data(0x27);
LCD_data(lati_value[5]);
LCD_data(lati_value[6]);
LCD_data(lati_value[7]);
LCD_data(lati_value[8]);
LCD_data(0x22);
}
void display_logn()
{
LCD_cmd(0xC0);
LCD_write_string(“lg:”);
LCD_data(longi_dir);
LCD_data(longi_value[0]);
LCD_data(longi_value[1]);
LCD_data(longi_value[2]);
LCD_data(0xDF);
LCD_data(longi_value[3]);
LCD_data(longi_value[4]);
LCD_data(0x27);
LCD_data(longi_value[6]);
LCD_data(longi_value[7]);
LCD_data(longi_value[8]);
LCD_data(longi_value[9]);
LCD_data(0x22);
}
void delay_5sec()
{
int i,j;
for(i=0;i<100;i++)
for(j=0;j<10000;j++);
}
void get_city_name()
{
unsigned int value1,value2,value3;
unsigned int lati_degree,lati_minute,longi_degree,longi_minute;
value1 = lati_value[0]-0x30;
value2 = lati_value[1]-0x30;
lati_degree = value1*10+value2;
value1 = lati_value[2]-0x30;
value2 = lati_value[3]-0x30;
lati_minute = value1*10+value2;
value1 = longi_value[0]-0x30;
value2 = longi_value[1]-0x30;
value3 = longi_value[2]-0x30;
longi_degree = value1*100+value2*10+value3;
value1 = longi_value[3]-0x30;
value2 = longi_value[4]-0x30;
longi_minute = value1*10+value2;
if((lati_degree==28) && (lati_minute==61) && (longi_degree==77) && (longi_minute==23))
{
LCD_cmd(0x01);
LCD_write_string(“It’s a Delhi”);
delay_5sec();
}
else if((lati_degree==26) && (lati_minute==92) && (longi_degree==75) && (longi_minute==82))
{
LCD_cmd(0x01);
LCD_write_string(“It’s a Jaipur”);
delay_5sec();
}
else if((lati_degree==23) && (lati_minute==03) && (longi_degree==72) && (longi_minute==58))
{
LCD_cmd(0x01);
LCD_write_string(“It’s a Ahmedabad”);
delay_5sec();
}
else if((lati_degree==18) && (lati_minute==97) && (longi_degree==72) && (longi_minute==82))
{
LCD_cmd(0x01);
LCD_write_string(“It’s a Mumbai”);
delay_5sec();
}
else if((lati_degree==23) && (lati_minute==25) && (longi_degree==77) && (longi_minute==41))
{
LCD_cmd(0x01);
LCD_write_string(“It’s a Bhopal”);
delay_5sec();
}
else if((lati_degree==22) && (lati_minute==56) && (longi_degree==88) && (longi_minute==36))
{
LCD_cmd(0x01);
LCD_write_string(“It’s a Kolkata”);
delay_5sec();
}
else if((lati_degree==12) && (lati_minute==96) && (longi_degree==77) && (longi_minute==56))
{
LCD_cmd(0x01);
LCD_write_string(“It’s a Bengaluru”);
delay_5sec();
}
else if((lati_degree==13) && (lati_minute==8) && (longi_degree==80) && (longi_minute==27))
{
LCD_cmd(0x01);
LCD_write_string(“It’s a Channai”);
delay_5sec();
}
}
int main(void)
{
P2=0x00; //LCD_DATA port as out put port
P3=0x0F; //ctrl as out put
init_LCD(); //initialization of LCD
LCD_write_string(” GPS DEMO”);
LCD_cmd(0xC0);
LCD_write_string(” using AT89C51″);
init_USART(); // initialization of USART
while(1)
{
value=usart_getch();
if(value==’$’)
{
value=usart_getch();
if(value==’G’)
{
value=usart_getch();
if(value==’P’)
{
value=usart_getch();
if(value==’R’)
{
value=usart_getch();
if(value==’M’)
{
value=usart_getch();
if(value==’C’)
{
value=usart_getch(); while(value!=’,’) // wait upto next “,”
{ value=usart_getch(); } value=usart_getch();
while(value!=’,’) // wait upto next “,”
{
value=usart_getch();
} value=usart_getch(); while(value!=’,’) // wait upto next “,”
{
value=usart_getch();
} lati_value[0] = usart_getch();
value = lati_value[0];
for(t=1;value!=’,’;t++)
{
lati_value[t] = usart_getch();
value = lati_value[t];
}
lati_dir=usart_getch();
value = usart_getch();
longi_value[0] = usart_getch();
value = longi_value[0];
for(t=1;value!=’,’;t++)
{
longi_value[t] = usart_getch();
value = longi_value[t];
}
longi_dir=usart_getch(); LCD_cmd(0x01); display_lat();
display_logn();
get_city_name(); }
}
}
}
}
}
}
}