Data lost over SerialPort

I have discovered that Raptor is loosing data when it is received at certain speeds over SerialPort. I was sending data from my PC and Cobra II. It looks like there are no problems with these speeds: 600, 1200, 2400, 4800, 9600, 19200. But at these speeds some of the data is getting lost: 38400, 57600, 115200, 256000. I was sending 50 bytes every 200 ms - 1000 ms and I was counting received bytes on Raptor.
I had the same issue with G120, at some baud rates data was getting lost. I don’t remember exact baud rates - I will need to retest it.

Code snippet, please.

My G400 often raises DataReceived event with .BytesToRead = 0. Maybe it’s related.

@ iamin - What else are you doing in your application?

@ John - Nothing, just reading data.

@ iamin - No networking?

@ John - Nope.

@ Simon from Vilnius - I wrote an example code and then tried it, but I could not reproduce this behavior. So I have looked at my original code and traced down what is causing data loss. Here is the code:


Private ReadOnly _uart As New SerialPort("COM1", 115200, Parity.None, 8, StopBits.One)
Private ReadOnly _thRead As New Thread(AddressOf Read)
Private _dataInBuffer As Integer
Private ReadOnly _t As New Timer(New TimerCallback(AddressOf Time), Nothing, 1000, 1000)

Sub Main()
	_uart.ReadTimeout = 0
	_uart.Open()
	Debug.Print("Ready to start")
	_thRead.Start()
	Thread.Sleep(-1)
End Sub
Private Sub Time(state As Object)
	Debug.Print("T: " & _dataInBuffer)
End Sub

Private Sub Read()
	Dim c As Integer

	Do
		c = _uart.BytesToRead
		If c <> _dataInBuffer Then
			_dataInBuffer = c
			Debug.Print(_dataInBuffer.ToString())
		End If
	Loop
End Sub

If you comment out [em]Debug.Print(_dataInBuffer.ToString())[/em] everything works correctly.

@ iamin -

try to add Thread.sleep(1) in do… loop.

@ Dat - Your suggestion drastically reduces data losses. In 6 kB sent only 4 bytes were lost. Without [em]Sleep[/em] it was loosing on average 30%. If I increase [em]Sleep[/em] time to 5 milliseconds, it seems there no losses at all.

Can you explain what is going on? How does sleep solve this issue?

@ iamin -

All I know is, a thread without sleep will disable some interrupt more than 20ms.

@ iamin -
Hi,
to test the quality of data transfer from PC to a FEZ/Gadegteer board over serial port I transmit a known data array e.g. large array of strings from PC to the Gadgeteer device, - do no things with Debug.print during the data transfer, and then test the received data array for equality with the data I sent. When all is ready I Debug.Print a message whether there was a match or not. This way I saw no problems with lost data. As I think Debug.print is to slow to represent the datatransfer and misses some things

That’s why I have added [em]Timer[/em]. It prints out every second what is the current amount of data in the buffer. And I expect it to be 50, 100, 150, … 5000, 5050, 5100 and so on. But without using [em]Sleep[/em] I get something like 36, 71, 102, 143 …

I had a look on your code. I cannot see that you really read from the serial port. I think it’s necessary that you really read the bytes which arrived and sum up the counts of bytes you got.

c = _uart.BytesToRead

does not update the index

looks like he wanted to count only, doesn’t want to read

@ RoSchmi - RX buffer on G400 is 16KB, so I was testing if it works without any issues. I can read data from buffer, it does not change anything - I am still loosing data when Debug.Print is present. If you have Raptor, you can copy paste my code and try it.

@ Dat - yes, but this is only appropriate if you do not send more data than the size of the uart buffer, otherwise you will have a buffer overflow. iamin sends 6KB, that’s more than the size of the buffer.

Edit: My post was to early or to late. I didn’t know that the buffer is 16KB.

@ iamin - yes,I have a raptor an will try it. However I do not know, when I get the time to do it.

@ iamin -
if you are interested, you can try my little Codeshare entry “RS232 Gadgeteer <=> PC Round-n-Round” I think it was made für the raptor. Device sends a string to the PC, PC returns it, device sends the received string again to PC and so on. The string did not change.

@ iamin -
May be your problem is not the raptor but the signal quality: On a RS232 cable of 1 or 2 m length I would think that you will have problems with data rates above 19200 baud. Only for these datarates (38400, 57600, 115200, 256000) you saw the lost bytes.
You can test it if you connect RX and TX and let the raptor talk with himself. This should work even on the higher datarates.

1 Like

@ RoSchmi - For testing I was using two configurations:

  1. PC -> USB to UART converter -> 10 cm wires to Raptor
  2. Cobra II -> 10 cm wires to Raptor

@ RoSchmi - You are bringing up good points, but I think the fact that after adding [em]Sleep[/em] I get no data loss explains everything.