Subversion Repositories Projects

Compare Revisions

Ignore whitespace Rev 2520 → Rev 2521

/MKLiveView/v1.0/Source/MKLiveView/SerialPortCtrl.xaml.cs
0,0 → 1,260
///============================================================================
/// This file is part of MIKROKOPTER SERIAL CONTROL TUTORIAL.
/// by JOHN C. MACDONALD at Ira A. Fulton College of Engineering and Technology
/// (http://hdl.lib.byu.edu/1877/2747)
/// (http://hdl.lib.byu.edu/1877/2748)
///============================================================================
/// made lot of changes here...
///============================================================================
 
 
 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.IO.Ports;
 
namespace MKLiveView
{
public partial class SerialPortCtrl : UserControl
{
private SerialPort port;
 
public event PortOpenedHandler PortOpened;
public delegate void PortOpenedHandler();
public event PortClosedHandler PortClosed;
public delegate void PortClosedHandler();
public event DataReceivedHandler DataReceived;
public delegate void DataReceivedHandler(byte[] buffer);
 
public SerialPortCtrl()
{
InitializeComponent();
port = new SerialPort();
port.ReadTimeout = 10000;
port.WriteTimeout = 1000;
textBoxStatus.Text = "closed";
textBoxBaudRate.Text = "57600";
textBoxDataBits.Text = port.DataBits.ToString();
populateComboBoxes();
setComboBoxDefaultValues();
}
 
public SerialPort Port
{
get
{
return port;
}
}
 
public void Connect(bool bConn)
{
if (bConn)
Dispatcher.Invoke((Action)(() => buttonOpen_Click(null, null)));
else
Dispatcher.Invoke((Action)(() => buttonClose_Click(null, null)));
}
private void buttonOpen_Click(object sender, RoutedEventArgs e)
{
try
{
if (port.IsOpen == true)
{
port.DataReceived -= SerialPortDataReceived;
port.Close();
}
 
lastoffset = 0;
append = false;
 
port.PortName = comboBoxPortName.Text;
port.BaudRate = Convert.ToInt32(textBoxBaudRate.Text);
port.DataBits = Convert.ToInt32(textBoxDataBits.Text);
port.StopBits = (StopBits)Enum.Parse(typeof(StopBits), comboBoxStopBits.Text);
port.Parity = (Parity)Enum.Parse(typeof(Parity), comboBoxParity.Text);
port.DataReceived += SerialPortDataReceived;
 
port.Open();
textBoxStatus.Text = "open";
textBoxStatus.Background = Brushes.LightGreen;
if (PortOpened != null)
{
// PortOpened(port.BaseStream);
PortOpened();
}
}
catch (Exception ex)
{
textBoxStatus.Text = "error: " + ex;
textBoxStatus.Background = Brushes.Coral;
}
}
private void buttonClose_Click(object sender, RoutedEventArgs e)
{
port.DataReceived -= SerialPortDataReceived;
port.Close();
if (PortClosed != null)
PortClosed();
textBoxStatus.Text = "closed";
textBoxStatus.Background = Brushes.LightGray;
lastoffset = 0;
append = false;
}
 
public string[] getPortNameValues()
{
try
{
return SerialPort.GetPortNames().Reverse().ToArray();
}
catch
{
return new string[0];
}
}
 
public string[] getStopBitValues()
{
return Enum.GetNames(typeof(StopBits));
}
 
public string[] getParityValues()
{
return Enum.GetNames(typeof(Parity));
}
 
private void populateComboBoxes()
{
comboBoxPortName.ItemsSource = getPortNameValues();
comboBoxStopBits.ItemsSource = getStopBitValues();
comboBoxParity.ItemsSource = getParityValues();
}
 
private void setComboBoxDefaultValues()
{
try { comboBoxPortName.SelectedIndex = 0; }
catch { }
try { comboBoxStopBits.SelectedIndex = 1; }
catch { }
try { comboBoxParity.SelectedIndex = 0; }
catch { }
}
 
byte[] messageBuffer = new byte[4096];
int lastoffset = 0;
bool append = false;
byte sentinel = Convert.ToByte('\r');
 
object oLock = 0;
private void SerialPortDataReceived(object sender, SerialDataReceivedEventArgs e)
{
System.Threading.Monitor.Enter(oLock);
int offset = 0;
try
{
byte[] buffer = new byte[port.BytesToRead];
port.Read(buffer, 0, port.BytesToRead);
 
bool bFound = false;
for (int i = 0; (i < buffer.Length) && port.IsOpen; i++)
{
if (buffer[i] == sentinel)
{
if (!append)
{
byte[] message = new byte[i + 1 - offset];
if (buffer[offset] != '#')
System.Diagnostics.Debug.Print(buffer[offset].ToString());
Buffer.BlockCopy(buffer, offset, message, 0, i + 1 - offset);
if (DataReceived != null)
DataReceived(message);
}
else
{
 
Buffer.BlockCopy(buffer, 0, messageBuffer, lastoffset, i + 1);
byte[] message = new byte[lastoffset + i + 1];
Buffer.BlockCopy(messageBuffer, 0, message, 0, message.Length);
messageBuffer.Initialize();
append = false;
lastoffset = 0;
// System.Diagnostics.Debug.Print(message.Length.ToString());
// System.Diagnostics.Debug.Print(BitConverter.ToString(message));
if (DataReceived != null)
DataReceived(message);
}
offset = i + 1;
if (buffer.Length > i + 1)
{
//offset = i + 1;
bFound = false;
}
else
{
// offset = 0;
bFound = true;
}
 
 
}
 
}
if (!bFound && port.IsOpen)
{
if (!append)
{
if (buffer[offset] != '#')
System.Diagnostics.Debug.Print(buffer[offset].ToString("X2"));
Buffer.BlockCopy(buffer, offset, messageBuffer, 0, buffer.Length - offset);
lastoffset = (buffer.Length - offset);
}
else
{
if (messageBuffer[0] != '#')
System.Diagnostics.Debug.Print(buffer[0].ToString("X2"));
Buffer.BlockCopy(buffer, offset, messageBuffer, lastoffset, buffer.Length - offset);
 
lastoffset += (buffer.Length - offset);
}
append = true;
 
}
}
catch (Exception ex)
{
System.Diagnostics.Debug.Print(ex.Message);
}
finally
{
System.Threading.Monitor.Exit(oLock);
}
 
 
}
 
private void btnRefresh_Click(object sender, RoutedEventArgs e)
{
if (!port.IsOpen)
{
// comboBoxPortName.Items.Clear();
comboBoxPortName.ItemsSource = getPortNameValues();
}
else
MessageBox.Show("Port has to be closed!");
}
 
}
 
}