2
votes

I'm using the following code snippet to send gps data accross a com port once a second:

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

This is all fine and good, but when writing to the serial port using the following method:

serialPort.Write(theString);

with theString == 504 charactors My read program, using:

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

will only ever read 254 bytes of data from that write statment. The same occurrs with putty too.

I have tried splitting the write statment into 254 byte sized chunks and writing twice but it appears that the second write operation, although confirmed as run by my writer program, never gets read by the reader program.

I know my write buffer is 4096 bytes and my read buffer is 2048 bytes.

My string is this:

$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

When I try to write to the buffer using one write statment per line in the string, It will write everything to the buffer, however, two write operations will get interlaced in the reader, so the result is this:

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...

None of this makes sense to me, although at 9600 baud rate the interlacing problem does not occurr, (I assume because 4800 baud == 480bytes/s), Changing the baud rate is not an option, and somehow the normal GPS is able to transmit all this data in one burst.

QUESTION:

Does anyone know why my read is only ever picking up 254 bytes of data when I am writing 504 bytes of data to the stream? Is there some constraint on

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

that does not allow for more than 254 bytes? (which would not explain the second write operation not completing).

Or even. does anyone know of a better way to write to the serial port?


This method appears to work for the data provided (although my original question still stands):

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);
}
1

1 Answers

2
votes

Hang on, you stated that you used a one-second timeout but your code reads:

serialPort.WriteTimeout = 500;

That's a half-second timeout on the sending side. And at 4.8Kbps (which is roughly 480 characters per second, as you state), that's only enough time to send about 240 characters.

It may be that the GPS can do this because it doesn't have that half-second timeout.

Try bumping the timeout up a bit and seeing what happens - five seconds should give you plenty of breathing space for testing. At 4.8Kbps, 504 bytes will need a little more than a second for full transmission.

And be sure you really don't want any handshaking? Lack of that may also cause data loss down the track.