Author Topic: A weekend project: low-latency USB to RS-485 and CAN  (Read 1008 times)

0 Members and 1 Guest are viewing this topic.

Offline smilingfishTopic starter

  • Newbie
  • Posts: 7
  • Country: kz
A weekend project: low-latency USB to RS-485 and CAN
« on: October 05, 2026, 01:10:27 am »
Last spring my student worked with a three-axis manipulator over RS-485 and ran into 16 ms latency with his FT232-based USB adapter. He later found how to set the latency timer to 1 ms, but it was still not good enough for the application.

So I decided to spend a weekend and some Astra tokens building my own USB adapter. It uses STM32F405 and has a few features I wanted for my bench use:
- galvanic isolation;
- software-controlled line termination;
- software-selectable RS-485 / CAN on the same connector pins;
- logging and a small dashboard with communication statistics.
The CAN mode is not fully compliant ISO 11898-2 physical layer, but works for bench testing and debugging CAN devices.
I planned using a CA-IS3098W transceiver but did not find one, and used TDA51S485 instead. It specifies 500 kbaud only, although worked reliably at 6 Mbaud.

I compared the round-trip time for 16384 8-byte request / 8-byte response transactions under Windows. For latency measurement I turned one device to a responder with a fixed 10 us response delay (the actual measured delay was about 11–12 µs). The three competitors were:
- FT232H, latency timer set to minimal 1 ms, D2XX driver (VCP driver showes very similar values)
- "FT232" $2 clone adapter from AliExpress, its clone chip marked FT232RL
- CP2102

Charts 1 and 2 - RTT histograms measured at 115 kbaud and maximum error-free baud rate for each adapter.
Chart 3 - RTT with simutaneous bulk transfers through the same USB hub, 15 MB/s read + 15 MB/s write
 

Offline smilingfishTopic starter

  • Newbie
  • Posts: 7
  • Country: kz
A weekend project: low-latency USB to RS-485 and CAN
« Reply #1 on: October 05, 2026, 01:37:44 am »
Firmware.

Naturally, I did not write any of the firmware code myself. It was generated entirely by an LLM. The 512 kB Flash currently fits a bootloader, version management, and both “golden” and “silver” firmware. The device enumerates as a composite USB device and also exposes a small disk, which contains an HTML dashboard showing the current operating mode and transfer statistics. Firmware updates can simply be copied onto the same disk.
There is still a lot of room to add higher-level functionality if needed, for example protocols such as Modbus, or application-specific tracing and diagnostics.

I also put the programming documentation on the same disk as README.md, together with the hardware schematic exported as JSON, just the netlist plus component values. The idea is to keep machine-readable documentation on the device itself that an LLM can immediately work with the firmware and hardware.
« Last Edit: October 05, 2026, 04:35:08 am by smilingfish »
 

Offline Renate

  • Super Contributor
  • ***
  • Posts: 1746
  • Country: de
    • Renate's Android Page
Re: A weekend project: low-latency USB to RS-485 and CAN
« Reply #2 on: October 05, 2026, 05:31:02 am »
Yeah, I've run into this.

The FTDI has parameters for latency.
In Linux with the driver you can:
Code: [Select]
#include <linux/serial.h>

struct serial_struct serial;

ioctl(fd, TIOCGSERIAL, &serial);
serial.flags|=ASYNC_LOW_LATENCY;
ioctl(fd, TIOCSSERIAL, &serial);

Internally this is controlled by USB vendor messages:
Code: [Select]
#define FTDI_SET_LATENCY_TIMER 0x09
#define FTDI_GET_LATENCY_TIMER 0x0a

I built my own fake FTDI.
I made a 200 µS timeout on external RX to sending USB IN.
At my speed a byte is 86 µS.
That's presuming that what is sending is stutter free.
 

Offline moffy

  • Super Contributor
  • ***
  • Posts: 3035
  • Country: au
Re: A weekend project: low-latency USB to RS-485 and CAN
« Reply #3 on: October 05, 2026, 06:51:16 am »
The USB frame frequency for low speed and full speed is 1kHz and for high speed 8kHz. https://en.wikipedia.org/wiki/USB_communications
 

Offline udok

  • Regular Contributor
  • *
  • Posts: 83
  • Country: at
Re: A weekend project: low-latency USB to RS-485 and CAN
« Reply #4 on: October 05, 2026, 07:25:39 am »
RS232/RS485/Parallel-Port is interrupt driven and can therefore handle packages of a few bytes in a few µs.

USB is designed for high troughput with rather large packages and not for low latency protocols. 
USB is packet oriented with a 1 ms time slot (125µs with high-speed). 
Therefore round trip latency cannot be better than 2 ms (or 250 µs with high speed) in the worst case.

In real life the windows driver buffering and the task switch timer intervall of about 16 ms increases latency further. 

I have build an USB adapter which maps the Audio Precison S1/S2 parallel port to USB (www.s1usb.com).
It works very well, but despite the significantly higher throughput of USB, it is not as fast as the original parallel port.
« Last Edit: October 05, 2026, 07:43:53 am by udok »
 

Offline smilingfishTopic starter

  • Newbie
  • Posts: 7
  • Country: kz
