我正在从串行乐器中获取数据,以便在图表上进行绘图。数据流速率为230 kbps,串行流水线不到50%,数据传输速率约为100 kbps,实际上并没有真正变化,速率和数量也不同。
在同一台计算机上使用过像Teraterm这样的串行终端程序;我可以捕获数据并证明数据源和测试接收方法都很好,我发现捕获的数据没有错误。
我正在开发的Windows窗体应用程序丢失数据。我把它从接收,捕获(并行),解析和绘图,到接收和捕获都减少了。并且发现我仍然在捕获中看到丢失的数据。
我不是一个经验丰富的Windows人员,因此可能不知道更好的方法来完成相同的功能。以下是我为执行接收操作而采取的措施:
我正在使用System.IO.Ports.SerialPort类。 我通过以下方式修改.DataReceived事件:
+= new SerialDataReceivedEventHandler(comPort_DataReceive);
然后我调用open()方法。
注意:我可能在这里做了一些不正确的事情,我从来没有在任何时候使用 - =清除.DataReceived事件,而是每次打开时,事件都会再次添加。然而,即使我只与港口交谈一次,这些问题也会发生。
这是我的数据接收功能代码。 RxString是一个字符串。
private void comPort_DataReceive(object sender, SerialDataReceivedEventArgs e)
{
RxString = comPort.ReadExisting();
this.Invoke(new EventHandler(ParseData));
}
private void ParseData(object sender, EventArgs e)
{
// Save to capture file, if capture is enabled
if ((WriteToFileEnabled == true) && (WriteToFileName != null))
{
writeFileHandle.Write(RxString);
}
return;
// Previously would parse and plot data
}
那么,在这种情况下,人们如何在不丢失数据的情况下执行接收?
关注的问题包括:串行接收的缓冲区有多大,或者如果我有一个合理响应的应用程序,我是否需要担心?流量控制无关紧要,远程设备无论发生什么都会发送数据,因此我的计算机可以接收数据并对其进行处理或忽略。但是,如果我丢失了数据或遇到了帧错误和内容,我怎么知道呢? (我问最后一个没有在SerialPort类结构上搜索过多,抱歉。)
答案 0 :(得分:3)
让我们假设您的设备正在发送长度为85个字节的消息。 DataReceive事件处理程序可以触发或不触发一次以接收这85个字节。因为它可能不止一次触发您的代码必须考虑到这一点。 DataReceive事件处理程序应该读取可用的字节并将它们附加到稍后处理的缓冲区。
此外,SerialPort类引发的事件中只有一个可以一次执行。在该示例中,假设处理程序必须触发三次以接收85个字节。处理第一部分时,其他两部分无法执行。如果在处理第一部分时需要其中一个事件PinChanged或ErrorReceived,则它们也不能执行。
我对SerialPort类的前两次体验是9600 bps终端和1 Mbps蓝牙设备。对于速度较慢的工作效果并不快,但是当我想出如何更快地工作时,速度越慢就可以使用相同的方法。
我的方法论:
在打开串口之前,我启动另外两个在do循环中运行的后台线程。第一个(接收)从串行端口读取所有可用字节,将它们添加到缓冲区,并在每次读取时发出第二个线程的信号。第二个(协议)确定是否已到达完整消息,是否进行字节到字符串转换,更新UI等。根据应用程序,我可能会启动第三个处理错误和引脚更改的线程。所有这些线程都受到线程AutoResetEvent的限制。
我的DataReceive事件处理程序中有一行,AutoResetEvent上的Set是限制Receive。
这方面的VB示例可以在SerialPort Methodology找到。自采用这种方法以来,我没有遇到任何似乎困扰其他SerialPort用户的问题,并且已成功使用它,速度高达2Mbps。