///============================================================================
/// 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)
///============================================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO.Ports;
using System.IO;
namespace SimpleSerialPort
{
public partial class SimpleSerialPort
: UserControl
{
private SerialPort port
;
public event PortOpenedHandler PortOpened
;
public delegate void PortOpenedHandler
();
public event PortClosedHandler PortClosed
;
public delegate void PortClosedHandler
();
// public delegate void PortOpenedHandler(Stream stream);
public event DataReceivedHandler DataReceived
;
public delegate void DataReceivedHandler
(byte[] buffer
);
public SimpleSerialPort
()
{
InitializeComponent
();
port
= new SerialPort
();
port
.ReadTimeout = 10000;
port
.WriteTimeout = 1000;
textBoxStatus
.Text = "closed";
//textBoxBaudRate.Text = port.BaudRate.ToString();
textBoxBaudRate
.Text = "57600";
textBoxDataBits
.Text = port
.DataBits.ToString();
populateComboBoxes
();
setComboBoxDefaultValues
();
// PortOpened += SimpleSerialPort_PortOpened;
}
public SerialPort Port
{
get
{
return port
;
}
}
public void Connect
(bool bConn
)
{
if (bConn
)
buttonOpen
.Invoke((Action
)(()=> buttonOpen_Click
(null,
null)));
else
buttonClose
.Invoke((Action
)(() => buttonClose_Click
(null,
null)));
}
private void buttonOpen_Click
(object sender, EventArgs 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";
if (PortOpened
!= null)
{
// PortOpened(port.BaseStream);
PortOpened
();
}
}
catch (Exception ex
)
{
textBoxStatus
.Text = "error: " + ex
;
}
}
private void buttonClose_Click
(object sender, EventArgs e
)
{
port
.DataReceived -= SerialPortDataReceived
;
port
.Close();
PortClosed
();
textBoxStatus
.Text = "closed";
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
.Items.AddRange(getPortNameValues
());
comboBoxStopBits
.Items.AddRange(getStopBitValues
());
comboBoxParity
.Items.AddRange(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
);
// bFound = true;
}
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
);
// bFound = true;
}
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
);
// textBoxBuffer.Invoke((Action)(() => textBoxBuffer.Text = "n " + offset.ToString()));
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
);
// textBoxBuffer.Invoke((Action)(() => textBoxBuffer.Text = "a " + offset.ToString()));
lastoffset
+= (buffer
.Length - offset
);
}
append
= true;
}
}
catch(Exception ex
)
{
System.Diagnostics.Debug.Print(ex
.Message);
}
finally
{
System.Threading.Monitor.Exit(oLock
);
}
}
}
}