mirror of
https://github.com/dotMorten/NmeaParser.git
synced 2026-02-04 14:54:38 +01:00
Added device tab for opening up other devices and example of auto discovery of serial port devices
This commit is contained in:
parent
b195c12d7a
commit
ac4f8c9bb3
|
|
@ -49,6 +49,41 @@
|
|||
HorizontalScrollBarVisibility="Visible"
|
||||
/>
|
||||
</TabItem>
|
||||
<TabItem Header="Device">
|
||||
<Grid>
|
||||
<StackPanel Margin="10">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="Current device: " />
|
||||
<TextBlock Text="None" x:Name="currentDeviceInfo" FontWeight="Bold" />
|
||||
</StackPanel>
|
||||
<Button Width="200" Content="Open NMEA Log..." Click="OpenNmeaLogButton_Click" HorizontalAlignment="Left" Padding="20,5" Margin="0,5" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Width="200" Content="Auto-discover serial port"
|
||||
HorizontalAlignment="Left" Padding="20,5" Margin="0,5"
|
||||
Click="AutoDiscoverButton_Click" />
|
||||
<TextBlock x:Name="autoDiscoverStatus" VerticalAlignment="Center" />
|
||||
</StackPanel>
|
||||
<GroupBox Header="Open Serial device" Width="200" HorizontalAlignment="Left">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Serial port:" />
|
||||
<ComboBox x:Name="serialPorts" />
|
||||
<TextBlock Text="Baud rate:" />
|
||||
<ComboBox x:Name="baudRates" SelectedIndex="3">
|
||||
<ComboBoxItem>1200</ComboBoxItem>
|
||||
<ComboBoxItem>2400</ComboBoxItem>
|
||||
<ComboBoxItem>4800</ComboBoxItem>
|
||||
<ComboBoxItem>9600</ComboBoxItem>
|
||||
<ComboBoxItem>19200</ComboBoxItem>
|
||||
<ComboBoxItem>38400</ComboBoxItem>
|
||||
<ComboBoxItem>57600</ComboBoxItem>
|
||||
<ComboBoxItem>115200</ComboBoxItem>
|
||||
</ComboBox>
|
||||
<Button Content="Connect" HorizontalAlignment="Left" Padding="20,5" Margin="0,5" Click="ConnectToSerialButton_Click" />
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</TabItem>
|
||||
</TabControl>
|
||||
|
||||
<Grid.ColumnDefinitions>
|
||||
|
|
|
|||
|
|
@ -21,20 +21,64 @@ namespace SampleApp.WinDesktop
|
|||
public partial class MainWindow : Window
|
||||
{
|
||||
private Queue<string> messages = new Queue<string>(101);
|
||||
|
||||
private NmeaParser.NmeaDevice currentDevice;
|
||||
//Dialog for browsing to nmea log files
|
||||
private Microsoft.Win32.OpenFileDialog nmeaOpenFileDialog = new Microsoft.Win32.OpenFileDialog()
|
||||
{
|
||||
Filter = "Text files|*.txt|NMEA Log|*.nmea|All files|*.*",
|
||||
InitialDirectory = new System.IO.FileInfo(typeof(MainWindow).Assembly.Location).DirectoryName
|
||||
};
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// Use serial port:
|
||||
//var comPort = System.IO.Ports.SerialPort.GetPortNames().First();
|
||||
//var port = new System.IO.Ports.SerialPort(comPort, 4800);
|
||||
//var device = new NmeaParser.SerialPortDevice(port);
|
||||
//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");
|
||||
device.MessageReceived += device_MessageReceived;
|
||||
var _ = device.OpenAsync();
|
||||
|
||||
StartDevice(device);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unloads the current device, and opens the next device
|
||||
/// </summary>
|
||||
/// <param name="device"></param>
|
||||
private void StartDevice(NmeaParser.NmeaDevice device)
|
||||
{
|
||||
//Clean up old device
|
||||
if (currentDevice != null)
|
||||
{
|
||||
currentDevice.MessageReceived -= device_MessageReceived;
|
||||
currentDevice.Dispose();
|
||||
}
|
||||
output.Text = "";
|
||||
messages.Clear();
|
||||
gprmcView.Message = null;
|
||||
gpggaView.Message = null;
|
||||
gpgsaView.Message = null;
|
||||
gpgllView.Message = null;
|
||||
pgrmeView.Message = null;
|
||||
satView.GpgsvMessages = null;
|
||||
//Start new device
|
||||
currentDevice = device;
|
||||
currentDevice.MessageReceived += device_MessageReceived;
|
||||
var _ = currentDevice.OpenAsync();
|
||||
if (device is NmeaParser.NmeaFileDevice)
|
||||
currentDeviceInfo.Text = string.Format("NmeaFileDevice( file={0} )", ((NmeaParser.NmeaFileDevice)device).Filename);
|
||||
else if (device is NmeaParser.SerialPortDevice)
|
||||
{
|
||||
currentDeviceInfo.Text = string.Format("SerialPortDevice( port={0}, baud={1} )",
|
||||
((NmeaParser.SerialPortDevice)device).Port.PortName,
|
||||
((NmeaParser.SerialPortDevice)device).Port.BaudRate);
|
||||
}
|
||||
}
|
||||
|
||||
private void device_MessageReceived(object sender, NmeaParser.NmeaMessageReceivedEventArgs args)
|
||||
|
|
@ -64,5 +108,102 @@ namespace SampleApp.WinDesktop
|
|||
pgrmeView.Message = args.Message as NmeaParser.Nmea.Gps.Garmin.Pgrme;
|
||||
});
|
||||
}
|
||||
|
||||
//Browse to nmea file and create device from selected file
|
||||
private void OpenNmeaLogButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var result = nmeaOpenFileDialog.ShowDialog();
|
||||
if (result.HasValue && result.Value)
|
||||
{
|
||||
var file = nmeaOpenFileDialog.FileName;
|
||||
var device = new NmeaParser.NmeaFileDevice(file);
|
||||
StartDevice(device);
|
||||
}
|
||||
}
|
||||
|
||||
//Creates a serial port device from the selected settings
|
||||
private void ConnectToSerialButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var portName = serialPorts.Text as string;
|
||||
var baudRate = int.Parse(baudRates.Text);
|
||||
var device = new NmeaParser.SerialPortDevice(new System.IO.Ports.SerialPort(portName, baudRate));
|
||||
StartDevice(device);
|
||||
}
|
||||
|
||||
//Attempts to perform an auto discovery of serial ports
|
||||
private async void AutoDiscoverButton_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var button = sender as Button;
|
||||
button.IsEnabled = false;
|
||||
System.IO.Ports.SerialPort port = await Task.Run<System.IO.Ports.SerialPort>(() => {
|
||||
return FindPort(
|
||||
new System.Progress<string>((s) => { Dispatcher.BeginInvoke((Action)delegate() { autoDiscoverStatus.Text = s; }); }));
|
||||
});
|
||||
if (port != null) //we found a port
|
||||
{
|
||||
autoDiscoverStatus.Text = "";
|
||||
serialPorts.Text = port.PortName;
|
||||
baudRates.Text = port.BaudRate.ToString();
|
||||
ConnectToSerialButton_Click(sender, e);
|
||||
}
|
||||
else
|
||||
autoDiscoverStatus.Text = "No GPS port found";
|
||||
button.IsEnabled = false;
|
||||
}
|
||||
|
||||
//Iterates all serial ports and attempts to open them at different baud rates
|
||||
//and looks for a GPS message.
|
||||
private static System.IO.Ports.SerialPort FindPort(IProgress<string> progress = null)
|
||||
{
|
||||
var ports = System.IO.Ports.SerialPort.GetPortNames().OrderBy(s => s);
|
||||
foreach (var portName in ports)
|
||||
{
|
||||
using (var port = new System.IO.Ports.SerialPort(portName))
|
||||
{
|
||||
var defaultRate = port.BaudRate;
|
||||
List<int> baudRatesToTest = new List<int>(new[] { 9600, 4800, 115200, 19200, 57600, 38400, 2400 }); //Ordered by likelihood
|
||||
//Move default rate to first spot
|
||||
if (baudRatesToTest.Contains(defaultRate)) baudRatesToTest.Remove(defaultRate);
|
||||
baudRatesToTest.Insert(0, defaultRate);
|
||||
foreach (var baud in baudRatesToTest)
|
||||
{
|
||||
|
||||
if (progress != null)
|
||||
progress.Report(string.Format("Trying {0} @ {1}baud", portName, port.BaudRate));
|
||||
port.BaudRate = baud;
|
||||
port.ReadTimeout = 2000; //this might not be long enough
|
||||
bool success = false;
|
||||
try
|
||||
{
|
||||
port.Open();
|
||||
if (!port.IsOpen)
|
||||
continue; //couldn't open port
|
||||
try
|
||||
{
|
||||
port.ReadTo("$GP");
|
||||
}
|
||||
catch (TimeoutException)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
//Error reading
|
||||
}
|
||||
finally
|
||||
{
|
||||
port.Close();
|
||||
}
|
||||
if (success)
|
||||
{
|
||||
port.Dispose();
|
||||
return new System.IO.Ports.SerialPort(portName, baud);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue