mirror of
https://github.com/dotMorten/NmeaParser.git
synced 2026-01-20 15:40:16 +01:00
parent
0f0403d879
commit
0be7e552d5
|
|
@ -80,6 +80,7 @@ namespace NmeaParser
|
|||
readCount = await ReadAsync(buffer, 0, 1024, token).ConfigureAwait(false);
|
||||
failcounter = 0;
|
||||
}
|
||||
catch (TaskCanceledException) { }
|
||||
catch (TimeoutException t)
|
||||
{
|
||||
OnDisconnecting(t);
|
||||
|
|
|
|||
|
|
@ -19,9 +19,11 @@ using System.Linq;
|
|||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using System.IO.Ports;
|
||||
using System.Threading;
|
||||
|
||||
namespace NmeaParser
|
||||
{
|
||||
{
|
||||
/// <summary>
|
||||
/// A Serial Port NMEA device
|
||||
/// </summary>
|
||||
|
|
@ -42,6 +44,9 @@ namespace NmeaParser
|
|||
/// }
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
#if WINDOWS && NET6_0_OR_GREATER
|
||||
[Obsolete("Use WinRTSerialDevice type instead, as the underlying SerialPort implementation comes with a range of issues")]
|
||||
#endif
|
||||
public class SerialPortDevice : NmeaDevice
|
||||
{
|
||||
/// <summary>
|
||||
|
|
@ -69,6 +74,26 @@ namespace NmeaParser
|
|||
return Task.FromResult<System.IO.Stream>(Port.BaseStream);
|
||||
}
|
||||
|
||||
//private class SerialPortStreamWrapper : Stream
|
||||
//{
|
||||
// private SerialPort port;
|
||||
// public SerialPortStreamWrapper(SerialPort port)
|
||||
// {
|
||||
// this.port = port;
|
||||
// }
|
||||
|
||||
// public override int Read(byte[] buffer, int offset, int count) => port.Read(buffer, offset, count);
|
||||
|
||||
// public override Task<int> ReadAsync(byte[] buffer, int offset, int count, CancellationToken cancellationToken)
|
||||
// {
|
||||
|
||||
// return base.ReadAsync(buffer, offset, count, cancellationToken);
|
||||
// }
|
||||
// public override int ReadTimeout { get => port.ReadTimeout ; set => port.ReadTimeout = value; }
|
||||
|
||||
// public override int WriteTimeout { get => port.WriteTimeout; set => port.WriteTimeout = value; }
|
||||
//}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Task CloseStreamAsync(System.IO.Stream stream)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -60,6 +60,7 @@ namespace NmeaParser
|
|||
/// }
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
[Obsolete("Use WinRTSerialDevice type instead")]
|
||||
public class SerialPortDevice : NmeaDevice
|
||||
{
|
||||
private SerialDevice m_port;
|
||||
|
|
|
|||
149
src/NmeaParser/WinRTSerialDevice.cs
Normal file
149
src/NmeaParser/WinRTSerialDevice.cs
Normal file
|
|
@ -0,0 +1,149 @@
|
|||
|
||||
// *******************************************************************************
|
||||
// * Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// * you may not use this file except in compliance with the License.
|
||||
// * You may obtain a copy of the License at
|
||||
// *
|
||||
// * http://www.apache.org/licenses/LICENSE-2.0
|
||||
// *
|
||||
// * Unless required by applicable law or agreed to in writing, software
|
||||
// * distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// * See the License for the specific language governing permissions and
|
||||
// * limitations under the License.
|
||||
// ******************************************************************************
|
||||
|
||||
#if WINDOWS_UWP || NET6_0_OR_GREATER && WINDOWS
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using Windows.Devices.SerialCommunication;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
|
||||
namespace NmeaParser
|
||||
{
|
||||
/// <summary>
|
||||
/// A Serial Port NMEA device using Windows' WinRT APIs.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// To use the NMEA Parser against a serial device in a Windows 10 Universal app, ensure the serial device capability is enabled by opening package.appxmanifest in a text editor, and add the following to the <c><Capabilities></c> section:
|
||||
/// </para>
|
||||
/// <code lang="xml">
|
||||
/// <DeviceCapability Name="serialcommunication">
|
||||
/// <Device Id="any">
|
||||
/// <Function Type="name:serialPort" />
|
||||
/// </Device>
|
||||
/// </DeviceCapability>
|
||||
/// </code>
|
||||
/// <code lang="cs">
|
||||
/// var selector = SerialDevice.GetDeviceSelector("COM3"); //Get the serial port on port '3'
|
||||
/// var devices = await DeviceInformation.FindAllAsync(selector);
|
||||
/// if(devices.Any()) //if the device is found
|
||||
/// {
|
||||
/// var deviceInfo = devices.First();
|
||||
/// var serialDevice = await SerialDevice.FromIdAsync(deviceInfo.Id);
|
||||
/// //Set up serial device according to device specifications:
|
||||
/// //This might differ from device to device
|
||||
/// serialDevice.BaudRate = 4800;
|
||||
/// serialDevice.DataBits = 8;
|
||||
/// serialDevice.Parity = SerialParity.None;
|
||||
/// var device = new NmeaParser.SerialPortDevice(serialDevice);
|
||||
/// device.MessageReceived += device_NmeaMessageReceived;
|
||||
/// }
|
||||
/// ...
|
||||
/// private void device_NmeaMessageReceived(NmeaParser.NmeaDevice sender, NmeaMessageReceivedEventArgs args)
|
||||
/// {
|
||||
/// // called when a message is received
|
||||
/// }
|
||||
/// </code>
|
||||
/// </remarks>
|
||||
public class WinRTSerialDevice : NmeaDevice
|
||||
{
|
||||
private SerialDevice m_port;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a list of serial devices available.
|
||||
/// </summary>
|
||||
/// <returns>A set of serial devices available.</returns>
|
||||
public static async Task<IEnumerable<SerialDevice>> GetSerialDevicesAsync()
|
||||
{
|
||||
List<SerialDevice> services = new List<SerialDevice>();
|
||||
if(Windows.Foundation.Metadata.ApiInformation.IsMethodPresent("Windows.Devices.Enumeration.DeviceInformation", "FindAllAsync")) // Ensure we are on an OS where these WinRT APIs are supported
|
||||
{
|
||||
|
||||
if (Windows.Foundation.Metadata.ApiInformation.IsMethodPresent("Windows.Devices.SerialCommunication.SerialDevice", "GetDeviceSelector"))
|
||||
{
|
||||
var devices = await Windows.Devices.Enumeration.DeviceInformation.FindAllAsync(SerialDevice.GetDeviceSelector());
|
||||
foreach (var d in devices)
|
||||
services.Add(await SerialDevice.FromIdAsync(d.Id));
|
||||
}
|
||||
}
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SerialPortDevice" /> class.
|
||||
/// </summary>
|
||||
/// <param name="device">The serial port.</param>
|
||||
/// <exception cref="ArgumentNullException">port</exception>
|
||||
public WinRTSerialDevice(SerialDevice device)
|
||||
{
|
||||
if (device == null)
|
||||
throw new ArgumentNullException("device");
|
||||
m_port = device;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the active serial port.
|
||||
/// </summary>
|
||||
public SerialDevice SerialDevice
|
||||
{
|
||||
get
|
||||
{
|
||||
return m_port;
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Task<System.IO.Stream> OpenStreamAsync()
|
||||
{
|
||||
return Task.FromResult<System.IO.Stream>(m_port.InputStream.AsStreamForRead(0));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Task CloseStreamAsync(System.IO.Stream stream)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes data to the serial port (useful for RTCM/dGPS scenarios)
|
||||
/// </summary>
|
||||
/// <param name="buffer">The byte array that contains the data to write to the port.</param>
|
||||
/// <param name="offset">The zero-based byte offset in the buffer parameter at which to begin copying
|
||||
/// bytes to the port.</param>
|
||||
/// <param name="count">The number of bytes to write.</param>
|
||||
[Obsolete("Use WriteAsync")]
|
||||
public void Write(byte[] buffer, int offset, int count)
|
||||
{
|
||||
m_port.OutputStream.AsStreamForWrite().Write(buffer, offset, count);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool CanWrite => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task WriteAsync(byte[] buffer, int offset, int length)
|
||||
{
|
||||
if (m_port == null)
|
||||
throw new InvalidOperationException("Device not open");
|
||||
|
||||
return m_port.OutputStream.WriteAsync(buffer.AsBuffer(offset, length)).AsTask();
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
using NmeaParser.Gnss;
|
||||
using NmeaParser;
|
||||
using NmeaParser.Gnss;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
|
@ -6,6 +7,8 @@ using System.Threading.Tasks;
|
|||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using Windows.Devices.Enumeration;
|
||||
using Windows.Devices.SerialCommunication;
|
||||
|
||||
namespace SampleApp.WinDesktop
|
||||
{
|
||||
|
|
@ -28,22 +31,32 @@ namespace SampleApp.WinDesktop
|
|||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
//Get list of serial ports for device tab
|
||||
var availableSerialPorts = System.IO.Ports.SerialPort.GetPortNames().OrderBy(s => s);
|
||||
serialPorts.ItemsSource = availableSerialPorts;
|
||||
serialPorts.SelectedIndex = 0;
|
||||
// Use serial portName:
|
||||
//var comPort = availableSerialPorts.First();
|
||||
//var portName = new System.IO.Ports.SerialPort(comPort, 4800);
|
||||
//var device = new NmeaParser.SerialPortDevice(portName);
|
||||
|
||||
//Use a log file for playing back logged data
|
||||
var device = new NmeaParser.NmeaFileDevice("NmeaSampleData.txt") { EmulatedBaudRate = 9600, BurstRate = TimeSpan.FromSeconds(1d) };
|
||||
_ = StartDevice(device);
|
||||
|
||||
LoadSerialDevices();
|
||||
LoadBluetoothDevices();
|
||||
}
|
||||
|
||||
//Get list of serial ports for device tab
|
||||
private async void LoadSerialDevices()
|
||||
{
|
||||
var deviceList = new List<DeviceInfo>();
|
||||
var devices = await WinRTSerialDevice.GetSerialDevicesAsync();
|
||||
foreach (var item in devices)
|
||||
{
|
||||
deviceList.Add(new DeviceInfo()
|
||||
{
|
||||
DisplayName = $"{item.PortName}",
|
||||
CreateMethod = () =>
|
||||
{
|
||||
return Task.FromResult<NmeaParser.NmeaDevice>(new WinRTSerialDevice(item));
|
||||
}
|
||||
});
|
||||
}
|
||||
serialPorts.ItemsSource = deviceList;
|
||||
serialPorts.SelectedIndex = 0;
|
||||
}
|
||||
public class DeviceInfo
|
||||
{
|
||||
|
|
@ -206,9 +219,10 @@ namespace SampleApp.WinDesktop
|
|||
{
|
||||
try
|
||||
{
|
||||
var portName = serialPorts.Text as string;
|
||||
var baudRate = int.Parse(baudRates.Text);
|
||||
var device = new NmeaParser.SerialPortDevice(new System.IO.Ports.SerialPort(portName, baudRate));
|
||||
var portName = serialPorts.SelectedItem as DeviceInfo;
|
||||
var baudRate = uint.Parse(baudRates.Text);
|
||||
var device = await portName.CreateMethod() as WinRTSerialDevice;
|
||||
device.SerialDevice.BaudRate = baudRate;
|
||||
try
|
||||
{
|
||||
await StartDevice(device);
|
||||
|
|
|
|||
Loading…
Reference in a new issue