NMEA 0183 is the standard output protocol of GPS devices. This library makes it possible to write GPS applications for your Wiring i/o board, without knowing exactly how the NMEA protocol works. The library searches for 'sentences' in the output of a GPS receiver, and does checksum verification. Output from a GPS receiver will typically appear every second and contain different types of sentences. It looks like

$GPGGA,082804.683,5205.9421,N,00506.4368,E,1,03,3.0,0.3,M,,,,0000*01 $GPRMC,082804.683,A,5205.9421,N,00506.4368,E,0.02,146.61,190408,,*0C $GPBDG,082804.683,A,52.09904,5.10728,0.02,146.61,1,190408,*73

The NMEA:: library contains two basic constructs for connecting to a GPS's data stream, some routines for decoding sentences of type GPRMC specifically, some routines for calculating directions and distances, and several routines decoding for more advanced sentence types. All routines come with example code of how to use them.

Arduino Users

This library was developed for Wiring boards, the more powerful predecessor of Arduino. I do not have an Arduino board, so I could not test it, but I heard reports that Arduino's do not have enough memory. It runs fine on Wiring boards.
Based on my NMEA library, Mikal Hart created TinyGPS for Arduino. It does not contain the "distance_to" and "course_to" functions, however.

Data Connection

These two constructs together form the heart of the library. Basically, you set up a data connection of type NMEA and then use the routine decode() to interpret data from the GPS. Just look into the example code provided with them to see how to use them.

NMEA
Data connection to GPS receiver

decode()
Decodes data from GPS receiver

GPRMC Routines

These routines provide easy access to 'GPRMC' type sentences. GPRMC type sentences are available from every GPS receiver, and for most applications they provide all the data you need. For example, they contain your exact position, speed, and direction of movement. For most projects, or if you are new to dealing with GPS data, these routines are all you need.

gprmc_status()
Returns status of GPS positioning

gprmc_utc()
Returns exact time of GPS positioning

gprmc_latitude()
Returns latitude of GPS position

gprmc_longitude()
Returns longitude of GPS position

gprmc_speed()
Returns speed-over-ground

gprmc_course()
Returns direction of movement

Distance and Direction Calculations

I included easy-to-use routines for geographic distance and course calculation. They are great for many projects! Given the last GPRMC sentence received, they simply tell you how far a geographic point is, and in what direction you should travel to get there.

gprmc_distance_to()
Returns distance to a given position on Earth

gprmc_course_to()
Returns direction to a given position on Earth

Advanced Use

If you want to access other than GPRMC sentences only, you can use some additional routines. Different GPS receivers will output different types of sentences. For example, you may want to know exactly how many satellites are used in the location fix, by reading the 8th term in a GPGGA type sentence. The following routines offer direct access to the last sentence received, which can be of any datatype.

sentence()
Returns the last sentence received

terms()
Returns the number of terms in the last sentence received

term()
Returns a specific term from the last sentence received

term_decimal()
Returns decimal value of a specific term from the last sentence received

libversion()
Returns the version number of this library

Code Examples and Applications

Basic positioning with GPRMC sentence type
Determining speed
Determining distance to destination
Determining course to destination
Connecting to all sentence types

Very simple GPS navigation tool with LCD display
It shows the direction and distance to a destination on an LCD display. Photos of the Wiring/GPS/LCD hardware setup are included.

Technical Details

The NMEA:: library connects to the Application Layer of the NMEA 0183 protocol. It assumes that sentences are no longer than 100 characters and contain no more than 30 terms (including both datatype and checksum terms). Also it assumes that terms contain no more that 15 characters each. A two-digit checksum term in capitalized hexadecimal MSB-first notation is required. Sentences with faulty syntax, structure, or checksum value are discarded without notification. Sentences of both known (e.g. $GPRMC, $GPGGA, $GPRMB) and unknown (e.g. $HELLO, $FOO, $FOOBAR) datatypes are correctly decoded, given these constraints.

Distance and direction are calculated over 'great-circle' paths on a perfect sphere. This method does not take into account terrain height variations, and Earth is no perfect sphere. As a result, calculated values may be slightly off. Distance is estimated to be off 0.5% at most. For direction, the error is expected to be negligible.

Objects of class NMEA allocate substantial memory, be aware of this in heavy-duty applications or on tiny hardware platforms. The source code was written in the Wiring language and is slightly optimized for processing speed. Decoding of incoming characters was kept very simple and happens fairly fast. However, when a complete GPRMC sentence is received, calculation of floating point values requires some heavy processing.

References

When writing this library, I scraped much information off the web. My main sources were

Dale DePriest's NMEA page
Wikipedia page about the geographic coordinate system
Aviation Formulary V1.43 (for distance and course calculations)
Writing a Library for Arduino
Wiring and Arduino websites

Download

To use the library, download the zipped file below. It contains a directory named 'NMEA'. Copy it into the 'libraries' folder under your Wiring/Arduino installation directory. Then restart the Wiring/Arduino programming environment.

NMEA library version 1 (Zip format)
The first basic version of the library. Only tested with Wiring i/o board, not with Arduino. The example code may not function correctly on Arduino.

Tested Platforms

Wiring-0015 i/o board with µ-Blox GPS-PS1E receiver module.

Feedback

Feel free to send me feedback on the NMEA:: library, for example on which platforms (i/o board and GPS receiver) it was successfully tested. I will do my best to answer you. My webpage http://www.maartenlamers.com/ tells you how to reach me.

No Warranty

Remember, this is free software written by me for fun, not money. I am an amateur developer. As a result of this, it comes absolutely WITHOUT ANY WARRANTY! Think of this before you use it in your boat, car or model airplane.

License and Distribution

Creative Commons License
The NMEA library for Wiring by Maarten Lamers is licensed under a Creative Commons Attribution-Share Alike 3.0 Netherlands License. Basically, you can share this work and make derivative works from it, as long as you attribute this library to my name and you distribute the resulting work under a similar license. See here for the details.

Oh, and remember, this product come with absolutely no warranty whatsoever!