3

I need to know if I can get acceleration data from an IMU at 500Hz via USB.

I've been going through the code that the manufacturer provides and trying to improve it. Right now I cannot go faster than 166Hz. Things I've tried:

  • Switched from streaming mode to polling. The reason is that in streaming mode the SDK of the manufacturer uses the ioctl library to know if there is new data to be read. The faster I would go was 10Hz. In polling mode, every N milliseconds data gets read from the port using a standard read command. I went from 10Hz to 166Hz, that is, for N=6. But with N<6 I get no improvement. 166Hz is a ceiling right now.

  • Increased the process priority. This has no effect at all. Maybe because I'm only running the browser and the code I'm working on?

Yes, I know linux is not a real time system. At the end of the day I'll have to live with that. I may use xenomai later on the code. But right now I need to know how fast I can go. Not theoretically, but in a real application. Any ideas about how to increase the performance?

EDIT: This are the timestamps of the time I get the data, in millisencods. Note the bursts.

 1449258970519 
 1449258970519 
 1449258970525 
 1449258970531 
 1449258970531 
 1449258970543 
 1449258970543 
 1449258970543 
 1449258970549 
 1449258970555 
 1449258970555 
 1449258970562 
 1449258970567 
 1449258970567 
 1449258970573 
 1449258970579 
 1449258970579 
 1449258970585

EDIT: The amount of data that I have to transfer is very small... say at most 16 floats, plus some headers. I can safely assume 128 bytes is enough. So 128x1000 is still A LOT less than the 480 Mpbs that USB 2 offers.

cauchi
  • 1,192
  • 2
  • 13
  • 22

3 Answers3

5

You can get 166Hz.. that's interesting as I thought the default polling rate for USB was 125Hz.

Still, you'll possibly need to modify your kernel, drivers/usb/input/hid-core.c - set the polling rate there. There's a fair bit of info on the internet about updating mouse polling rates to 1000Hz (those gamers....) either with a tweak to the configuration. It might have some info relevant to your device.

You'll probably have to post this question on a Linux board to get detailed info however.

The other alternative is to buffer - most cases don't matter if you poll at 100Hz if each read grabs 10 commands of data!

gbjbaanb
  • 48,354
  • 6
  • 102
  • 172
3

500Hz through USB, assuming 8 or 16 bit data, should be no problem. I've worked on an application that sampled 4 16 bit channels at 8kHz, and I didn't even have to give it any consideration to make it read that fast.

How are you hitting your 166Hz ceiling? Are you at 100% cpu usage on the client? Are you hitting 100% utilization on your USB device? What USB interface are you using? Is it custom by the manufacturer of your device, or does it use something common like an FTDI USB-UART chip?

For some devices and interfaces there is a way to specify how many bytes should be buffered before the OS indicates there is anything to be read. Set that to 1 byte and see if that solves your problems.

Without more specific details about what device, what interface, and how you're communicating over USB, we can't solve your problems, we can only speculate.

Edit: If you need your software to make a decision and respond back at a 500hz granularity, you're out of luck, as no desktop operating system is real-time enough to reliably do that. If you just need to read the data and make a decision 'every now and then' as in every few 10s of milliseconds or less frequently, then you'll be fine.

whatsisname
  • 27,463
  • 14
  • 73
  • 93
  • The CPU usage is very low. I mean I'm hitting a ceiling in the sense that the lowest "efective" sampling interval I get is 6ms. I can ask for 1ms, the IMU will generate the data at 1ms (I can check the timestamps), but it will get in spurs with an efective sampling rate of 6ms anyway. – cauchi Dec 04 '15 at 12:23
  • I'm using usb 2.0. I'm accessing through /dev/ttyACM0. We use a real time library for linux called xenomai, and believe, you can get 500hz granularity. – cauchi Dec 04 '15 at 12:30
  • from the data communications protocol, the "UART BAUD RATE" can be changed. So I'm guessing the communication channel uses USB-UART. I'm going through the baud rate right now. – cauchi Dec 04 '15 at 14:23
  • @cauchy: with an effective rate of 6ms, or 1ms but with 6 samples queued every time you read the usb buffer? You need to make this explicitly clear because there is a significant difference between the two and your question and comments make it very unclear. – whatsisname Dec 04 '15 at 18:25
  • I added info to the question. – cauchi Dec 07 '15 at 10:33
0

After looking around quite a log, reading manuals, and getting some output from the linux kernel USB mailing list, I'm going to say that is not a good idea to use a USB for 500Hz continous data transfer.

At first I thought that it should be possible, and the math proved it. Meaning, if USB 2.0 offers 480Mbs, I should be able to poll my imu for a few floats at 500Hz. I think that I needed at most 128kps. Well, as proposed by someone at the linux kernel mailing list (someone who very kindly answered all my questions!) I profiled the data transfer and it came at 27 Kbs, which is way lower than the theoretical 480 Mpbs of USB 2.0.

Then, on several places I found reference to the issues of "bursts" in USB data. For reasons that I don't fully understand yet, that's how the USB driver works.

So, for frequencies above 150 (maybe even lower), USB is not your guy if you need to get data at regular intervals.

I tested different drivers, on different computers, and always got a similar result. Data in burst after a 6ms sampling interval.

cauchi
  • 1,192
  • 2
  • 13
  • 22