Hello,
Here is a NMEA parser that does not involve strings for decoding. Not a single one.
It takes an NMEA sentence as a byte array, as it would come from the GPS/UART, and then decode it to different static variables.
The caller only has to periodically check those variables to get the latest data :
class Program
{
private static readonly String GGAString = "$GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47";
private static readonly String GSAString = "$GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39";
private static readonly String GSVString1 = "$GPGSV,3,1,11,03,03,111,00,04,15,270,00,06,01,010,00,13,06,292,00*74";
private static readonly String GSVString2 = "$GPGSV,3,3,11,22,42,067,42,24,14,311,43,27,05,244,00,,,,*4D";
private static readonly String RMCString = "$GLRMC,221030,A,4807.038,N,01131.000,E,022.4,084.4,101120,003.1,W*6A";
static void Main()
{
NMEAParser.Parse(Encoding.UTF8.GetBytes(RMCString));
Debug.WriteLine($"Latest RMC sentence");
Debug.WriteLine($"Fix time : {NMEAParser.RMCSentence.FixTime}");
Debug.WriteLine($"Status : {(NMEAParser.RMCSentence.Status == 'A' ? "valid" : "Invalid")}");
Debug.WriteLine($"Latitude : {NMEAParser.RMCSentence.Latitude,8:N3} {NMEAParser.RMCSentence.LatitudeHemisphere}");
Debug.WriteLine($"Longitude : {NMEAParser.RMCSentence.Longitude,8:N3} {NMEAParser.RMCSentence.LongitudePosition}");
Thread.Sleep(Timeout.Infinite);
}
}
The strings you are seeing here are only for readability. As you can see, they are sent to the parser as Byte arrays.
Result :
Latest RMC sentence
Fix time : 11/10/2020 22:10:30
Status : valid
Latitude : 48.070 N
Longitude : 11.310 E
You know where I live, now
So far, only four sentences are handled : RMC, GGA, GSA and GSV. But it’s very easy to add new ones.
Why this parser ? Because strings in C# can easily lead to memory issues and because GPS data can come in huge amounts or numerous chunks in a short time.
This code does not consume much memory. So far, parsing 5 sentences every second during 2 min has only consumed 13KB.
Whereas using strings to decode sentences with the same timings eats up 268KB of memory…
> Before loop BYTES :
> +-----------+------------+------------+
> | Memory | Used | Free |
> +-----------+------------+------------+
> | Managed | 156,080 | 351,712 |
> | Unmanaged | 0 | 33,554,404 |
> +-----------+------------+------------+
>
> After loop BYTES :
> +-----------+------------+------------+
> | Memory | Used | Free |
> +-----------+------------+------------+
> | Managed | 169,616 | 338,176 |
> | Unmanaged | 0 | 33,554,404 |
> +-----------+------------+------------+
>
> Before loop STRINGS :
> +-----------+------------+------------+
> | Memory | Used | Free |
> +-----------+------------+------------+
> | Managed | 155,504 | 352,288 |
> | Unmanaged | 0 | 33,554,404 |
> +-----------+------------+------------+
>
> After loop STRINGS :
> +-----------+------------+------------+
> | Memory | Used | Free |
> +-----------+------------+------------+
> | Managed | 423,696 | 84,096 |
> | Unmanaged | 0 | 33,554,404 |
> +-----------+------------+------------+
It will replace the current MBN parser in the GPS utilities driver.
But remember : it’s a parser. Only a parser. The GPS and UART logic are separate things not handled in this code.