Binary Serial Data logjam

Status
Not open for further replies.

balboni

New member
I am trying to take analog readings on a Teensy 3.2 and send them to a Windows 10 computer via Serial.write. I am sending the data as soon as it is available. I am running into a problem where the data being read by the computer is occasionally being delayed. After the writing is initiated, somewhere between 17,000 and 22,000 bytes are written before there is a pause. After that, there is a pause every 8192 bytes. The Teensy code is running at a speed that there is, on average, one byte being written approximately every 10 microseconds. The pause that occurs is on the order of 30 to 40 milliseconds (which is a huge difference). I have experimented with changing the number of bytes being written at a time from 16 to 32 to 64 to 128 and still run into the same problem. Using an IntervalTimer at 750 microseconds changes the data being sent between pauses to 16384. Changing the timer to 1000 microseconds changes the data being sent between pauses to 49152. It's not lost to me that these values are all powers of two.
Does anyone have any insight as to where the delay is coming from? Is it from the Teensy or from the computer? Is there a specific recommended data rate that I should stay below? If my calculations are correct, 12.5 Mb/s translates to less that one microsecond per byte.

Thanks
 
Does anyone have any insight as to where the delay is coming from? Is it from the Teensy or from the computer?

No idea. Even if I had the exact code for both the Teensy and Windows 10 side, to truly answer this I'd have to set up a test here and watch with a protocol analyzer.

How the packet sizes Teensy sends and the way the USB controller and Windows drivers respond, especially when running close to max bandwidth, can be very complex....


Is there a specific recommended data rate that I should stay below? If my calculations are correct, 12.5 Mb/s translates to less that one microsecond per byte.

This I can answer. Generally about 1 MByte/sec transfer is possible, sometimes as much as 1.1 Mbyte/sec with a good USB controller and USB 2.0 hub with good a TT. USB high-level protocol overhead imposes an upper limit of 1.2 Mbyte/sec. But there is also data dependent protocol overhead by a bit stuffing algorithm, and overhead required by the controller chip on your motherboard to guarantee timing for SOF packets, so this 1.2 Mbyte/sec speed is never seen in practice.

But if other USB2 devices are active, or if you do small I/O operations on the Windows side, the maximum speed can be lower. USB Serial uses USB "bulk" transfer, where all the non-guaranteed bandwidth (by "isochronous" and "interrupt" transfer types) left over can be used. How much bandwidth you actually get varies. Pushing close to the 1 Mbyte/sec limit is just asking for trouble.

I can also point you to the special Serial.send_now() function. Normally data to transmit with Serial.write() or Serial.print() is efficiently packed into USB packets. When you call this function, and partial packet is immediately given to the USB controller. The drivers on the Windows side should usually respond to a short packet by making any buffered data available to your program, without waiting for more. Obviously Teensy has no control over what Windows does, but this is the usual behavior, so you can usually use this special function to trade off bandwidth for lower latency.
 
Status
Not open for further replies.
Back
Top