Added to Nuget, included bug fixes found along the way

This commit is contained in:
2025-09-27 09:25:52 -05:00
parent 13a3044bbf
commit 1129c6c4be
6 changed files with 127 additions and 24 deletions

View File

@@ -3,8 +3,9 @@ using GpsClient2.Exceptions;
using GpsClient2.Model;
using GpsClient2.NmeaMessages;
using System;
using System.ComponentModel;
using System.IO.Ports;
using System.Threading;
using System.Threading.Tasks;
namespace GpsClient2 {
public class ComPortGpsClient : BaseGpsClient {
@@ -14,7 +15,8 @@ namespace GpsClient2 {
private SerialPort _serialPort;
private DateTime? _previousReadTime;
private readonly BackgroundWorker worker = new BackgroundWorker();
private ComPortInfo data = null;
#endregion
#region Constructors
@@ -30,30 +32,36 @@ namespace GpsClient2 {
#region Connect and Disconnect
public override bool Connect() {
var data = (ComPortInfo)GpsInfo;
data = (ComPortInfo)GpsInfo;
IsRunning = true;
OnGpsStatusChanged(GpsStatus.Connecting);
_serialPort = new SerialPort(data.ComPort, 9600, Parity.None, 8, StopBits.One);
_serialPort = new SerialPort(data.ComPort, data.BaudRate, Parity.None, 8, StopBits.One);
// Attach a method to be called when there
// is data waiting in the port's buffer
_serialPort.DataReceived += port_DataReceived;
//_serialPort.DataReceived += port_DataReceived;
try {
// Begin communications
_serialPort.Open();
OnGpsStatusChanged(GpsStatus.Connected);
// Enter an application loop to keep this thread alive
while (_serialPort.IsOpen) {
Thread.Sleep(data.ReadFrequenty);
}
worker.DoWork += Worker_DoWork;
worker.RunWorkerAsync();
return true;
} catch {
Disconnect();
throw;
}
}
return true;
private async void Worker_DoWork(object sender, DoWorkEventArgs e) {
while (_serialPort.IsOpen) {
await Task.Delay(data.ReadFrequency);
//Thread.Sleep(data.ReadFrequenty);
processData();
}
}
public override bool Disconnect() {
@@ -62,24 +70,103 @@ namespace GpsClient2 {
OnGpsStatusChanged(GpsStatus.Disabled);
return true;
}
#endregion
#region Location Callbacks
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) {
processData();
}
private void processData() {
try {
var readString = _serialPort.ReadExisting();
OnRawGpsDataReceived(readString);
var result = _parser.Parse(readString);
if (typeof(GprmcMessage) != result.GetType()) return;
if (_previousReadTime != null && GpsInfo.ReadFrequenty != 0 && ((GprmcMessage)result).UpdateDate.Subtract(new TimeSpan(0, 0, 0, 0, GpsInfo.ReadFrequenty)) <= _previousReadTime) return;
OnGpsDataReceived(new GpsDataEventArgs((GprmcMessage)result));
} catch (UnknownTypeException ex) {
Console.WriteLine(ex.Message);
var readString = _serialPort.ReadExisting().Trim();
foreach (string sentence in readString.Split(new string[] { Environment.NewLine }, StringSplitOptions.None)) {
if (sentence.Length > 0 && sentence.StartsWith("$") && sentence.Contains("*")) {
parseSentence(sentence.Trim());
}
}
} catch (Exception ex) {
Console.WriteLine(" ==> " + ex.Message);
}
}
private void parseSentence(string sentence) {
if (sentence.StartsWith("$GPGSV")) { return; } // Ignore all $GPGSV messages
//Console.WriteLine(sentence);
try {
OnRawGpsDataReceived(sentence);
var result = _parser.Parse(sentence);
if (result == null) { return; }
if (typeof(GprmcMessage) != result.GetType()) return;
if (_previousReadTime != null && GpsInfo.ReadFrequency != 0 && ((GprmcMessage)result).UpdateDate.Subtract(new TimeSpan(0, 0, 0, 0, GpsInfo.ReadFrequency)) <= _previousReadTime) return;
OnGpsDataReceived(new GpsDataEventArgs((GprmcMessage)result));
} catch (UnknownTypeException ex) {
Console.WriteLine(" ==> " + ex.Message + " : " + sentence);
} catch (ArgumentException ex) {
Console.WriteLine(" ==> " + ex.Message + " : " + sentence);
}
}
#endregion
#region "Find My GPS Device Methods"
public async Task<bool> FindGps() {
int[] bauds = { 9600, 4800 };
foreach (string comPort in SerialPort.GetPortNames()) {
foreach (int baud in bauds) {
if (await IsGpsPort(comPort, baud)) {
GpsInfo = new ComPortInfo(comPort, baud);
return true;
}
}
}
return false;
}
private static async Task<bool> IsGpsPort(string comPort, int baudRate) {
bool result = await Task.Run(() => {
Console.Write("Attempting to locate GPS on " + comPort + ":" + baudRate + "...");
SerialPort serial = new SerialPort(comPort, baudRate, Parity.None, 8, StopBits.One);
serial.ReadTimeout = 3000;
try {
serial.Open();
Console.Write(" Connected. Listening for NMEA Sentences...");
} catch (Exception ex) {
Console.WriteLine(" Error: " + ex.Message);
return false;
}
string sData = "";
while (true) {
string s;
try {
s = serial.ReadLine();
} catch (Exception ex) {
serial.Close();
Console.WriteLine(" Error: " + ex.Message);
return false;
}
if (string.IsNullOrEmpty(s)) { return false; }
sData += s + Environment.NewLine;
if (sData.Length > 1500) {
if (sData.Contains("$GPRMC") || sData.Contains("$GPGGA") || sData.Contains("$GPGSA")) {
Console.WriteLine(" This is a GPS device!");
serial.Close();
return true;
}
}
}
});
return result;
}
#endregion
}
}