GPS Library for Windows 10 IoT and Raspberry Pi

I am tinkering with Raspberry Pi 3 (RasPi) and Windows 10 IoT Core. I was thinking how to build an IoT device with GPS functionality in RasPi. Many IoT projects employ GPS module but they use it mostly with Arduino to build quadcopter. Some people tried it with RasPi, but they use it in Raspbian OS. No one seems tried to build directly with RPi and Windows.

So, I made my own implementation, a library to connect Windows apps with GPS device. Long story short, you can make Windows app running on RasPi which utilize GPS, and you can code it on C#.

Check the code on GitHub. The library is licensed under GNU Lesser General Public License v3. You may use it in your project while retaining the license and credit to me. 🙂

How To Use

You just simply to download the binary release, or compile it on your own. Then add reference to Heliosky.IoT.GPS.dll in your project.

To use the library, you can add usings below to simplify the class resolution.

[csharp] using Windows.Devices.Enumeration;
using Windows.Devices.SerialCommunication;
using Heliosky.IoT.GPS;
[/csharp]

Load the serial device via .NET SerialDevice and DeviceInformation class. In this example, we assume that the only serial device available is the GPS serial device, which is on the array index 0.

[csharp] string deviceSelector = SerialDevice.GetDeviceSelector();
var deviceInformations = await DeviceInformation.FindAllAsync(deviceSelector);
var gpsDeviceInfo = deviceInformations[0];
[/csharp]

After that you can instantiate UBXSerialGPS class by supplying the device info retrieved earlier. You can also supply a Configuration.Port object to specify port configuration that will be used by the GPS serial device. Currently ony BaudRate that is correctly implemented, along with InputProtocol and OutputProtocol. Changing the rest of configuration might make the GPS device not responding and you will have to cold restart the entire device (RasPI). Additionally it is not recommended to change InputProtocol and OutputProtocol to other than UBX as it will make the UBXSerialGPS cannot communicate with the device, as the NMEA protocol is not implemented.

[csharp] Configuration.Port cfg_prt = new Configuration.Port()
{
PortID = 1,
StopBit = Configuration.Port.StopBitType.OneStop,
Parity = Configuration.Port.ParityType.NoParity,
CharacterLength = Configuration.Port.CharacterLengthType.Bit8,
BaudRate = 115200,
InputProtocol = Configuration.Port.Protocol.UBX,
OutputProtocol = Configuration.Port.Protocol.UBX
};

var gps = new UBXSerialGPS(gpsDeviceInfo, cfg_prt);
[/csharp]

You can then start the GPS by calling method Start

[csharp] await gps.Start();
[/csharp]

You can request for data/message from GPS device by calling PollMessageAsync method. It is a generic method with its type parameter is the message type. Below is the example of retrieving geodetic position data (latitude and longitude):

[csharp] var currentPosition = await gps.PollMessageAsync<Navigation.GeodeticPosition>();
Debug.WriteLine("Position: {0}, {1}", currentPosition.Latitude, currentPosition.Longitude);
[/csharp]

You can also request for the data to be sent periodically. To configure this, you can send Configuration.Message object to the GPS. You can retrieve the Configuration.Message instance by calling GetInstanceForType method and specify the data class you want to receive periodically on type parameter. You can then register to the event MessageReceived to receive the message

[csharp] Configuration.Message cfg_msg = Configuration.Message.GetConfigurationForType<Navigation.GeodeticPosition>();
bool res = await gps.WriteConfigAsync(cfg_msg);

if(res)
Debug.WriteLine("Success configuring message");
else
Debug.WriteLine("Failed configuring message");

gps.MessageReceived += Gps_MessageReceived

// EVENT HANDLER

private void Gps_MessageReceived(object sender, MessageReceivedEventArgs e)
{
Navigation.GeodeticPosition pos = e.ReceivedMessage as Navigation.GeodeticPosition;

if(pos != null)
{
// Process the geodetic position here
}
}
[/csharp]

In the sample project that is available on the source control, you can see the demonstration on how to use the library. You can start from there. I will explain more about the internal of the library later.

You may also like...

3 Responses

  1. Sachin rana says:

    There was a mismatch between the processor architecture of the project being built “AMD64” and the processor architecture of the reference “Heliosky.IoT.GPS”, “ARM”. This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. IOT.SmartTrack

  2. XGu says:

    Great work!

    I have a question, if I want multiple MessageReceived ? For example with DOP and Geodetic,

    Thanks!!!

    • Gilang says:

      You need to try-casting the object to the message you are desired. If the cast is unsuccessful, then the object is not of that type. 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *