For the actual serial port provider we have a base class.
This takes care of all the serial port side of things
using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Diagnostics;
namespace GpsTest
{
public abstract class SerialPortGpsProviderBase : IGpsDataProvider
{
/// <summary>
/// Fire this event when A GPS line of data has been received
/// </summary>
public event GpsDataReceivedEventHandler GpsDataReceived;
#region Attributes
protected SerialPort comPort = new SerialPort();
#endregion
public SerialPortGpsProviderBase()
{
}
~SerialPortGpsProviderBase()
{
Dispose(false);
}
#region IDisposable Members
private bool m_disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!m_disposed)
{
if (disposing)
{
// Dispose managed resources
}
// Dispose unmanaged resources
comPort.Dispose();
}
m_disposed = true;
}
#endregion
public bool IsOpen()
{
return comPort.IsOpen;
}
public void Open()
{
//set up the delegate used to read data in.......
comPort.DataReceived += new SerialDataReceivedEventHandler(comPort_DataReceived);
try
{
//finally open the port....
comPort.Open();
Trace.WriteLine("Com port " + comPort.ToString() + " Open=" + comPort.IsOpen.ToString());
}
catch (System.Exception ex)
{
Trace.WriteLine(DateTime.Now.ToString() +
": Failed to open COM port with exception: " + ex.Message);
}
}
protected abstract void comPort_DataReceived(object sender,
SerialDataReceivedEventArgs e);
protected void FireGpsDataReceived(string data)
{
try
{
if ((data.Length > 0) &&
(GpsDataReceived != null))
{
GpsDataReceived(this, new GpsDataLineEventArgs(data));
}
}
catch (System.Exception ex)
{
Trace.WriteLine(DateTime.Now +
": Failed to extract GPS data in comPort_DataReceived: " +
ex.Message);
}
}
public void Close()
{
try
{
//check we have a valid COM port to close...
if (comPort.IsOpen)
{
comPort.Close();
Debug.WriteLine("Com port " + comPort.ToString() + " CLOSED");
}
}
catch (System.Exception ex)
{
Trace.WriteLine(DateTime.Now.ToString() +
": Failed to close COM port with exception: " +
ex.Message);
}
}
}
}
The actual provider just implements the code to read the data and parse it
using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Diagnostics;
namespace GpsTest
{
// First simple provider
public class GpsSerialPortDataProvider : SerialPortGpsProviderBase
{
#region Attributes
private const string comPortName = "COM14";
private const int baudRate = 4800;
#endregion
public GpsSerialPortDataProvider()
{
//set up the com port settings.....
comPort.PortName = comPortName;
comPort.BaudRate = baudRate;
comPort.Parity = Parity.None;
comPort.StopBits = StopBits.One;
comPort.DataBits = 8;
comPort.Handshake = Handshake.None;
comPort.ReadTimeout = 1000;
comPort.NewLine = "\r\n";
}
~GpsSerialPortDataProvider()
{
Dispose(false);
}
protected override void comPort_DataReceived(
object sender,
SerialDataReceivedEventArgs e)
{
//Read a line of GPS data (each is sent with a \r\n at the end)
try
{
string data = comPort.ReadLine();
FireGpsDataReceived(data);
}
catch (System.Exception ex)
{
Trace.WriteLine(DateTime.Now +
": Failed to extract GPS data in comPort_DataReceived: "
+ ex.Message);
}
}
}
}
Due to a driver fault on the device we were using we could not read the data a line at a time. We had to clear the buffer out every time we read it, so here is the alternative provider
using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
using System.Diagnostics;
namespace GpsTest
{
public class GpsSerialPortDataProvider3 : SerialPortGpsProviderBase
{
#region Attributes
private const string comPortName = "COM14";
private const int baudRate = 4800;
#endregion
public GpsSerialPortDataProvider3()
{
//Setup the COM port
comPort.PortName = comPortName;
comPort.BaudRate = baudRate;
//set up the other settings.....
comPort.Parity = Parity.None;
comPort.StopBits = StopBits.One;
comPort.DataBits = 8;
comPort.Handshake = Handshake.None;
comPort.ReadTimeout = 1000;
comPort.ReceivedBytesThreshold = 256;
}
~GpsSerialPortDataProvider3()
{
Dispose(false);
}
private string buffer = "";
private object bufferLock = new object();
protected override void comPort_DataReceived(object sender,
SerialDataReceivedEventArgs e)
{
//Read a line of GPS data (each is sent with a \r\n at the end)
try
{
// Read out everything in the buffer
string data = comPort.ReadExisting();
if (data.Length > 0)
{
string ready = string.Empty;
lock (bufferLock)
{
buffer += data;
// Do we have any complete lines in the buffer
int ix = buffer.LastIndexOf("\r\n");
if (ix >= 0)
{
// Remove all the complete lines
ready = buffer.Remove(ix);
// Truncate the buffer any incomplete data at the end
buffer = buffer.Remove(0, ix + 2);
}
}
if (ready.Length > 0) // found some complete lines
{
// Extract them
string[] lines = ready.Split(new string[] { "\r\n" },
StringSplitOptions.RemoveEmptyEntries);
foreach (string line in lines)
{
// Invoke the GpsDataReceived event with the complete line
FireGpsDataReceived(line);
}
}
}
}
catch (System.Exception ex)
{
Trace.WriteLine(DateTime.Now.ToString() +
": Failed to extract GPS data in comPort_DataReceived: " +
ex.Message);
}
}
}
}
No comments:
Post a Comment