Added device tab for opening up other devices and example of auto discovery of serial port devices

This commit is contained in:
mort5161 2015-03-20 12:46:55 -07:00
parent b195c12d7a
commit ac4f8c9bb3
2 changed files with 183 additions and 7 deletions

View file

@ -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>

View file

@ -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;
}
}
}