The Global Positioning System (GPS) is a satellite-based navigation system that provides location and time information of the GPS device in all weather conditions, anywhere on or near the Earth, where there is an unobstructed line of sight to four or more GPS satellites.
A GPS module is a device that uses Global Positioning System to determine the location of a vehicle or person. GPS receivers are used to provide reliable navigation, positioning and timing services to the users at anytime and anywhere on the earth. This Global positioning system uses a minimum of 4 satellites to provide the data to the receivers. If the GPS receiver is only able to get signals from 3 satellites, you can still get your position, but it will be less accurate. As mentioned above, the GPS receiver needs 4 satellites to determine the position in 3-dimensions. 0Gps.png

GPS Module Specs

Name Description
Volatge Vmin=3.6v and Vmax=6v (Tested with 5v)
Time To Start Cold Start 29s(Average under Open Sky)

Warm Start 28s(Average under Open Sky)
Hot Start 1s(Average under Open Sky)
InDoor: GPS modules take more time to get valid data and some times won't work.

Interface Full Duplex Serial Interface(UART)
Baud Rate Default-9600, Also supports 4800/9600/38400/115200
Start Bit 1-bit
Stop Bit 1-bit
Data Bits 8-bit
Parity None
Update Rate Default 1Hz, Also supports 1/2/4/5/8/10
Ouput Frames GPGGA, GPGSA, GPGSV, GPRMC and GPVTG


GPS Frame Formats

The serial interface protocol is based on the National Marine Electronics Association’s NMEA 0183 ASCII interface specification. GpsLog.png

GGA-GLOBAL POSITIONING SYSTEM FIX DATA

Time, position and fix related data for a GPS receiver. $GPGGA,hhmmss.sss,ddmm.mmmm,a,dddmm.mmmm,a,x,xx,x.x,x.x,M,x.x,M,x.x,xxxx*hh<CR><LF>

GLL - LATITUDE AND LONGITUDE, WITH TIME OF POSITION FIX AND STATUS

Latitude and longitude of current position, time, and status. $GPGLL,ddmm.mmmm,a,dddmm.mmmm,a,hhmmss.sss,A,a*hh<CR><LF>

GSA - GPS DOP AND ACTIVE SATELLITES

GPS receiver operating mode, satellites used in the navigation solution reported by the GGA or GNS sentence and DOP values.
$GPGSA,A,x,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,x.x,x.x,x.x*hh<CR><LF>

GSV - GPS SATELLITE IN VIEW

Numbers of satellites in view, PRN number, elevation angle, azimuth angle, and C/No. Four satellites details are transmitted per message. Additional satellite in view information is sent in subsequent GSV messages. $GPGSV,x,x,xx,xx,xx,xxx,xx,…,xx,xx,xxx,xx *hh<CR><LF>

RMC - RECOMMENDED MINIMUM SPECIFIC GPS/TRANSIT DATA

Time, date, position, course and speed data provided by a GNSS navigation receiver. $GPRMC,hhmmss.sss,A,dddmm.mmmm,a,dddmm.mmmm,a,x.x,x.x,ddmmyy,x.x,a,a*hh<CR><LF>

VTG - COURSE OVER GROUND AND GROUND SPEED

The Actual course and speed relative to the ground. $GPVTG,x.x,T,x.x,M,x.x,N,x.x,K,a*hh<CR><LF>

GPRMC Frame Decoding

We will be using this frame for GPS data (time, lat-long). Below table provides the informtion encoded in the GPS frame. $GPRMC,hhmmss.sss,A,dddmm.mmmm,a,dddmm.mmmm,a,x.x,x.x,ddmmyy,x.x,a,a*hh<CR><LF> $GPRMC,110831.000,A,1304.8763,N,07733.6457,E,0.79,303.84,010116,,,A*68

