SerialPort class and DataReceived event... Getting bytes. Use ReadLine or ReadExisting? Any examples?
I would like to send and receive bytes over serial. My receiver should get the bytes asynchronously. I've written the small example below that appears to work, but it leaves me with an unsettled feeling.
Should I really be using WriteLine, ReadLine? As it's written now, is it possible that the code in the event handler m_port_DataReceived is going to be called for each and every byte? That was my understanding of the event "DataReceived"; perhaps I'm wrong. Does ReadLine block until it sees an end of line character?
Should I somehow use the "if (e.EventType == SerialData.Eof)" construct in the event handler? You can see I have it commented out. I tried it and could not get it to work. When would one expect a SerialData.Eof? My idea was that I could wait before all bytes were present before calling "ReadExisting". However, the "if" statement never evaluated to true. Force the code to go to ReadExisting did correctly read all the bytes however.
In general, what's the best way to set up my code to receive bytes coming over the serial port? The sender will be sending small chunks of bytes every 125 msecs, but will not be sending special characters. The packets of bytes are spaced out in time, so I don't think there's a problem of mixing packets together. More the problem is, "once you see one byte, go read everything, as long as you wait a very short time, you'll get everything". Giv开发者_如何学Pythonen this scenario, is there a preferred way?
Thanks in advance, Dave
public class SerialPortController
{
SerialPort m_port;
public SerialPortController(bool server)
{
if (server)
{
m_port = new SerialPort("COM4");
m_port.BaudRate = 115200;
m_port.Open();
byte[] sillyBytes = new byte[] { 0, 1, 2, 3, 4, 5, 6, 7 };
ASCIIEncoding encoding = new ASCIIEncoding();
string output_string = encoding.GetString(sillyBytes);
m_port.WriteLine(output_string);
//m_port.Write(sillyBytes, 0, 8);
}
else
{
m_port = new SerialPort("COM5");
m_port.DataReceived += new SerialDataReceivedEventHandler(m_port_DataReceived);
m_port.BaudRate = 115200;
m_port.Open();
}
int character = Console.Read();
}
void m_port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
//if (e.EventType == SerialData.Eof)
{
// string answer = m_port.ReadExisting();
string answer = m_port.ReadLine();
ASCIIEncoding encoding = new ASCIIEncoding();
byte[] byte_answer = encoding.GetBytes(answer);
}
}
}
There´s and example at MSDN which shows simple use of this.
And it used ReadExisting instead of ReadLine.
Also from the docs:
The DataReceived event is not guaranteed to be raised for every byte received. Use the BytesToRead property to determine how much data is left to be read in the buffer.
private static void DataReceviedHandler(
object sender,
SerialDataReceivedEventArgs e)
{
SerialPort sp = (SerialPort)sender;
string indata = sp.ReadExisting();
Console.WriteLine("Data Received:");
Console.Write(indata);
}
精彩评论