【发布时间】:2017-05-19 23:43:04
【问题描述】:
请看下面我的代码,它是应用程序的一部分,目的是根据通过串口接收的数据绘制在线图表。而那部分代码负责接收和绘制:
private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e)
{
rx_str = serialPort1.ReadTo("\r\n");
//rx_str = serialPort1.ReadExisting();
serialPort1.DiscardInBuffer();
this.Invoke(new EventHandler(rx_parse));
}
private void rx_parse(object sender, EventArgs e)
{
Match mch = Regex.Match(rx_str, ex_reg);
data.Add(Convert.ToInt16(mch.Value.ToString());
chart1.Series["Series1"].Points.AddY(Convert.ToDouble(data[tab_size]));
tab_size++;
}
使用的变量之前创建的:
rx_str - 字符串
数据 - 双打列表
tab_size - 整数
ex_reg - 使用的正则表达式模式
在这种情况下,我在从缓冲区同步接收到的数据时遇到了真正的问题。 为了测试它,我通过微控制器中的 ADC 测量一些东西并将其作为字符串发送到 PC。
让我们举个例子 - 接收到的数据可能如下所示:373\r\n
我正在使用正则表达式从接收到的字符串中只取数字。数据经常从缓冲区获取字符串 rx_str,例如:73\r\n3、3、\n37、\n3 等,而不是每个周期的 373\r\n。所以,然后我处理顺序错误的数据,这会导致图表中的错误结果。
请给我一个建议,当我每次从缓冲区获取数据时,如何同步它以接收相同的符号顺序。我的意思是获得相同形式的接收数据。 我补充说我已经通过终端检查过,一切正常,每次都是相同形式的数据。对于此示例 - 373\r\n
【问题讨论】:
-
Invoke() 调用会导致大量延迟。通常非常麻烦,因为它很可能导致 Close() 调用死锁。但这里有必要避免 rx_str 上的线程竞争错误。这使得 DiscardInBuffer() 非常致命,它会丢弃您尚未读取的数据。究竟失去了什么是不可预测的。它必须从代码中删除。 Invoke() 导致的延迟仍然可能由于溢出错误导致额外的数据丢失,请务必同时实现 ErrorReceived 事件,以便您看到发生的情况。
-
请注意,这保证会出错,您永远不会从图表中删除任何数据。这将使它越来越慢。一旦 UI 跟不上数据速率,并且串口握手不够可靠,那么接收缓冲区就会溢出。失去对 UI 的所有控制通常也会引起注意。
标签: c# serial-port