为什么 SerialDataReceivedEventArgs 收到不完整的数据?

Why SerialDataReceivedEventArgs receive incomplete data?

我目前正在研究 IO 板。串行对象已初始化并侦听传入数据。我正在使用 SerialPort1.ReadExisting(); 读取传入数据作为传入字符串,预计在每次读取时都会以 {X000000}5E + \r\n 形式到达。

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");
    }
}

当像那样使用 ReadExisting() 时,我得到了我想要的结果,我会得到介于“{X”和“}”之间的值,但是当我做一个 split char 时,我总是出错关于索引超出范围。我改变了读取方式,在读取的时候加上Environment.NewLine来判断数据是否接收完整。结果将如下图所示。

我也根据 SO 答案尝试如下所示,但传入的字符串数据将与上图相同:-

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.

我读错了吗?我还将波特率从 9600 增加到 19200,但传入的数据仍然与提供的图像相同。跟IO板程序有关系吗?我不太确定。

正如@jdweng 所指出的,串行端口 DataReceived 事件有点随机触发。它可能会触发中间字符串,您只能收到一半的消息。您必须构建自己的字符串。大多数串行到串行通信使用回车 returns (\r) 或换行符 (\n) 来确定消息已完成。根据您告诉我们的内容,您似乎在末尾添加了 <CR><LF>,因此我们可以查找 LF 以了解我们获得了整个字符串。

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);
        }
    }
}

所以在上面的例子中,我正在寻找一个换行字符来知道我收到了完整的消息。 (LF 或 \n)。