Introduction

NMEA 0183 is a combined electrical and data specification for communication between marine electronic devices such
as echo sounder, sonars, anemometer, gyrocompass, autopilot, GPS receivers, and many other types of instruments.

NMEA 0183 standard uses a text-based (ASCII) serial communications protocol. It defines
the rules for transmitting "sentences" from one "talker" to multiple listeners.

Yes, there are many different NMEA sentence parser implementations in C#. But
I have not found any implementation with a full list of talker IDs and sentence IDs.
So, this is my attempt to make it.

Shortly about NMEA 0183 protocols

There are two layers in NMEA 0183:

data link layer

application layer protocol

In fact, data link layer defines only serial configuration:

bit rate (typically 4800)

8 data bits

no parity checking

1 stop bit

no handshake

Application layer is more complex, but not so. A common NMEA sentence format
is listed below:

NMEA defines two types of sentences: proprietary and non-proprietary. Non-proprietary sentences
have a one of standard two-letter talker ID (e.g., GP for GPS unit, GL for glonass unit, etc.), and one of
standard
three-letter sentence ID (e.g., GLL for geographic location GPS data, DBK - depth below keel, and so on).
All of these talker IDs and sentence IDs can
be found in the official paper.
Non-proprietary sentences have a 'P' letter instead of the standard talker ID, followed by
a three-letter standard manufacturer code (GRM for Garmin, MTK for MTK, etc.),
and further follows
any string - name of proprietary command (depends on the specific manufacturer).
Maximum length for sentences – 82 characters.

I will explain it with an example for a (standard) 'GLL' GPS sentence:

You see that the key in this dictionary – formatting string, and value –
Func<string, object>,
is initialized as a lambda expression for compactness. And now we can create a method for parsing a list of data fields, obtained from
the NMEA sentence:

May be it is not the best way for implementation, but I use container classes for standard and proprietary sentences, returning in
the Parse method.
Both classes are inherited from the base class NMEASentence:

Using the Code

Notice, if you use a .NET Framework version lower than 3.5 you need to add a conditional compilation constant:

FRAMEWORK_LOWER_35

NMEAParser also can build NMEA0183 sentences. There are two
methods for building sentences: BuildSentence and BuildProprietarySentence.
You can use these methods with an instance of the NMEAStandartSentence
or NMEAProprietarySentence class as a parameter:

Extra Info

An extra info: You can see in the ParseToken method that I add some extra functionality, especially there
is a new data type – arrays; For formatters for arrays,
use the following syntax: “[<standard>]”, values must be separated by ‘|’. Also I added ‘byte arrays’ with formatting string “h—h”.
A byte array data field must be like
this: “0x4d5a0023…”, with hexadecimal values of bytes.

Points of Interest

Did you learn anything interesting/fun/annoying while writing the code?

Yes, I did! Interesting - it is the first time I used lambdas. You can see how, in
the code block:

If you...

If you need some proprietary sentences support that is not supported yet - tell me,
I'll try to add it. If you have found out a bug/slip/grammatical error,
please let me know -
I'll fix it as fast as I can.

This is an interesting solution. The only feedback I have at this point results from the fact that it is converted from C# which forces the emulation of C# "like" commands in the resulting Java. It appears you are a C# programmer attempting to help the Java community, which is great.

I am inclined to take the converted code and build a true Java solution from it. It also needs to be packaged into a jar file for general usage in a Java project. But it's not really built to support that. Again a result of starting as a C# application.

Thank you for your efforts. It will be a big help in the GIS project I have ahead of me.

You refer to an embedded hardware solution. Many of us are in need of an API for our own custom programming. Are you the developer of the embedded application? Please try not to inadvertently misdirect people in the attempt at making your application more visible.

I can't find the method declared as "string BuildSentence(NMEAStandartSentence)" but another one which is declared as "string BuildSentence(TalkerIdentifiers talkerID, SentenceIdentifiers sentenceID, object[] parameters)".

So I am wondering which is the newer one. and should I just use the latter?

That's it: not NMEA. There are many gps messages from commercialreceptor which are raw, and data comes binary. Also SBAS systems give its data in binary format.

I was looking for an elegant way of writing my code to get data from those messages, and found thia project. I really like the way you are paraing the NMEA messages, it's clear and smart. But in a gps raw message I don't have commas (colons?) to separate one data fiel from another, and since it is not a string I don't see how I could use raw strings to compare received message with them as you do.

So, any suggestion of how could I adapt your ideas to binary messages?

Commas and colons - it doesn't matter, if you have field with fixed sizes and/or field separators - method will be similar. Raw strings - i don't know what you mean, in C# i use byte arrays for such purposes. Tell me which protocol support you need - may be it will be interesting to add such functionality to library.

spelling remains a bit quirky but that's no problem
I am updating a number of the sentence profiles to meet my requirements (sailing performance monitoring ) - is there a mechanism for me to pass on the changes and reasons ?

2) if no such manufacturer in NMEAParser, or if you find incorrect/irrelevant sentence description, or you have description for new/unknown sentence - say it to me by email (dikarev-aleksandr[at]yandex.ru, and i'll update NMEAParser.

First of all, let me tell you this is an incredible piece of work ... good design and the implementation is the best of all the projects in The Code Project website. You lapse into Russian every once in awhile in the comments, but that's okay. The code is easy enough to read. Thank you for sharing.

I'd like to see an example of the sentence creation. More specifically, I'm looking for an example on how to create a TTM sentence. Regards, Ed.

Thanks for your message! I haven't found a 2.30/3.01 specification, i have only version from wikipedia - link, if you know of freely available any NMEA specification - let me know, i'll update NMEAParser.

PS When i was working with my Quectel L10 GPS receiver, I found some inconsistencies and fix it (extra status field at the end of GGA, GSV and GLL sentences), but not uploaded it yet.

Thank you for commenting! I tried to make it easily expanded and as easy as i can. And i think about sentences formats not as 'magic strings' anti-pattern but as database, integrated in code. These strings ('x.x' or 'hhmmss.ss' etc.) easy to understand for people who read manuals for GPS receivers.

It's a little ironic, that an article about parsing sentences, misspelled it as "sentense" in both the article title and throughout the code/article.

grammar helps, too.

Just along for the ride.
"the meat from that butcher is just the dogs danglies, absolutely amazing cuts of beef." - DaveAuld (2011)"No, that is just the earthly manifestation of the Great God Retardon." - Nagy Vilmos (2011)
"It is the celestial scrotum of good luck!" - Nagy Vilmos (2011)

Just along for the ride.
"the meat from that butcher is just the dogs danglies, absolutely amazing cuts of beef." - DaveAuld (2011)"No, that is just the earthly manifestation of the Great God Retardon." - Nagy Vilmos (2011)
"It is the celestial scrotum of good luck!" - Nagy Vilmos (2011)