# What can I do to decrease the latency from these serial ports which are attached to a PC via a Serial to USB adapter?

I think I have accidentally discovered a need in my life for embedded systems. Which is great! And kind of scary. And I need help.

Background: I got hired to build a GUI application which takes scans from two SICK LMS-291s and integrates them with a sub-inch accuracy GPS, so you know where each scan occurred. As the naive web programmer I am, I understood that timing would be important, but didn't realize it would also be hard! If you don't know when each GPS point and each scan occurred, you can't figure out where the scans occur. Oops.

They had specified windows 7 as the platform, as well as bought a SeaLevel RS422 to USB box to hook up the sensors and GPS to, and in short order I discovered my folly. Somewhere between the sensors and my computer program, something was keeping the scans from arriving in a timely manner. The LMS spits out 75 scans per second, or at 13.32 ms/scan. My program doesn't get them in a timely manner. It gets them every 100 or so milliseconds, in groups of 7 or 8 or 10 or something. Also sometimes not enough scans show up, or they're mangled. Either this SeaPort adapter is only sending ten times a second (is that possible? I don't know how USB works) or Windows isn't checking the buffer (there must be a buffer somewhere, right?) nearly often enough.

Present Day: This leads to some inaccuracies that the client is basically okay with. I'm not, though, and since I've got a chance to do similar work for the client (integrating more sensors inputs!), I'd like to figure out how to do it right, e.g. given the accuracy of the GPS, be able to give guarantees about the precision and accuracy of the scan locations.

What does that look like? I need a UI, and to be able to check input from these three devices every 13.32 milliseconds. If I used FreeRTOS with, say, Nano-X for the GUI, run on a laptop they provide, would that sound like a sane solution? Is it possible that the RS-422 to USB adapter is causing these delays, and using Windows is actually just fine for this purpose?

-
Who did you have to murder to get those laser range-finders, and did he have a friend who might have some as well? –  Connor Wolf Jan 19 at 2:16
@ConnorWolf Hah! I wish I owned them. It's for ag (determining crop volume), so they were willing to shell out for hardware (tractors can cost $75k...), but unwilling to shell out for programming talent. – canisrufus Jan 19 at 2:33 I don't know the buffer size in Windows, but you certainly want to check that. On Linux these buffers are 4kB in size and depending on the data you are sending and the system calls you use, a program may only receive 4kB data chunks. If that is the issue you want to carefully check which system calls you use to read from the buffers. – jippie Jan 19 at 7:33 I suggest you look into getting a direct serial connection - you can get serial port cards for PCs and laptops (also note that most Panasonic toughbooks still have serial ports as standard). This will get away from any buffering issues in the USB-serial interface. Windows 7 has good enough realtime capability so you probably don't need to move off that. – ConcernedOfTunbridgeWells Jan 19 at 8:52 Just a comment: the title is funny, but doesn't help a lot figuring out the content of the question: could you clarify it? – clabacchio Jan 19 at 9:27 show 1 more comment ## 3 Answers The problem is almost certainly in the USB buffering related to the USB-RS422 converter. USB has variable and fairly high latency. The easiest solution would just be a better RS422 interface, ideally something PCI/PCI-e based. That would solve the latency issues. You may also be able to modify the USB polling rate, though this is fairly dependent on the host OS (what platform are you on?). For what it's worth, I looked about on sealevel system's website, and it is MASSIVELY infected with marketing bullshit. They literally spend like 10 pages and multiple white-papers on saying "we use a USB hub internally, rather then doing MCU multiplexing". Hey SeaLevel! That's what the cheap-ass$50 4-port USB-serial interface I bought on e-bay from china does too! You're not special, even if you write half a dozen vapid whitepapers trying to make it sound like you are!

Have you tried to force those things to use FTDI drivers? I'd put money on it they're just using bog-standard FTDI FT232 or similar. Can you pop the box on one of them open, and take pictures?

If you really want to spin your own hardware, for fun or educational opportunities, I'd strongly suggest you not try to do everything in the hardware. Since you need to simply time-correlate all three signals, all you really need is something that can listen on three serial lines (two RS422, one RS232 (the GPS)), time-stamps the data, and forwards it to the main computer.

Once the data is time-stamped, you're free to have all the buffer-latency you want, since you can always just look at the time-stamps.

Realistically, if you have no base in hardware, designing something with enough crunch to draw a nice GUI is quite the undertaking.

Personally, I'd probably throw a fairly chunky ARM MCU at the buffering issue, and be done with it. Despite the fact that it's an Arduino, the Arduino Due has plenty of SRAM, and is more then fast enough for what you need (and there is lots of support, which is always nice).
Alternatively, the STM32 series has similar performance, and is more intended for "advanced" users (read, there are fewer, or no examples to reference). ST makes lots of quite nice, extremely inexpensive eval boards as well.

With the Due, you do get a native USB port, for which you could roll your own CDC driver if you wanted. Some of the STM32 boards have native USB as well.

-
Regarding OS: I'm using windows 7 on a single core tablet at the moment. I can also use a laptop and install whatever I want. –  canisrufus Jan 19 at 2:34
Dedicating a microcontroller to correlating the data, then forwarding it to a windows box for display purposes is the way I'd go too. +1 –  JustJeff Jan 19 at 2:53
The card you link would probably work, though from how full of bullshit SeaLevel seems elsewhere, I'm not sure I'd trust them. For what it's worth, they do mention that that PCI-e card uses a 16C954 hardware quad uart IC (presumably there are two of them on the card). –  Connor Wolf Jan 19 at 3:43
Really, I think the only proper solution would be to call them and just ask about having latency issues. There may be things that can be tuned in their driver! –  Connor Wolf Jan 19 at 3:44
+1 on the STM32F4 solution; the STM32F4-Discovery board is comically under-priced, has up to 6 UART's, and a USB OTG FS port. If you're not familiar with embedded design then you're going to find it pretty challenging to get USB running on it; simplest to just hook in through a UART with an FTDI cable. The Coocox IDE is free, has no code size limits, and supports the Discovery board reasonably well. –  markt Jan 19 at 8:20

If I understand the question, what this comes down to is taking time/place messages from GPS over one serial line, and correlating range data messages received over other serial lines. Ideally, the range finder messages would have their own time stamp, and if you could synchronize all the clocks, you'd be able to pin down the location where the range was taken by interpolating the range time stamp between the two gps messages with the closest matching time stamps. But of course, you don't have that.

A couple of solutions come to mind, all along the lines of using a microcontroller to do the real-time data correlation, and pumping the output of that into the PPC for display purposes. Basically the microcontroller is there to deal with the tight timing issues.

So for a simpler solution, all you'd need is some way to collect all the messages from the several different serial lines, and combine them into a single stream, in the order they were received in, and pump that into the PC. You can infer that any range finder message between two GPS messages occurred sometime between those two messages.

This gives you a degree of uncertainty of course, dependent on the frequency of the GPS messages. The trade-off is that as you increase the GPS message frequency (to get more accurate correlation), you increase the demands on the microcontroller, and the demands on the serial link into the PC. At an extreme, the serial link is saturated with GPS messages with an occasional range message thrown in. Obviously most of those GPS messages are not needed. The advantage of this solution though, is that the micro has very little to do, from a software standpoint. You could do it all in a simple loop of assembly language, no OS required.

For a more complex solution, you can form a local clock in the micro, and use the GPS to synchronize that clock, so that when you get a range message, you can obtain a time stamp using the micro's clock. Using a micro with a crystal timebase, you could probably get by with 1Hz GPS messages and still get much better than millisecond accuracy times stamped on the range messages. A competent embedded systems person could probably also pull this one off in assembler on a lower end micro, but you mentioned you're just starting out. You could look at a more powerful micro that can run linux, and probably find a pre-existing solution for synchronizing the linux clock to the GPS.

-
Easier than building a real-time clock in the MCU and syncing it using GPS is just to use any of the timer/counter peripherals to measure the number of cycles between GPS message and range-finder message, and add that delta-time information to the data stream. –  Ben Voigt Jan 19 at 21:59