This repository is a supported version of a library I posted back in 2011 at CodeProject
The library is able to parse and build any NMEA0183-sentences. Common used standard sentences are supported 'from the box'.
If you looking for a tiny and fast C/Arduino code for parsing NMEA0183-sentences, please, refer to UCNL_ALibs library
The parser/builder is made as a static class.
To use it, just:
- Add UCNLNMEA to your project's references list.
- Add a propriate using declaration:
using UCNLNMEA;
Sentence ID | Description |
---|---|
AAM | Waypoint Arrival Alarm |
ALM | GPS Almanac Data |
APB | Autopilot Sentence "B" |
APA | Autopilot Sentence "A" |
ASD | Autopilot System Data |
BEC | Bearing & Distance to Waypoint, Dead reckoning |
BOD | Bearing, Origin to Destination |
BWC | Bearing & Distance to Waypoint, Great Circle |
BWR | Bearing & Distance to Waypoint, Rhumb Line |
BWW | Bearing, Waypoint to Waypoint |
DBK | Depth Below Keel |
DBS | Depth Below Surface |
DBT | Depth Below Transduser |
DCN | Obsolete Decca Position |
DPT | Depth |
DSC | Digital Selective Calling Information |
DSE | Extended DSC |
DSI | DSC Transponder Initiate |
DSR | DSC Transponder Response |
DTM | Datum Reference |
FSI | Frequency Set Information |
GBS | GBS Satellite Fault Detection |
GGA | Global Positioning System Fix Data |
GLC | Geographic Position, Loran-C |
GLL | Geographic Position, Latitude/Longitude |
GRS | GPS Range Residuals |
GSA | GPS DOP and Active Satellites |
GST | GPS Pseudorange Noise Statistics |
GSV | GPS Sattelites in View |
GTD | Geograpic Location in Time Differences |
GXA | Transit Position |
HDG | Heading, Deviation & Variation |
HDM | Heading, Magnetic |
HDT | Heading, True |
HSC | Heading Steering Command |
LCD | Loran-C Signal Data |
MSK | MSK Receiver Interface (for DGPS Beacon Receivers) |
MSS | MSK Receiver Signal Status |
MTW | Water Temperature |
MWD | Wind Direction & Speed |
MWV | Wind Speed & Angle |
OLN | Obsolete Omega Line Numbers |
OSD | Own Ship Data |
RMA | Recommend Minimum Specific Loran-C Data |
RMB | Recommend Minimum Navigation Information |
RMC | Recommend Minimum Specific GPS/TRANSIT Data |
ROO | Waypoints in Active Route |
ROT | Rate of Turn |
RPM | Revolutions |
RSA | Rudder Sensor Angle |
RSD | RADAR System Data |
RTE | Routes |
SFI | Scanning Frequency Information |
STN | Multiple Data ID |
TLL | Target Latitude & Longitude |
TRF | Obsolete TRANSIT Fix Data |
TTM | Tracked Target Message |
VBW | Dual Ground/Water Speed |
VDR | Set and Drift |
VHW | Water Speed and Heading |
VLW | Distance Traveled through Water |
VPW | Speed, Measured Parallel to Wind |
VTG | Track Made Good and Ground Speed |
VWR | Relative Wind Speed & Angle |
WCV | Waypoint Closure Velocity |
WDC | Distance to Waypoint, Great Circle |
WDR | Distance to Waypoint, Rhumb Line |
WNC | Distance, Waypoint to Waypoint |
WPL | Waypoint Location |
XDR | Transducer Measurement |
XTE | Cross-Track Error, Measured |
XTR | Cross-Track Error, Dead Reckoning |
ZDA | Time & Date |
ZDL | Time & Distance to Variable Point |
ZFO | UTC & Time from Origin Waypoint |
ZTG | UTC & Time to Destination Waypoint |
Talker ID | Description |
---|---|
AG | Autopilot - General |
AP | Autopilot - Magnetic |
CD | Communications - Digital Selective Calling (DSC) |
CR | Communications - Receiver / Beacon Receiver |
CS | Communications - Sattelite |
CT | Communications - Radio-Telephone (MF/HF) |
CV | Communications - Radio-Telephone (VHF) |
CX | Communications - Scanning Receiver |
DF | Direction Finder |
EC | Electronic Chart Display & Information System (ECDIS) |
EP | Emergency Position Indicating Beacon (EPIRB) |
ER | Engine Room Monitoring Systems |
GA | Gallileo |
GB | BeiDou |
GL | GLONASS |
GP | Global Positioning System (GPS) |
GN | Mixed satellite fix |
HC | Heading - Magnetic Compass |
HE | Heading - North Seeking Gyro |
HN | Heading - Non North Seeking Gyro |
II | Integrated instrumentation |
IN | Integrated Navigation |
LC | Loran C |
P | Proprietary Code |
RA | RADAR and/or ARPA |
SD | Sounder, Depth |
SN | Electronic Positioning System, other/general |
SS | Souder, Scanning |
TI | Turn Rate Indicator |
VD | Velocity Sensor, Doppler, other/general |
DM | Velocity Sensor, Speed Log, Water, Magnetic |
VW | Velocity Sensor, Speed Log, Water, Mechanical |
WI | Weather Instruments |
YX | Transduser |
ZA | Timekeeper - Atomic Clock |
ZC | Timekeeper - Chronometer |
ZQ | Timekeeper - Quartz |
ZV | Radio Update, WWV or WWVH |
double shipHeading = 48.123;
string hdt_sentence = NMEAParser.BuildSentence(
TalkerIdentifiers.GN, // Talker identifier = GN (GPS + GLONASS)
SentenceIdentifiers.HDT, // Sentense identifier = HDT (Heading from True North)
new object[] // Parameters list
{
shipHeading, // Heading value in degrees
"T" // T stands for True
}));
after that, hdt_sentence
will has a value "$GNHDT,48.123,T*17\r\n"
To parse new built sentence, one can use following code:
// parseResult can be NMEAStandardSentence or NMEAProprietarySentence
// to use it, you have to check type of the result and make a cast
try parseResult = NMEAParser.Parse(hdt_sentence);
if (parseResult is NMEAStandardSentence) // check if it is a standard sentence
{
// sentence parameters are stored in 'paramters' field, which is an object[]
// accoring to HDT sentence format, the first parameter (index = 0) is a double value for heading
Console.WriteLine(string.Format("Heading: {0:F03}", (parseResult as NMEAStandardSentence).parameters[0]));
}
double lat = 48.50963056;
double lon = 44.55977778;
double speedKmh = 0.5;
string rmc_sentence = NMEAParser.BuildSentence(
TalkerIdentifiers.GN, // Talker identifier = GN (GPS + GLONASS)
SentenceIdentifiers.RMC, // Sentence identifier = RMC
new object[] // Parameters list
{
DateTime.Now, // UTC time
"Valid", // Time is valid
lat, "N", // Position latitude, degrees
lon, "E", // Position longitude, degrees
speedKmh.Value / 0.5144, // Speed
null, // track true
DateTime.Now, // UTC date
null, // magnetic variation
null, // magnetic variation direction
"D", // Positioning system mode indicator, D = differential
});
after that, rmc_sentence
will has value $GNRMC,233843.698,A,4830.5778,N,04433.5867,E,0.972006,,270719,,,D*6F\r\n
To parse it, use following code:
// parseResult can be NMEAStandardSentence or NMEAProprietarySentence
// to use it, you have to check type of the result and make a cast
try parseResult = NMEAParser.Parse(rmc_sentence);
if (parseResult is NMEAStandardSentence) // check if it is a standard sentence
{
// sentence parameters are stored in 'paramters' field, which is an object[]
var rmcResult = (parseResult as NMEAStandardSentence);
Console.WriteLine(string.Format("Lat: {0:F06}, Lon: {1:F06}",
rmcResult.parameters[2], // latitude value as double
rmcResult.parameters[4] // longitude value as double
// ... etc
));
}
Dealing with proprietary sentences is pretty the same process as with standard ones, except few diffirencies: First, you should add a description for a sentence. Consider we need an ACK sentence, which should has single integer parameter - error code.
NMEAParser.AddManufacturerToProprietarySentencesBase(ManufacturerCodes.UWV); // Add new entry to proprietary sentences descriptor
// message identifier "0", parameters: integer, double, string and a byte array
// parameters go as a string, where items are separated with commas
// x stands for an integer value
// x.x stands for double
// c--c stands for string
// h--h stands for a hex string or a byte array (e.g. "ff0123aa4d5a")
NMEAParser.AddProprietarySentenceDescription(ManufacturerCodes.UWV, "0", "x,x.x,c--c,h--h");
Now we can build and parse sentence $PUWV0 as follows:
int int_parameter = 12345;
double double_parameter = 3.1415;
string string_parameter = "this is a string parameter";
byte[] byte_array_parameter = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var uwv0_sentence = NMEAParser.BuildSentence(
ManufacturerCodes.UWV,
"0",
new object[] {
int_parameter,
double_parameter,
string_parameter,
byte_array_parameter
});
After the call, uwv0_sentence
will has value "$PUWV0,12345,3.1415,this is a string parameter,0x010203040506070809*51\r\n
"
Parsing this proprietary sentence is as follows:
var pResult = NMEAParser.Parse(uwv0_sentence);
if (pResult is NMEAProprietarySentence)
{
var prop_sentence = (pResult as NMEAProprietarySentence);
// here we can check:
// Manufacturer identifier, by accessing prop_sentence.Manufacturer
// Sentence identifier, by accessing prop_sentence.SentenceID
// and all the parameters, as with standard sentences:
int_parameter = (int)prop_sentence.parameters[0];
double_parameter = (double)prop_sentence.parameters[1];
string_parameter = (string)prop_sentence.parameters[2];
byte_array_parameter = (byte[])prop_sentence.parameters[3];
}