2010-06-01 265 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小時來解決這個問題。