Hand to hand with GPS
Episode: 2
NMEA Messages
As we all know, what is GPS?
GPS is a system, widely used throughout the globe. It recites versatile superfluous
information including position, speed, time, altitude very precisely. Its having
diverse applications like navigation, tracking, tracing, location, timing and very soon
it will be very essential indigence for human being as same as the telephone.
Now briefly we see the constituents of GPS. It uses between 24 and 32 Medium
Earth Orbit satellites that transmit precise microwave signals. A GPS receiver
receives that microwave signals to determine the above mentioned information. It
was developed by United States for defence purpose, but now it can be accessed by
everyone freely.
The important questions are, how can we use GPS? , what information we can
get? So now a days it is very easy to use GPS, many of the electronic gazettes around
us are loaded with GPS and these are having very easy to use graphical user
interface. Tracking, navigation, mapping can be done with the help of these gazettes.
But to make customize systems that use GPS as per our requirement, we just require
a GPS receiver.
A GPS receiver is a chip that receives microwave signals from satellites, converts
that signals to a particular message protocol like NMEA and gives serial output. We
can use that serial output in our system. The canonical hassle is to understand the
protocol of NMEA. We are going to describe an algorithm that takes serial input,
analyze it and recites the superfluous information.
The algorithm is very easygoing, can be implemented to any programming
language, any embedded system’s compiler like Keil, AVR studio, winAVR, Keil for
ARM etc.
What is NMEA message format?, National Marine Electronics Association (NMEA)
is an organisation that is creating standards for marine electronics to unify the
systems. In GPS’s context NMEA standards are the communication protocol,
followed by GPS receiver to give serial output.
Fig 1 | Understanding NMEA messages.
The diagram shows that a GPS receiver receives microwave signals from
satellite system and gives output in NMEA messages. NMEA messages are
basically packets of data or information. GPS receiver delivers information
line by line, here we refer these lines as the packets of information. These
messages are classified in various types of packets. Each packet has its own
protocol to send the information. These packets are identified by their
names. GPS receiver sends these packets serially, every second it delivers a
packet of information.
Fig 2 | understanding of NMEA Packets
First five character of a packet represent the packet name, and other
superfluous information separated by comma.
Ie. $GPVTG,176.41,T,,M,0.00,N,0.00,K,A*38
Here ‘$GPVTG’ is packet name and it is followed by other information.
Fig 3 | Actual NMEA messages
Important NMEA message packets.
a. GGA – Global Positioning System Fix Data
b. GLL – Geographic Position – Latitude/Longitude
c. GSA – DOP and Active Satellites
d. GSV – Satellites in view
e. RMC – Recommended Minimum Specific GNSS Data
f. VTG – Course Over Ground and Ground Speed
a. $GPGGA - Global Positioning System Fix Data
Data/Information : Time, Position, Numbers of satellite used, altitude
etc.
Message format:
$GPGGA,hhmmss.ss,LLmm.llll,{N/S},yyymm.mmmm,{E/W},i,ns,h.d,a.h,M,
g.s,M,a.s,XXXX*CS
Index Message Discription
0 $GPGGA Packet name (Global Positioning System Fix Data)
1 hhmmss.ss UTC Time hh : hours mm : minutes ss.ss : seconds
2 LLmm.mmmm Latitude LL : Degree mm.mmmm = minutes
3 {N/S} North or South
4 yyymmm.mmmm Longitude yyy : Degree mmm.mmmm : minutes
5 {E/W} East or West
6 i Valid indicator (Fix value) 0: Not valid 1: Valid
7 ns Number satellites used
8 h.d HDOP : Horizontal Dilution Of Precision
9 a.h Altitude
10 M Antenna height Unit (meters)
11 g.s Difference between the WGS-84 reference ellipsoid surface and the mean-sea-level altitude.
12 M Unit of above parameter (meters)
13 a.s Age in seconds since last update
14 XXXX Reference station ID
15 CS Check Sum
Table 1 | GGA Packet format
b. $GPGLL – Geographic Position – Latitude/Longitude
Data/Information: Position, UTC time, and status etc.
Packet format:
$GPGLL,LLmm.mmmm,{N/S},yyymm.mmmm,{E/W},hhmmss.ss,i,m*CS
Index Message Discription
0 $GPGLL Packet name (Geographic Position – Latitude/Longitude)
1 LLmm.mmmm Latitude LL : Degree mm.mmmm = minutes
2 {N/S} North or South
3 yyymmm.mmmm Longitude yyy : Degree mmm.mmmm : minutes
4 {E/W} East or West
5 hhmmss.ss UTC Time hh : hours mm : minutes ss.ss : seconds
6 i Status indicator A : valid V : invalid
7 m Mode indicator A: autonomous N: data not valid
8 CS Check sum
Table 2 | GLL Packet format
c. $GPGSA – DOP and Active Satellites
Data/Information : Operating mode, satellite used in fix position and DOP etc.
Packet format:
$GPGSA,i,j,aa,aa,aa,aa,aa,aa,aa,aa,aa,aa,aa,aa,p.d,h.d,v.d*CS
Index Message Discription
0 $GPGSA Packet name (DOP and Active Satellites)
1 i : Mode M : Manual, forced to operate in 2D or 3D A : Automatic, 3D/2D
2 J : Mode 1 : Fix not available 2 : 2D 3 : 3D
3 aa Ids of Satellites used in position fix , null for unused
4 p.d PDOP
5 h.d HDOP
6 v.d VDOP
7 CS Check sum
Table 3 | GSA packet format
d. $GPGSV : GPS Satellites in view
Data/information : Messages, messages id, satellite id, elevation, azimuth etc.
Packet format:
$GPGSV,N,M, ns,si,se,saz,sn,…………. , ns,si,se,saz,sn *CS
Index Message Discription
0 $GPGSV Packet name (GPS Satellites in view)
1 N Number of messages
2 M Message Number
3 ns Number of satellites in view
4 si Satellites ID
5 Se Satellites Elevation
6 saz Satellite azimuth
7 sn SNR number
8-19 3 set of 4-7 Satellites information
20 CS Checksum
Table 4 | GSV packet format
e. $GPRMC – Recommended Minimum Specific GNSS Data
Data/information : Time, Date, Position, speed and status etc.
Packet Format:
$GPRMC,hhmmss.ss,i,LLmm.mmmm,{N/S},yyymm.mmmm,{E/W},s.n,t.c,DDMMYY,m.v,
{E/W},
m*CS<CR><LF>
Index Message Discription
0 $GPRMC Packet name (Recommended Minimum Specific GNSS Data)
1 hhmmss.ss UTC Time hh : hours mm : minutes ss.ss : seconds
2 i Valid indicator 0: Not valid 1: Valid
3 LLmm.mmmm Latitude LL : Degree mm.mmmm = minutes
4 {N/S} North or South
5 yyymmm.mmmm Longitude yyy : Degree mmm.mmmm : minutes
6 {E/W} East or West
7 s.n Speed in Knots
8 t.c True Course/ Heading
9 DDMMYY Date
10 m.v Magnetic variation
11 {E/W} East or West
12 m Mode indicator A: autonomous N: data not valid
13 CS Check Sum
Table 5 | RMC packet format
f. $GPVTG – Course Over Ground and Ground Speed
Data/Information: Speed and course.
Packet format:
$GPVTG,m.v,T,m.h,M,s.n,N,s.k,K,m*CS<CR><LF>
Index Message Discription
0 $GPVTG Packet name (Course Over Ground and Ground Speed)
1 m.v Magnetic Variation / heading
2 T Fixed text (Heading unit degree)
3 m.h Magnetic heading
4 M Degree, magnetic heading unit
5 s.n Speed in Knots
6 N Speed unit Knots
7 s.k Speed in KM per Hour
8 K Speed unit KM / hr
9 m Mode indicator A: autonomous N: data not valid
10 CS Check sum
Table 4 | GSV packet format
Algo for extracting GPS data
form NMEA messages
Step 1. Create connection with GPS receiver.
Step 2. While RX: go to Step 3 –
Step3. Message = Read Line (Rx data)
Step4. if ( message [0:2] ! = ‘$GP’ ) – we are not getting NMEA messages / packets
{
Break – go to step 3.
}
. else – we are getting NMEA messages.
{
Step 5. if (message [0:5+ = = ‘$GPGGA’ )
{
Fragments [] = explode(“,” message)
if (Fragments [2] == ‘’” OR Fragments [4] == “‘’)
{
latitude or longitude can’t be determined
Break loop – go to step 3
}
UTCTime = Fragments[1]
– Format :- hhmmss.ss
UTCTime = UTCTime *0:1+ . “:”.UTCTime *2:3+ . “:”.UTCTime *4:5+
– Format :- hh:mm:ss
Latitude = Fragments [2]
-Format :- xxmm.dddd
Latitude = Latitude[0:1] + Latitude[2:8] / 60
-Format :- Decimal format
Loc_N/S = Fragments[3]
Longitude = Fragments[4]
-Format:- yyymm.dddd
Longitude = Longitude[0:2] + Longitude [3:9] / 60
-Format :- Decimal format
Loc_E/W = Fragments[5]
Fix = Fragments[6]
Nos_satellite = Fragments[7]
HDOP = Fragments[8]
Altitude = Fragments[9]
Break – go to step 3.
}
Step6. if (message *0:5+ = = ‘$GPGLL’ )
{
Fragments *+ = explode(“,” message)
if (Fragments *1+ == ‘’” OR Fragments *3+ == “‘’)
{
latitude or longitude can’t be determined
Break loop – go to step 3
}
Latitude = Fragments [1]
-Format :- xxmm.dddd
Latitude = Latitude[0:1] + Latitude[2:8] / 60
-Format :- Decimal format
Loc_N/S = Fragments[2]
Longitude = Fragments[3]
-Format:- yyymm.dddd
Longitude = Longitude[0:2] + Longitude [3:9] / 60
-Format :- Decimal format
Loc_E/W = Fragments[4]
UTCTime = Fragments[5]
– Format :- hhmmss.ss
UTCTime = UTCTime *0:1+ . “:”.UTCTime *2:3+ . “:”.UTCTime *4:5+
– Format :- hh:mm:ss
Status = Fragments[6]
Mode = Fragments [7]
Break – go to step 3.
}
Step7. if (message *0:5+ = = ‘$GPGSA’ )
{
Fragments *+ = explode(“,” message)
Mode_a = Fragments[1]
Mode_b = Fragments[2]
Operating_setellites = Fragments[3]
PDOP = Fragments[4]
HDOP = Fragments[5]
VDOP = Fragments[6]
Break – go to step 3.
}
Step8. if (message *0:5+ = = ‘$GPGSV’ )
{
Fragments *+ = explode(“,” message)
Nos_messages = Fragments[1]
Message_No = Fragments[2]
Nos_setellites = Fragments[3]
Satellite_ID = Fragments[4]
Satellite_elevation = Fragments[5]
Satellite_azimuth = Fragments[6]
SNR_No = Fragments[7]
Break – go to step 3.
}
Step 9. if (message *0:5+ = = ‘$GPRMC’ )
{
Fragments *+ = explode(“,” message)
if (Fragments *3+ == ‘’” OR Fragments *5+ == “‘’)
{
latitude or longitude can’t be determined
Break loop – go to step 3
}
UTCTime = Fragments[1]
– Format :- hhmmss.ss
UTCTime = UTCTime *0:1+ . “:”.UTCTime *2:3+ . “:”.UTCTime *4:5+
– Format :- hh:mm:ss
Status = Fragments[2]
Latitude = Fragments [3]
-Format :- xxmm.dddd
Latitude = Latitude[0:1] + Latitude[2:8] / 60
-Format :- Decimal format
Loc_N/S = Fragments[4]
Longitude = Fragments[5]
-Format:- yyymm.dddd
Longitude = Longitude[0:2] + Longitude [3:9] / 60
-Format :- Decimal format
Loc_E/W = Fragments[6]
Speed = Fragments[7]
Heading = Fragments[8]
Date = Fragments[9]
-format :- ddmmyy
Date = Date*0:1+. “-”. Date*2:3+. “-”. Date*4:5+
-Format:- dd-mm-yy
Magnetic_variation = Fragments[10]
Mode = Fragments[12]
Break – go to step 3.
}
Step10. if (message *0:5+ = = ‘$GPVTG’ )
{
Fragments *+ = explode(“,” message)
Heading = Fragments[1]
Heading_unit = Fragments[2]
Magnetic_heading = Fragments[3]
Magnetic_heading_unit= Fragments[4]
Speed_knots= Fragments[5]
Speed_unit_knots = Fragments[6]
Speed_KM = Fragments[7]
Speed_unit_KM = Fragments[8]
Mode = Fragments[9]
Break -go to step. 3
}
Break – go to step 3.
}
Explanation for some functions used in algo :
Message[i:j] : here message in a string that stores a packet in it.
Message[i:j] : represent a substring of message from index i to j elements (note i
and j both are included).
Explode : it splits the string in to fragments by a specific character, here we are splitting
message by comma “,”, and it stores all the fragments in to an array named
fragments[].
Other notations are common notations for many programming languages like C, C++.
User can use either full or partial algorithm according to requirement.