Re: A weekend project: low-latency USB to RS-485 and CAN
« Reply #5 on: October 05, 2026, 07:58:09 am »
USB is packet oriented with a 1 ms time slot (125µs with high-speed).
Therefore round trip USB latency cannot be better than 2 ms (or 250 µs with high speed) in the worst case.
Not necessarily. The frame/microframe structure does not work quite that way. In the true worst case, RTT can actually be much longer if the host controller is servicing many endpoints generating a lot of traffic. There is no simple way to assign an arbitrary priority to a particular bulk endpoint.
But normally a transfer does not have to wait for the next frame or microframe. The host controller can schedule multiple transactions, in both directions, within the same microframe as long as there is available bus time.
At 480 Mbit/s, the actual time of a short bulk transaction is below 1 µs. Protocol overhead and inter-packet gaps are significant addon to a small payload, but still very short compared with a 125 µs microframe. So a request and its response can quite easily both occur within the same microframe.
 
The following users thanked this post: moffy

Offline spostma

  • Regular Contributor
  • *
  • Posts: 189
  • Country: nl
Re: A weekend project: low-latency USB to RS-485 and CAN
« Reply #6 on: October 05, 2026, 08:48:20 am »
Interesting project!

Have you tried what the latency of off-the-shelf 480Mbps USB2-to-uart converters
such as the WCH CH9111L, CH9114F or CH347F chips is
when you activate event character triggers for the receiver?

these chips should support 15Mbps on the UART, so the USB slave must be a fast processor.
The hardware should enable low-latency comms as long as the PC driver behaves well (utilizes microframes and event chars).

These USB2-to-UART boards can be found on AliExpress for evaluation.
 

Offline spostma

  • Regular Contributor
  • *
  • Posts: 189
  • Country: nl
Re: A weekend project: low-latency USB to RS-485 and CAN
« Reply #7 on: October 05, 2026, 09:23:38 am »
By the way, I found that USB2 hubs with Multiple Transaction Translator (MTT) architecture
really speed up USB2 traffic a lot if many small packtets are transmitted.

These MTT hubs are often recommended for low latency audio over USB;
simply plug your low latency device into a MTT USB2 hub.

USB2 Hub chips with MTT are for example Terminus FE2.1, WCH CH334/335/CH336,
with the tiny crystal-free CH334R being my favourite.

---

Another gotcha is that plugging your device into an USB3 port will reduce latency,
see the quite interesting 'Resolving USB Speed Mis-Detection: Full vs High-Speed on Linux' page:
https://industrialmonitordirect.com/blogs/knowledgebase/resolving-usb-speed-mis-detection-full-vs-high-speed-on-linux#section-4

which says:
HCD stack  Typical FS round-trip latency Notes
uhci_hcd    1.0-2.5 ms                       Frame-locked, polling-based interrupt scheduling
ohci_hcd    1.0-2.0 ms                       Similar frame scheduling, slightly more efficient isochronous handling
ehci_hcd (HS hub TT) 0.3-0.8 ms       Microframe scheduling on HS upstream
xhci_hcd (native FS)    0.125-0.4 ms  Microframe scheduling, integrated TT
 
The following users thanked this post: moffy

Offline smilingfishTopic starter

  • Newbie
  • Posts: 7
  • Country: kz
Re: A weekend project: low-latency USB to RS-485 and CAN
« Reply #8 on: October 05, 2026, 09:58:54 am »
plugging your device into an USB3 port will reduce latency,
I suppose the old drivers have mostly become history, and virtually all computers of the last decade use xHCI to handle their USB ports. And xHCI can indeed perform efficient scheduling within a microframe.
 

Offline mikeselectricstuff

  • Super Contributor
  • ***
  • Posts: 14779
  • Country: gb
    • Mike's Electric Stuff
Re: A weekend project: low-latency USB to RS-485 and CAN
« Reply #9 on: October 05, 2026, 10:06:50 am »
Last spring my student worked with a three-axis manipulator over RS-485 and ran into 16 ms latency with his FT232-based USB adapter. He later found how to set the latency timer to 1 ms, but it was still not good enough for the application.
Did you try using the FTDI high-speed USB parts - FT232H etc. ?
May also improve latency if you pad the packets to force transmission before the timeout is needed
« Last Edit: October 05, 2026, 06:02:44 pm by mikeselectricstuff »
Youtube channel:Taking wierd stuff apart. Very apart.
Mike's Electric Stuff: High voltage, vintage electronics etc.
Day Job: Mostly LEDs
 

Offline SiliconWizard

  • Super Contributor
  • ***
  • Posts: 17799
  • Country: fr
Re: A weekend project: low-latency USB to RS-485 and CAN
« Reply #10 on: October 05, 2026, 05:34:44 pm »
Those using a FTDI chip will face this "latency" due to how they buffer data internally. The only sure way of having a data packet "sent" from device to host "ASAP" (note that ASAP will depend on the host OS as well) is to trigger that using the "send immediate" pin of the FTDI chip (SIWU# pin). The HS chips have it, I really don't know about the FS-only chips, which I haven't used in ages.

"sent" was in quotes because with USB, devices can not send data to the host on their own. They can only get ready to send data, and then the host will periodically issue a IN token to see if a device has some data to send. So with FTDI chips in particular, the "send" latency will depend both on the frequency of IN tokens from the host side and on the internal buffering (FIFO) of the chip, which will prevent acknowledging a IN token if the FIFO doesn't contain a minimum amount of data , or some timeout has occured, whatever happens first - the goal being to optimize throughput rather than latency by default.
 


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf

 

-->