9

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?

canisrufus
  • 205
  • 3
  • 8
  • 2
    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 '14 at 02: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 '14 at 02: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 '14 at 07:33
  • 1
    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 '14 at 08: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 '14 at 09:27
  • Agree with clabacchio - the title drew me in, but could be a lot better for search/archiving. – Cybergibbons Jan 19 '14 at 20:44

4 Answers4

7

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.

Connor Wolf
  • 31,938
  • 6
  • 77
  • 137
  • 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 '14 at 02:34
  • Yeah I'd be happy to do open up the adapter next week (when I have access to the hardware again.) FWIW I believe this is the box we're using: http://www.sealevel.com/store/serial/asynchronous-serial/usb/2402-usb-to-4-port-rs-422-rs-485-db9-serial-interface-adapter.html – canisrufus Jan 19 '14 at 02:37
  • @canisrufus - Cool. At the moment, I'd strongly suggest just using a ExpressCard RS485 adapter, if you're interested in the simplest solution. There are multiple companies that make such devices, that that would almost certainly solve the latency issues. – Connor Wolf Jan 19 '14 at 02:42
  • Would this plausibly work? Do you have a company that you might trust/respect more? :) http://www.sealevel.com/store/serial/asynchronous-serial/pci-express/7804e-pci-express-8-port-rs-232-rs-422-rs-485-serial-interface.html – canisrufus Jan 19 '14 at 02:44
  • 7
    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 '14 at 02:53
  • Connor it seems like you might be gone for the night. Thanks for this answer, it makes me wish I'd stopped in here a couple of months ago. I'm very intrigued by picking up a due and other hardware to build a microcontroller. I asked a question about it here: http://electronics.stackexchange.com/questions/96897/how-would-i-make-an-arduino-due-recieve-rs-232-422-signals – canisrufus Jan 19 '14 at 03:27
  • 1
    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 '14 at 03:43
  • 1
    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 '14 at 03:44
  • fwiw, I'm not sure leaning on the serial port vendor would be worthwhile. The driver can be tweaked any way you like, but it's the software that reads the port and establishes a time for the data received that's the weak point. Ideally that s/w reads the input message, and establishes the time as close together in time as possible. Unless you have a realtime OS, all manner of non-deterministic events can wreck that. E.g., you read the range message, then just as you're about to mark the time, Boom! Preemptive scheduler runs something else for 50 msec, before you come back to note the time. – JustJeff Jan 19 '14 at 04:16
  • @JustJeff - I *largely* agree, though if you're careful, you can often manage < 20 ms determinacy even on windows. You just need to manage the HELL out of the running processes, and turn all the services you don't need off, etc... – Connor Wolf Jan 19 '14 at 04:18
  • .. and of course, avoiding the introduction of special hardware when the the OP is a self-professed web programmer, and achieving 20msec, is probably a fair trade. – JustJeff Jan 19 '14 at 04:27
  • @JustJeff - Some of the people hacking on networking buffer issues have managed <300 uS jitter over USB using GPSes for a timing source (though they're using linux): https://lists.bufferbloat.net/pipermail/thumbgps-devel/2012-March/000109.html – Connor Wolf Jan 19 '14 at 04:33
  • @ConnorWolf network devices in Linux are handled *very* differently from any other device. Check your /dev/ directory for an eth0 device, you won't find it. Network adapters are optimized for performance/speed/data-volume to the extreme and you don't want the regular device subsystem overhead. Then again, the USB part is probably handled as a regular USB device, so it is still a nice accomplishment. – jippie Jan 19 '14 at 07:47
  • @jippie - I know that. If you read the discussion, you'll see that they're using *usb GPS units* to derive an **independent** timebase for timing their network stuff. – Connor Wolf Jan 19 '14 at 08:10
  • 2
    +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 '14 at 08:20
  • @markt - Yeah, they're great deals. I mostly mentioned the Due first because it probably has the easiest tool-chain to get *started* with. I don't think going from zero to a working app on something like some of the STM32F boards is too easy for someone who isn't familliar with reading datasheets, etc..., since they are rather sparse WRT examples. The Due has the advantage of having the Arduino "training wheels", with the advantage that you can ignore them if needed. – Connor Wolf Jan 19 '14 at 08:26
3

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.

JustJeff
  • 19,163
  • 3
  • 48
  • 75
  • 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 '14 at 21:59
3

What I would probably do is multiplex the serial data into a new serial datastream at higer rate, with a static interleave. Then feed the datastream through USB-UART to the computer. That way you would know that the first byte is from device 1, the second byte from device 2, the third byte from device 3 and in this case a fourth byte as CRC or sequence number. Throw in a couple bytes start of frame marker to sync on the datastream, padding bytes if no data available and you're done. You may not know the absolute time, but you do know that the relative time between the various data chunks.

jippie
  • 33,033
  • 16
  • 93
  • 160
1

I'd also go with a microcontroller to receive the RS data, timestamp it, and forward it to the PC. You can't do any I/O timing critical work with a Windows PC (except with a sound card, perhaps), because the software and the drivers are changing all the time as drivers are updated behind your back.

But the first thing I would do is to get a USB logic analyzer, you can buy one for less than USD100, grab some messages from the GPS receiver and check out exactly when each byte is received. Use that info to try out / calculate exactly how accurate the timing of the data is in the first place: e.g. exactly what and when the GPS box transmits. Then you can you can work out what accuracy is achievable, and how much effort you would be willing to have in order to get to a certain level of accuracu.

enter image description here

Above, a picture of some (Saleae?) USB logic analyzer.


[Edit] Haha, using the sound card could be a funny way to make it actually work; you could connect the UART data to the sound card input (via some resistors and capacitors) and write software to detect each edge in the serial stream, giving you beautiful timing accuracy!. Ok, I'm not really suggesting this seriously, just for some laughs!

PkP
  • 7,567
  • 2
  • 23
  • 42