2012-04-12 107 views
1

我用下面的代碼片段發送GPS數據翻過一個COM端口每秒一次:串行端口緩衝器/波特率/數據丟失

serialPort = new SerialPort("COM4", 4800, Parity.None, 8, StopBits.One); 
serialPort.Handshake = Handshake.None; 
serialPort.WriteTimeout = 500; 
serialPort.Open(); 

這是一切優秀和良好的,但寫的時候使用下面的方法串口:

serialPort.Write(theString); 

theString == 504 charactors我讀出的程序,使用:

while (true) { 
     Console.Write(serialPort.ReadExisting()); 
    } 

將只會讀取該寫入資料中的數據254 bytes。 膩子也一樣發生。

我試過將寫入的數據分成254字節大小的塊並寫入兩次,但看起來第二次寫入操作雖然被我的寫入程序確認爲運行,但從未被讀取程序讀取。

我知道我的寫緩衝區是4096 bytes,我的讀緩衝區是2048 bytes

我的字符串是這樣的:

$GPGGA,191500.00,3351.6474,S,15112.6510,E,2,04,2.5,+0008,M,+020,M,00,0000*76 
$GPVTG,057.3,T,,,000.0,N,000.0,K,A*41 
$GPRMC,191500.00,A,3351.6474,S,15112.6510,E,000.0,057.3,120412,D*40 
$GPGLL,3351.6474,S,15112.6510,E,191500.00,A,A*79 
$GPGSA,A,3,,,,,,,,,,,,,2.5,1.3,2.1*34 
$GPGSV,1,1,5,03,20,40,89,06,18,30,86,12,25,15,80,20,5,36,70*77 
$GPDTM,999,,0.0,S,0.0,E,+0.0,W84*3B 
$GPZDA,191500.00,11,04,12*60 
$GPGBS,191500.00,+020.0,+020.0,+000.0,,0.00000,+0000.0,0000.0*63 
$GPMSS,999,999,200.0,4800,*56 

當我嘗試寫使用每行一個寫statment字符串中的緩衝區,它會寫的一切緩衝區,但是,兩次寫操作會得到隔行在讀者,所以結果是這樣的:

etc... 
$GPGGA,191500.00,3351.6474,S,15112.6510,E,2,04,2.5,+0008,M,+020,M,00,0000*76 
$GPDTM,999,,0.0,S,0.0,E,+0.0,W84*3B 
$GPVTG,057.3,T,,,000.0,N,000.0,K,A*41 
$GPZDA,191500.00,11,04,12*60 
$GPRMC,191500.00,A,3351.6474,S,15112.6510,E,000.0,057.3,120412,D*40 
$GPGBS,191500.00,+020.0,+020.0,+000.0,,0.00000,+0000.0,0000.0*63 
$GPGLL,3351.6474,S,15112.6510,E,191500.00,A,A*79 
$GPMSS,999,999,200.0,4800,*56 
$GPGSA,A,3,,,,,,,,,,,,,2.5,1.3,2.1*34 
$GPGSV,1,1,5,03,20,40,89,06,18,30,86,12,25,15,80,20,5,36,70*77 
etc... 

的這一切對我來說很有意義,雖然在9600波特率隔行掃描問題不occurr,(我假設,因爲4800 baud == 480bytes/s),更改波特率不一個選項,以及正常的GPS能夠在一個突發中傳輸所有這些數據。

問題:

有誰知道爲什麼我的閱讀是永遠只能撿254個字節的數據,當我寫504個字節的數據流? 是否有

serialPort.Write(Byte[], int offset, int count); 

一些約束,不允許超過254個字節? (這不會解釋第二次寫操作沒有完成)。

甚至。有誰知道寫入串口的更好方法嗎?


這種方法似乎對提供的數據工作(雖然我原來的問題仍然有效):

string Sentence = ""; 
for (int i = 0; i < block_list[total_block].Count; i+=2) { 
    Sentence = block_list[total_block][i] + block_list[total_block][i+1]; 
    serialPort.Write(Sentence); 
} 

回答

2

等一下,你說,你用一秒鐘的暫停,但你的代碼如下:

serialPort.WriteTimeout = 500; 

這是發送端的半秒超時。在4.8Kbps的速率下(大約每秒480個字符,正如你所說的那樣),只有足夠的時間發送約240個字符。

這可能是GPS可以做到這一點,因爲它沒有那個半秒超時。

嘗試將超時提高一點,看看會發生什麼 - 五秒鐘應該會給你充足的呼吸空間進行測試。在4.8Kbps的情況下,完整傳輸需要504字節以上的時間。

並確定你真的不想要任何握手?缺乏這一點也可能導致數據丟失。

+0

+1提高你的速度和超時時間。 – Simon 2012-04-12 04:13:06

+0

我有一個計時器,每秒調用一次寫入語句。我無法控制任何屬性,因爲我正在模擬真實的設備,但是我認爲寫入超時是它試圖寫入的時間,而不是它停止前寫入的實際時間。感謝您提供有價值的信息,我有點慚愧,我沒有將寫入超時與發送的數據聯繫起來! – Serdalis 2012-04-12 04:25:53