Skip to content
El Stepherino edited this page Jun 6, 2018 · 31 revisions

NMEA-0183 Parser Library in C#

This is a basic NMEA-0183 parser that processes bytes fed into its API. When a complete NMEA sentence is successfully read, application-level handlers are invoked.

There are many implementations of NMEA-0183 parsers out there. This is not about reinventing the wheel, but as an exercise on my part to port NMEA parsing code that I wrote over 12 years ago in C++. The motivation to put this up on Github came after I was invited to apply for work with the condition that I pass a coding tests. Having been on the hiring end of the coding interview, I can say that coding tests are utterly useless when compared to actual code samples on Github. So here I am with samples that - at the very least - depicts my coding style.

This is a clean and fairly easy to extend implementation.

Quick Example

This is the simplest scenario: using the DefaultNmeaHandler class. DefaultNmeaHandler implements the contract INmeaHandler, which defines support for the following NMEA-0183 data types:

  • GGA : Global Positioning System Fix Data
  • GSA : Satellite status
  • GSV : Satellites in view
  • GST : GPS Pseudorange Noise Statistics
  • HDT : NMEA heading log
  • RMC : Recommended Minimum data for gps
  • VTG : Track made good and ground speed

DefaultNmeaHandler implements the contract by invoking the event handler LogNmeaMessage each time a supported NMEA sentence is successfully parsed.

using Invernesspark.Utilities.NMEA;

...

// ... Create an object to handle parsed NMEA messages
DefaultNmeaHandler nmeaHandler = new DefaultNmeaHandler() ;
nmeaHandler.LogNmeaMessage += str => {
    Console.WriteLine("New NMEA Message: {0}", str ) ;
};

// ... Create the NMEA receiver
NmeaReceiver nmeaReceiver = new NmeaReceiver( nmeaHandler ) ;

// ... Attach handler for NMEA messages that fail NMEA checksum verification
nmeaReceiver.NmeaMessageFailedChecksum += (bytes, index, count, expected, actual) => {
    Console.Error.WriteLine("Failed Checksum: {0}; expected {1} but got {2}",
        Encoding.ASCII.GetString(bytes.Skip(index).Take(count).ToArray()),
        expected, actual );
};

// ... Attach handler for NMEA messages that contain invalid syntax
nmeaReceiver.NmeaMessageDropped += (bytes, index, count, reason) => {
    Console.WriteLine("Bad Syntax: {0}; reason: {1}",
        Encoding.ASCII.GetString(bytes.Skip(index).Take(count).ToArray()),
        reason );
};

// ... Attach handler for NMEA messages that are ignored (unsupported)
nmeaReceiver.NmeaMessageIgnored += (bytes, index, count) => {
    Console.WriteLine("Ignored: {0}", 
        Encoding.ASCII.GetString(bytes.Skip(index).Take(count).ToArray()));
};

// ... Your byte receiving logic...
bool keepReceiving = true ;
while ( keepReceiving ) {
    byte [] bytesReceived = /* receive some bytes from socket, file, whatever... */ 

    // ... Feed the bytes into the NMEA receiver
    nmeaReceiver.Receive( bytesReceived ) ;
}

The above code will invoke the appropriate callbacks each time a NMEA sentence is received.

Class Diagram

Clone this wiki locally