Field Name Data Description
1 UTC Time 110831.000 UTC Time in hhmmss.sss format (000000.000 - 235959.999)
2 Status A Data Validity A-Valid, V-Invalid(Navigation Warning)
3 Latitude 1304.8763 Latitude in dddmm.mmmm format, leading zeros transmitted
4 N/S Indicator N Latitude hemisphere indicator, N-North S-South
5 Longitude 07733.6457 Longitude in dddmm.mmmm format, leading zeros transmitted
6 E/W Indicator E Longitude hemisphere indicator, E-East W-West
7 Speed Over Ground 0.79 Speed Over Ground in Knots (000.0 ~ 999.9)
8 Course Over Ground 303.84 Course Over Ground in degrees (000.0 ~ 359.9)
9 UTC Date 010116 UTC Date in ddmmyy format
10 Magnetic variation Magnetic variation in degrees(000.0 ~ 180.0)
11 Magnetic variation Magnetic variation Direction, E-East W-West
12 Mode Indicator A N - Data Not Valid

A - Autonomous Mode
D - Differential Mode
E - Estimated Mode
M - Manual Input Mode
S - Simulator Mode

13 Checksum 68

Below is the sample code to decode the above frame

/***************************************************************************************************
Struct/Enums used
****************************************************************************************************/
/* Time S Lat P Long P Date
$GPRMC,110831.000,A,1304.8763,N,07733.6457,E,0.79,303.84,010116,,,A*68
*/
#define TIME_INDEX 7
#define STATUS_INDEX 18
#define LAT_INTEX 20
#define NS_POLE_INTEX 30
#define LONG_INDEX 32
#define EW_POLE_INTEX 43
#define DATE_INDEX 57
typedef struct
{
uint8_t lat[10];
uint8_t log[11];
uint8_t timeUTC[7];
uint8_t dateUTC[7];
uint8_t timeIST[7];
uint8_t dateIST[7];
uint8_t gpsStatus; //V-Invalid, A-Valid
uint8_t northSouthPole; //N-North S-South
uint8_t eastWestPole; //E-East W-West
uint8_t newDataReceived; // not for user, do not modify this value.
}gpsData_st;
/**************************************************************************************************/
char idata GpsDataLog[70]; // Buffer to store GPS frame $GPRMC,110831.000,A,1304.8763,N,07733.6457,E,0.79,303.84,010116,,,A*68
gpsData_st idata GpsData;
uint8_t idata V_StartLogging_U8 = 0,index_u8,ch;
const code daysPerMonth[12] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
/***************************************************************************************************
Serial ISR
****************************************************************************************************
* I/P Arguments: none
* Return value : none
* description : This serial ISR will continously receive the GPS data and store in the GpsDataLog buffer.
Since we will be using GPRMC data, logging starts once 'R' is detected in gps data frame.
At the end of the frame(\n), the status(A/V) will be evaluated for validity of gps data.
If the data is valid, then it will be coped to gpsData structure elements.
***************************************************************************************************/
void serial_isr() interrupt 4
{
if(RI == 1)
{
RI = 0;
ch = SBUF;
if(V_StartLogging_U8 == 1)
{
if(ch!='\n') //Keep storing the data till end of frame('\n');
{
GpsDataLog[index_u8++] = ch;
}
else
{ /* end of frame('\n') is received, stop logging and
extract the data into respective elements */
V_StartLogging_U8 = 0;
GpsData.newDataReceived = 1;
for(index_u8=0;index_u8<6;index_u8++)
{ /* Copy the time and date from the gpsLog */
GpsData.timeUTC[index_u8] = GpsDataLog[index_u8+TIME_INDEX];
GpsData.dateUTC[index_u8] = GpsDataLog[index_u8+DATE_INDEX];
GpsData.dateIST[index_u8] = GpsDataLog[index_u8+DATE_INDEX];
}
GpsData.gpsStatus=GpsDataLog[STATUS_INDEX];
if(GpsData.gpsStatus == 'A')
{ /* If gps data is valid then copy the lattitide(9-bytes) and longitude(10-bytes) */
for(index_u8=0;index_u8<9;index_u8++)
{ /* Copy 9bytes of lat-long in one for loop,
Remaining 1 byte of long is captured later */
GpsData.lat[index_u8] = GpsDataLog[index_u8+LAT_INTEX];
GpsData.log[index_u8] = GpsDataLog[index_u8+LONG_INDEX];
}
GpsData.log[9] = GpsDataLog[9+LONG_INDEX];
GpsData.eastWestPole = GpsDataLog[EW_POLE_INTEX]; //East/West Pole
GpsData.northSouthPole = GpsDataLog[NS_POLE_INTEX]; //North/South Pole
}
}
}
else if(ch == 'R')
{ /* $GPRMC is used as data frame, so wait till 'R' is received then start logging.
And set the index to 4 (to start logging from M) */
V_StartLogging_U8 = 1;
index_u8 = 4;
}
}
}

