datareceived Event Handler in Serial C#
I am trying to implement the datarecieved based event handler, I think I am able to receive data from the port, but having difficulties executing the event.. I have tried both ReadLine and ReadExisting.. can you please comment on my code.. Thanks,
private void Form1_Load( object sender, EventArgs e )
{
// graphing stuff
portname = "COM1";
parity = Parity.None;
BaudRate = 115200;
stopbits = StopBits.One;
databits = 8;
port = new System.IO.Ports.SerialPort(portname);
port.Parity = parity;
port.BaudRate = BaudRate;
port.StopBits = stopbits;
port.DataBits = databits;
port.DataReceived += new SerialDataReceivedEventHandler(port_DataReceived);
port.Open();
count = 0;
}
void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
try
{
line = port.ReadLine();
count++;
this.BeginInvoke(new LineReceivedEvent(LineReceived),line);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private delegate void LineReceivedEvent(string text);
private void LineReceived(string text)
{
if (zedGraphControl1.GraphPane.CurveList.Count <= 0)
return;
LineItem curve = zedGraphControl1.GraphPan开发者_运维百科e.CurveList[0] as LineItem;
if (curve == null)
return;
IPointListEdit list = curve.Points as IPointListEdit;
double value = double.Parse(text);
list.Add(count, value);
// graphing stuff
}
// graphing stuff
}
I have done a lot of work with Serial communications, and DataReceived
never works like I want it to. There is a property on SerialPort
called ReceivedBytesThreshold
that is supposed to change when the event fires, but I have hit and miss luck with it. Do some googling on this event, and you'll have thousands of results reporting problems with it. The event can work sometimes, but I wouldn't rely on it for mission critical operation.
The better way I have found to do it if you're looking for line endings is to simply have a tight loop that continually reads bytes into a buffer if they are available, and then invokes the LineReceived
method on the buffer when it encounters a line ending. Put this on its own thread, and it should do the trick. Add a few Thread.Sleep()
inside the loop to keep it from taking over.
If you're not looking for instantaneous reactions to the serial stream, then run it on a threaded timer every second or half second. Each tick of the timer, read all the existing bytes into the buffer, and whenever you encounter a line ending invoke LineReceived
.
I am also using the DataReceived event with great success in one of our products. The protocol I am implementing mandates a minimum packet size of 6 bytes, so I use that are my receive threshold.
I make sure to keep any orphaned data, and reconstruct it the next time the event occurs if I get an incomplete read or a malformed packet. I really have had very few issues with this implementation. I would suggest locking in the event handler so you don't end up with a race on the serial port, but that may not be needed.
精彩评论