Why SerialDataReceivedEventArgs receive incomplete data?

陌路散爱 提交于 2020-01-16 14:11:39

问题


I'm currently working on IO board. The serial object has been initialized and listen for incoming data. I'm reading incoming data using SerialPort1.ReadExisting(); as the incoming string expected to arrive as {X000000}5E + \r\n in every reading.

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    try
    {
        TextBox2.Invoke(new EventHandler(delegate
        {
            TextBox2.AppendText(SerialPort1.ReadExisting());
        }));
    }
    catch
    {
        MessageBox.Show("Couldn't open Port", "Error");
    }
}

When using ReadExisting() just like that, I got the result like I wanted and I will get the value of between "{X" and "}", but when I do a split char, I always got error regarding index out of bound. I change the way of reading by adding Environment.NewLine when reading to get whether the data is receive in a complete or not. The result will be like below image as expected.

I also try like below based from SO answer but incoming string data will be same as image above:-

var end = '\r';
int dataLength = _serialPort.BytesToRead;
byte[] data = new byte[dataLength];
int nbrDataRead = _serialPort.Read(data, 0, dataLength);

string RxString = System.Text.Encoding.ASCII.GetString(data);
LogEvents($"Serial port data: {RxString}");

It's like the full set of {X000000}5E is coming in 1-3 times in split to SerialDataReceivedEventArgs.

Am I reading the wrong way? I have also increase the baudrate from 9600 to 19200 but the incoming data still same as provided image. Do it has to do with the IO board program? I'm not so sure about this.


回答1:


As @jdweng pointed out, the serial port DataReceived event fires somewhat randomly. It could fire mid string and you could only receive half of the message. You'll have to build your own string. Most serial to serial communication use carriage returns (\r) or line feeds (\n) to determine that message is finished. From what you told us it looks like you tack on a <CR><LF> at the end, so we can look for the LF to know we got the whole string.

char LF = (char)10;
StringBuilder sb = new StringBuilder();
string currentLine = string.Empty;

private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
    string Data = serialPort1.ReadExisting();

    foreach (char c in Data)
    {
        if (c == LF)
        {
            sb.Append(c);

            CurrentLine = sb.ToString();
            sb.Clear();

            //parse CurrentLine here or print it to textbox
        }
        else
        {
            sb.Append(c);
        }
    }
}

So in the example above, I'm looking for a Line Feed character to know I got the whole message. (LF or \n).



来源:https://stackoverflow.com/questions/59187451/why-serialdatareceivedeventargs-receive-incomplete-data

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!