Code

Below is the sample code to receive the GPS data, decode it and display it on LCD.

/***************************************************************************************************
ExploreEmbedded Copyright Notice
****************************************************************************************************
* File: main.c
* Version: 16.0
* Author: ExploreEmbedded
* Website: http://www.exploreembedded.com/wiki
* Description: This file contains the sample program to read the GPS data and display it on LCD
This code has been developed and tested on ExploreEmbedded boards.
We strongly believe that the library works on any of development boards for respective controllers.
Check this link http://www.exploreembedded.com/wiki for awesome tutorials on 8051,PIC,AVR,ARM,Robotics,RTOS,IOT.
ExploreEmbedded invests substantial time and effort developing open source HW and SW tools, to support consider buying the ExploreEmbedded boards.
The ExploreEmbedded libraries and examples are licensed under the terms of the new-bsd license(two-clause bsd license).
See also: http://www.opensource.org/licenses/bsd-license.php
EXPLOREEMBEDDED DISCLAIMS ANY KIND OF HARDWARE FAILURE RESULTING OUT OF USAGE OF LIBRARIES, DIRECTLY OR
INDIRECTLY. FILES MAY BE SUBJECT TO CHANGE WITHOUT PRIOR NOTICE. THE REVISION HISTORY CONTAINS THE INFORMATION
RELATED TO UPDATES.
Permission to use, copy, modify, and distribute this software and its documentation for any purpose
and without fee is hereby granted, provided that this copyright notices appear in all copies
and that both those copyright notices and this permission notice appear in supporting documentation.
**************************************************************************************************/
#include <reg51.h>
#include <string.h>
#include "stdutils.h"
#include "gps.h"
#include "lcd.h"
int main()
{
/*Connect RS->P0.0, RW->P0.1, EN->P0.2 and data bus to P0.4 to P0.7*/
LCD_SetUp(P0_0,P0_1,P0_2,P_NC,P_NC,P_NC,P_NC,P0_4,P0_5,P0_6,P0_7);
LCD_Init(4,20);
GPS_Init();
while(1)
{
if(GPS_ReadData() == 1) // Display the data on LCD whenever new frame is received
{
LCD_GoToLine(0);
LCD_DisplayString("UTC: ");
LCD_DisplayString(GpsData.timeUTC); //Display Universal Time
LCD_GoToLine(1);
LCD_DisplayString("IST: ");
LCD_DisplayString(GpsData.timeIST); //Display Indian Standard Time(UTC+5:30)
LCD_GoToLine(2);
LCD_DisplayString("Lat: ");
LCD_DisplayString(GpsData.lat); //Display Latitude
LCD_DisplayChar(GpsData.northSouthPole); //Display N/S Pole
LCD_GoToLine(3);
LCD_DisplayString("Long:");
LCD_DisplayString(GpsData.log); //Display Longitude
LCD_DisplayChar(GpsData.eastWestPole); //Display E/W Pole
}
}
return (0);
}


Track on Google Maps

Lat = 1304.8763,N = 13+(04.8763/60) = 13.0812716666666667
Long = 07733.6457,E = 77+(33.6457/60) = 77.560761666666667
Now lets paste these values 13.0812716666666667, 77.560761666666667 on google maps and track the location.

GpsMap.PNG