Introduction
Hello!
In this article I want to consider the implementation of access to GPS data in devices based on WindowsCE. When creating the SCAUT-Navigator product, it was necessary to develop an application that works in both WinCE version 5.0 and WinCE version 6.0, which can receive NMEA data from a navigation receiver, and record them in a log.
Decision
To work with GPS in WinCE, both version 5.0 and version 6.0, the easiest way to use it is to work with a COM port. You can find in the device which COM port provides GPS data using the program: DeviceManager.

')
Often, manufacturers of firmware have already taken care that the COM ports of GPS were two. This allows you to separate software that requires GPS and navigation, so that they do not fight for access to the COM port. Suppose that the COM port we will use in exclusive access.
To get NMEA data (http://ru.wikipedia.org/wiki/NMEA_0183), we just need to open the COM port, read the data from it, then close the COM port. What looks like in C #:
///<summary> /// COM ///</summary> ///<param name="comPortName"> COM-</param> ///<param name="baudRate"></param> private void ReadData(string comPortName,int baudRate) { var serialPort = newSerialPort(comPortName) { BaudRate = baudRate, DataBits = 8, Parity = Parity.None, StopBits = StopBits.One, RtsEnable = true }; serialPort.Open(); // COM- //..... var line=serialPort.ReadLine(); //..... serialPort.Close(); }
Despite the fact that everything looks rather trivial, the above code often does not work due to access errors to the COM port. (For example, an error often occurs: "UnauthorizedAccessException: Access to port is denied").
Let's not get upset, there is another approach that works.
Wonderful people from the OpenNetCf project carefully provide the source codes of their own SerialPort.
http://serial.codeplex.com/SourceControl/changeset/view/25883#435389Add an OpenNetCf.IO.Serial assembly to the project
The class of work with the COM-port of GPS will look like this:
///<summary> /// GPS COM- ///</summary> public class GpsPort: IDisposable { private Port _serialPort; private bool _disposed; private readonly object _syncObject = new object(); public bool IsOpen { get; private set; } ///<summary> /// GPS ///</summary> ///<param name="serialPortName"></param> ///<param name="baudRate"></param> public GpsPort(string serialPortName, int baudRate) { _serialPort = newPort(serialPortName, newDetailedPortSettings { BasicSettings = newBasicPortSettings { BaudRate = (BaudRates)baudRate }, EOFChar = '\n' }); _disposed = false; } public void Dispose() { if (!_disposed) { Close(); _serialPort = null; _disposed = true; } GC.SuppressFinalize(this); } ///<summary> ///Destructor ///</summary> ~GpsPort() { Dispose(); } ///<summary> /// ///</summary> public void Open() { try { _serialPort.Open(); _serialPort.DataReceived += SerialPortDataReceived; IsOpen = true; } catch (Exception ex) { throw new ApplicationException("Could not open com port", ex); } } ///<summary> /// ///</summary> private void SerialPortDataReceived() { lock (_syncObject) { if (_serialPort == null || !_serialPort.IsOpen) return; var realPortData = _serialPort.Input; if (realPortData.Length == 0) return; Debug.Write(Encoding.GetEncoding("ASCII").GetString(realPortData, 0, realPortData.Length)); } } ///<summary> /// ///</summary> public void Close() { IsOpen = false; if (_serialPort != null) if (_serialPort.IsOpen) { _serialPort.DataReceived -= SerialPortDataReceived; _serialPort.Close(); } } }
In the SerialPortDataReceived method, we write, in fact, the parsing of NMEA strings.
To do this, you can:
- Write your NMEA parser;
- Use SharpGps ;
- Use NMEA-0183-2-0-Sentense-parser-builder ( Here is the developer's article on Habré);
- Any other parser.
I did not try to use Sentenseparserbuilder, but I have something to tell about SharpGps.
I will make a small digression from the topic. There is an amusing error in the checksum calculation in the library, although many of my colleagues believe that this is not an error, but logical behavior. But first things first:
In NMEA 0183 (
http://www.tronico.fi/OH6NT/docs/NMEA0183.pdf ), the checksum is described as a 2-digit hexadecimal number — the XOR checksum of all bytes in the line between $ and * ".
SharpGps has a checksum validation feature in the package:
private bool CheckSentence(string strSentence) { int iStart = strSentence.IndexOf('$'); int iEnd = strSentence.IndexOf('*'); //If start/stop isn't found it probably doesn't contain a checksum, //or there is no checksum after *. In such cases just return true. if (iStart >= iEnd || iEnd + 3 > strSentence.Length) return true; byte result = 0; for (int i = iStart + 1; i < iEnd; i++) { result ^= (byte)strSentence[i]; } return (result.ToString("X") == strSentence.Substring(iEnd + 1, 2)); }
This feature works great if the navigation receiver transmits a checksum in the form of two numbers (0x01, 0x02, etc.), as stated in the protocol. But any ideal code breaks into a reality in which navigation receivers transmit packets with a checksum without adding a leading zero (0x1,0x2).
In a running application, it turns out that some packets are dropped. In this case, the feeling that everything seems to be working. But the track, although it is, but of very poor quality.
To make it work, the last line can be rewritten, at least like this:
var packCrc = byte.Parse(strSentence.Substring(iEnd + 1, 2), System.Globalization.NumberStyles.AllowHexSpecifier); return (result == packCrc);
With retreat everything.
For storing navigation data, it was decided to use SqlServer Compact Edition. It is very easy to integrate it into the application, and use it in development. I did not plan to describe the use of SqlServer Compact in this article, if you want to see an article on using SqlServer Compact in applications on WinCe, you can mark it in the comments.
Conclusion
In this article, I gave a solution to the problem of accessing GPS data on WinCe devices, the solution was tested on navigators of various manufacturers (Prestigio, Texet, Shturmann, Mio) with different versions of WinCE. I hope that it will save you from a part of the rake waiting for you on the path of development under WinCE.
Thanks for attention. Waiting for questions and comments in the comments.