nanoFramework.Iot.Device.Common.GnssDevice 1.0.43

Prefix Reserved
dotnet add package nanoFramework.Iot.Device.Common.GnssDevice --version 1.0.43                
NuGet\Install-Package nanoFramework.Iot.Device.Common.GnssDevice -Version 1.0.43                
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="nanoFramework.Iot.Device.Common.GnssDevice" Version="1.0.43" />                
For projects that support PackageReference, copy this XML node into the project file to reference the package.
paket add nanoFramework.Iot.Device.Common.GnssDevice --version 1.0.43                
#r "nuget: nanoFramework.Iot.Device.Common.GnssDevice, 1.0.43"                
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
// Install nanoFramework.Iot.Device.Common.GnssDevice as a Cake Addin
#addin nuget:?package=nanoFramework.Iot.Device.Common.GnssDevice&version=1.0.43

// Install nanoFramework.Iot.Device.Common.GnssDevice as a Cake Tool
#tool nuget:?package=nanoFramework.Iot.Device.Common.GnssDevice&version=1.0.43                

This binding implements a base Global Navigation Satellite System (GNSS) device and a generic serial implementation. The device includes a generic serial module that supports multiple satellite navigation systems such as GPS, GNSS, and BeiDou. The Generic Serial GNSS Device is also extensible. Any serial modules like the NEO6-M, NEO-M8P-2, NEO-M9N from u-blox, ATGM336H, Minewsemi, ZED-F9P, ZOE-M8Q, SAM-M8Q, SARA-R5 and many many more are directly supported for the main NMEA0183 features.

Documentation

This bindings implement a large part of NMEA 0183 and a way to extend the processed elements.

The Locationclass is also aligned with the MAUI class Location. There is not a one to one match as .NET nanoFramework is using UnitsNet for the Course (with Angle) and Speed (with Speed).

Connections

There are only 4 wires required:

GPS/GNSS module MCU Header
VCC 3.3V / 5V
GND GND
TX RX
RX TX

It is important to check which voltage is required for your module.

Usage of Generic GNSS Serial Module

// Some modules like ESP32 requires to setup serial pins
// Configure GPIOs 16 and 17 to be used in UART2 (that's refered as COM3)
Configuration.SetPinFunction(9, DeviceFunction.COM2_RX);
Configuration.SetPinFunction(8, DeviceFunction.COM2_TX);

// By default baud rate is 9600
var gnssDevice = new GenericSerialGnssDevice("COM2");

// Subscribe for events
gnssDevice.FixChanged += FixChanged;
gnssDevice.LocationChanged += LocationChanged;
gnssDevice.OperationModeChanged += OperationModeChanged;
gnssDevice.ParsingError += ParsingError;
gnssDevice.ParsedMessage += ParsedMessage;

// Starts the module
gnssDevice.Start();

The various events allows you to subscribe for various behaviors. One of the main one is when the Fix change, meaning, your module starts to get proper data.

private static void ParsingError(Exception exception)
{
    Console.WriteLine($"Received parsed error: {exception.Message}");
}

private static void OperationModeChanged(GnssOperation mode)
{
    Console.WriteLine($"Received Operation Mode changed: {mode}");
}

private static void LocationChanged(GeoPosition position)
{
    Console.WriteLine($"Received position changed: {position.Latitude},{position.Longitude}");
}

private static void FixChanged(Fix fix)
{
    Console.WriteLine($"Received Fix changed: {fix}");
}

Extensibility of the GenericSerialGnssDevice

Creating your own NmeaData parsers

This class is extensible by using the ParsedMessage event and adding NmeaData elements to the Nmea0183Parser. The samples show how to to do this.

Here is a simple example of a TXT message processing:

using Iot.Device.Common.GnssDevice;
using System;

namespace GnssDevice.Sample
{
    /// <summary>
    /// Implements a simple TXT data from a GNSS device.
    /// </summary>
    internal class TxtData : NmeaData
    {
        /// <inheritdoc/>
        public override string MessageId => "TXT";

        /// <summary>
        /// Gets the decoded text.
        /// </summary>
        public string Text { get; internal set; }

        /// <summary>
        /// Gets the severity of the message.
        /// </summary>
        public MessageSeverity Severity { get; internal set; }

        /// <inheritdoc/>
        public override NmeaData Parse(string inputData)
        {
            if (!IsMatch(inputData))
            {
                throw new ArgumentException();
            }

            try
            {
                var subfields = GetSubFields(inputData);
                if(subfields.Length < 5)
                {
                    return null;
                }

                var txt = subfields[4];
                var sev = (MessageSeverity)int.Parse(subfields[3]);
                return new TxtData(txt, sev);
            }
            catch (Exception ex)
            {
                throw new ArgumentException("Invalid NMEA TXT data", ex);
            }
        }

        /// <summary>
        /// Initializes a new instance of the <see cref="TxtData"/> class.
        /// </summary>
        public TxtData() 
        { }

        /// <summary>
        /// Initializes a new instance of the <see cref="TxtData"/> class.
        /// </summary>
        /// <param name="txt">The TXT entry.</param>
        /// <param name="sev">The severity of the message.</param>
        public TxtData(string txt, MessageSeverity sev)
        {
            Text = txt;
            Severity = sev;
        }
    }

    public enum MessageSeverity
    {
        Error = 0,
        Warning = 1,
        Notice = 2,
        User = 7
    }
}

Once you have your own parser setup, you need to add it to the parsers:

// Add the TXT parser in the NMEA Parser
Nmea0183Parser.AddParser(new TxtData());

// on the GNSS device, make sure you add the ParsedMessage event
gnssDevice = new GenericSerialGnssDevice("COM2");
gnssDevice.ParsedMessage += ParsedMessage;

And you can then get the parsed element here:

private static void ParsedMessage(NmeaData data)
{
    Console.WriteLine($"Received parsed message: {data.GetType()}");
    if (data is TxtData txtData)
    {
        Console.WriteLine($"Received TXT message: {txtData.Text}, severity: {txtData.Severity}");
    }
}

If you want to replace one of the existing parser by your own, you can remove it from the Nmea0183Parser and add your own using the same principle.

Handling yourself unparsed messages

This can be done using the UnparsedMessage event. You just need to subscribe to the event and you'll be able to handle the message:

// on the GNSS device, make sure you add the UnparsedMessage event
gnssDevice = new GenericSerialGnssDevice("COM2");
gnssDevice.UnparsedMessage += UnparsedMessage;

As a result, all the unparsed messages will be delivered for you to handle:

private static void UnparsedMessage(string message)
{
    Console.WriteLine($"Received unparsed message: {message}");
}

Extensibility with the GnssDevice

The GnssDevice abstract class already incorporate quite some logic. The GenericSerialGnssDevice is using it and is a great example of extensibility. Check the code.

Product Compatible and additional computed target framework versions.
.NET Framework net is compatible. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages (1)

Showing the top 1 NuGet packages that depend on nanoFramework.Iot.Device.Common.GnssDevice:

Package Downloads
nanoFramework.Iot.Device.AtModem

This package includes the .NET nanoFramework binding Iot.Device.AtModem for .NET nanoFramework C# projects. This nuget allows to use AT Modem for SMS, calls, network, internal storage, HTTP, MQTT for some modems.

GitHub repositories (2)

Showing the top 2 popular GitHub repositories that depend on nanoFramework.Iot.Device.Common.GnssDevice:

Repository Stars
nanoframework/Samples
🍬 Code samples from the nanoFramework team used in testing, proof of concepts and other explorational endeavours
nanoframework/nanoFramework.IoT.Device
📦 This repo includes .NET nanoFramework implementations for various sensors, chips, displays, hats and drivers
Version Downloads Last updated
1.0.43 37 9/27/2024
1.0.31 185 9/6/2024
1.0.23 189 8/28/2024
1.0.17 223 8/16/2024
1.0.15 117 8/14/2024
1.0.8 101 8/12/2024
1.0.5 97 8/9/2024
1.0.1 83 8/6/2024