2010-06-01 199 views
5

我已经在VS2008 Express中设置了一个SerialDataReceivedEventHandler,它带有一个基于表单的程序。我的串行端口设置如下:C#.Net Serial DataReceived对于高速率数据,事件响应速度太慢

115200,8N1

DTR和RTS启用

ReceivedBytesThreshold = 1

我有我与通过蓝牙,USB转串口接口的设备。超级终端在任何数据速率下都可以很好地接收数据。数据以22字节长的数据包定期发送。该设备具有可调整的数据发送速率。在低数据速率,10-20Hz时,下面的代码工作良好,没有问题。但是,当我将数据速率提高到25Hz时,就开始在一次呼叫中接收多个数据包。我的意思是,每个传入数据包都应该有一个事件触发器。在更高的输出速率下,当事件被调用时,我立即测试了缓冲区大小(BytesToRead命令),然后缓冲区中有多个数据包。我认为这个事件缓慢发作,并且在达到代码时,更多的包装已经冲击缓冲区。我做的一个测试是查看事件每秒触发多少次。在10Hz时,我得到10个事件触发器,真棒。在100Hz时,我得到了40个事件触发器,不太好。我的目标数据速率是100HZ是可以接受的,200Hz的首选,和300Hz的最佳。这应该可以工作,因为即使在300Hz时,也就是52800bps,不到波特率115200的一半。我在看什么?

public Form1() 
    { 
     InitializeComponent(); 
     serialPort1.DataReceived += new SerialDataReceivedEventHandler(serialPort1_DataReceived);    
    } 


    private void serialPort1_DataReceived(object sender, SerialDataReceivedEventArgs e) 
    { 
     this.Invoke(new EventHandler(Display_Results)); 
    } 


    private void Display_Results(object s, EventArgs e) 
    { 
     serialPort1.Read(IMU, 0, serial_Port1.BytesToRead); 
    } 

回答

3

为什么你的invoke()调用DisplayResults?

这会将其推送到MessageLoop,这是一个不必要的延迟。

如果DataReceived()将数据推送到用于解耦处理的(线程安全)队列上,会更好。

我也认为你可能会遇到拆分包的问题。

+0

我试着删除Invoke()调用,并直接在DataReceived()事件中读取数据,结果相同。对不起,有点天真,但你能告诉我更多关于你如何排队的原因,以及为什么这样工作更快。谢谢您的帮助。 – Matthew 2010-06-02 05:52:15

1

可以尝试设置ReceivedBytesThreshold = 22,这将导致该事件被解雇时,至少有22个字节读取。请注意,这将是至少 22.可能还有更多。

虽然我不认为我会亲自这样做,因为如果将来您的数据包大小发生变化,例如12字节会发生什么?你最终会在缓冲区中有12个字节,但根本不会触发事件。

更好的是将其设置为1,当至少为时将触发事件1个字节可用。然后将所有收到的字节按Henk已发布的方式推送到列表或队列中。

请注意,DataReceivedEvent并不知道您认为数据包当然是什么。它只在有可用字节时触发。开发人员可以将这些字节组装成有意义的消息或数据包。

4

您是否试图调整USB串行转换器的时间延迟?我有一个FTDI USB转串口转换器的问题。我使用示波器查看来自设备的IN和OUT数据,我发现计算机的响应速度一直很慢。默认情况下,设备上的时间延迟设置为16毫秒。我将其更改为2毫秒,这有很大的不同。在设备管理器中转到您的USB串行转换器并在高级设置中,将延迟时间更改为2毫秒。它应该工作。尝试一下。

+1

任何想法为什么“16ms”延迟转换为接收数据串之间的数百毫秒? – supercat 2014-02-14 20:46:46

0

问题在于接收到的数据处理程序。

我跑了一个单独的线程while(true)循环和serial.ReadLine(),都完美的作品。

using System.Threading; 

Thread readThread = new Thread(Read); 
readThread.Start(); 

希望别人不需要花费3小时来解决这个问题。