2012-04-12 166 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