USB to digital I/O delay ?

Status
Not open for further replies.

Piero

Member
Hello everyone,

I just ordered a Teensy 3.0, and for now my main goal is to control the digital I/O ports on the board from a C++ program running on the mac (I care mostly about output for now). I'm a bit lost now, I guess it will be better once I actually get the board. I wanted to know what is the best/easiest way to do that (via teensyduino, or directly, as in the raw HID examples ?). From my C++ program I would like to be able to set the some pins on/off for a given duration with a single command.

My main question is about the delay (minimum, typical, maximum) to expect between the execution of the command in the C++ program and the actual change on the pin. Is a sub millisecond delay possible (I guess this depends if the device supports USB 2... most things I've read mention 1ms frame, so I would say USB 1) ?
 
1 ms is the typical latency you'll see, partly because Teensy 3.0 is a 12 Mbit/sec device with 1 ms USB frames, and partly because OS-X schedules user space time slices with 1 ms granularity.
 
Thanks for the answer ! Since then I received my teensy (very nice little thing, too bad I didn't order the version with the header pins, it delayed me for a couple of days), and I tested the serial latency programs I found here: http://neophob.com/2011/04/serial-latency-teensy-vs-arduino/.

When serial.send_now() is commented, I get these values:
port /dev/cu.usbmodem12341 opened
waiting for board to be ready:
.ok
latency @ 1 bytes: 5.00 ms average, 5.18 maximum
latency @ 2 bytes: 4.99 ms average, 5.21 maximum
latency @ 12 bytes: 5.00 ms average, 5.24 maximum
latency @ 30 bytes: 4.99 ms average, 5.19 maximum
latency @ 62 bytes: 5.00 ms average, 5.21 maximum
latency @ 71 bytes: 5.01 ms average, 5.95 maximum
latency @ 128 bytes: 5.59 ms average, 6.09 maximum
latency @ 500 bytes: 7.09 ms average, 8.02 maximum
latency @ 1000 bytes: 10.14 ms average, 11.10 maximum
latency @ 2000 bytes: 18.67 ms average, 19.13 maximum
latency @ 4000 bytes: 36.04 ms average, 36.97 maximum
latency @ 8000 bytes: 67.52 ms average, 70.13 maximum

But when it is uncommented, I get those:

port /dev/cu.usbmodem12341 opened
waiting for board to be ready:
.ok
latency @ 1 bytes: 0.14 ms average, 0.29 maximum
latency @ 2 bytes: 0.15 ms average, 0.28 maximum
latency @ 12 bytes: 0.19 ms average, 0.31 maximum
latency @ 30 bytes: 0.28 ms average, 0.37 maximum
latency @ 62 bytes: 0.42 ms average, 0.52 maximum
latency @ 71 bytes: 0.46 ms average, 0.52 maximum
latency @ 128 bytes: 0.66 ms average, 0.74 maximum
latency @ 500 bytes: 2.25 ms average, 2.39 maximum
latency @ 1000 bytes: 4.39 ms average, 4.58 maximum
latency @ 2000 bytes: 9.71 ms average, 9.94 maximum
latency @ 4000 bytes: 21.23 ms average, 21.41 maximum
latency @ 8000 bytes: 42.08 ms average, 43.22 maximum

For a few bytes, the average and max are below 1ms... considering your answer, how is it possible ?
 
(little bump / Happy new year :) )... This was observed on a Mac, with OS X Lion by the way.

Thanks.
 
Looks like Apple has made improvements in Lion. The last time I looked at these latency tests was Snow Leopard.

I do not know how Apple is getting the average latency under 0.5 ms. Normally the USB host controller chip doesn't retry communication with an IN endpoint from the first NAK token to the end of the frame.

Perhaps newer chips have the capability to do better (it's certainly possible from a USB protocol point of view) and Apple has carefully optimized their USB stack and drivers?
 
Thanks for the reply, I was afraid the values might have been artifacts, not corresponding to actual times. If by any chance you look at latencies again it would be nice to know what is happening exactly !

I'll try to repeat the test on different macs to see if it makes a difference. Maybe the Teensy 3 participates to these nice timings too ! (The tests on the website are for the Teensy 2)
 
I ran the benchmark on a Teensy 2 and a Teensy 3 on Win7x64 and Win8x64. I no longer have XP boxes around...

I see virtually no difference between Win7/Win8 -- just between the 2.0 and 3.0 Teensy.

u3YY7qJ.png


TEENSY 2.0 - Windows 7 x64

C:\temp\latency>latency_test COM5
port COM5 opened
waiting for board to be ready:
.ok
latency @ 1 bytes: 0.28 ms average, 1.00 maximum
latency @ 2 bytes: 0.26 ms average, 1.00 maximum
latency @ 12 bytes: 0.35 ms average, 1.00 maximum
latency @ 30 bytes: 0.50 ms average, 1.00 maximum
latency @ 62 bytes: 0.76 ms average, 1.00 maximum
latency @ 71 bytes: 0.86 ms average, 1.00 maximum
latency @ 128 bytes: 1.49 ms average, 14.00 maximum
latency @ 500 bytes: 4.11 ms average, 5.00 maximum
latency @ 1000 bytes: 8.06 ms average, 16.00 maximum
latency @ 2000 bytes: 15.54 ms average, 19.00 maximum
latency @ 4000 bytes: 30.67 ms average, 31.00 maximum
latency @ 8000 bytes: 60.97 ms average, 62.01 maximum


TEENSY 2.0 – Windows 8 x64

C:\temp\latency_test>latency_test.exe COM3
port COM3 opened
waiting for board to be ready:
.ok
latency @ 1 bytes: 0.25 ms average, 1.03 maximum
latency @ 2 bytes: 0.25 ms average, 1.01 maximum
latency @ 12 bytes: 0.34 ms average, 1.12 maximum
latency @ 30 bytes: 0.50 ms average, 1.36 maximum
latency @ 62 bytes: 0.75 ms average, 1.40 maximum
latency @ 71 bytes: 0.86 ms average, 1.25 maximum
latency @ 128 bytes: 1.25 ms average, 2.04 maximum
latency @ 500 bytes: 4.12 ms average, 5.02 maximum
latency @ 1000 bytes: 7.88 ms average, 8.69 maximum
latency @ 2000 bytes: 15.43 ms average, 16.25 maximum
latency @ 4000 bytes: 30.61 ms average, 31.38 maximum
latency @ 8000 bytes: 60.87 ms average, 61.70 maximum


TEENSY 3.0 - Windows 7 x64

C:\temp\latency>latency_test COM5
port COM5 opened
waiting for board to be ready:
.ok
latency @ 1 bytes: 0.32 ms average, 1.00 maximum
latency @ 2 bytes: 0.25 ms average, 1.00 maximum
latency @ 12 bytes: 0.25 ms average, 1.00 maximum
latency @ 30 bytes: 0.37 ms average, 1.00 maximum
latency @ 62 bytes: 0.50 ms average, 1.00 maximum
latency @ 71 bytes: 0.52 ms average, 1.00 maximum
latency @ 128 bytes: 0.76 ms average, 2.00 maximum
latency @ 500 bytes: 2.40 ms average, 3.00 maximum
latency @ 1000 bytes: 4.97 ms average, 6.00 maximum
latency @ 2000 bytes: 10.34 ms average, 11.00 maximum
latency @ 4000 bytes: 20.93 ms average, 21.00 maximum
latency @ 8000 bytes: 42.08 ms average, 43.00 maximum


TEENSY 3.0 – Windows 8 x64

C:\temp\latency_test>latency_test COM3
port COM3 opened
waiting for board to be ready:
.ok
latency @ 1 bytes: 0.25 ms average, 1.01 maximum
latency @ 2 bytes: 0.25 ms average, 1.12 maximum
latency @ 12 bytes: 0.25 ms average, 1.01 maximum
latency @ 30 bytes: 0.35 ms average, 1.12 maximum
latency @ 62 bytes: 0.50 ms average, 1.19 maximum
latency @ 71 bytes: 0.50 ms average, 1.25 maximum
latency @ 128 bytes: 0.76 ms average, 1.28 maximum
latency @ 500 bytes: 2.38 ms average, 3.41 maximum
latency @ 1000 bytes: 5.00 ms average, 5.79 maximum
latency @ 2000 bytes: 10.30 ms average, 11.07 maximum
latency @ 4000 bytes: 20.92 ms average, 21.92 maximum
latency @ 8000 bytes: 42.09 ms average, 43.09 maximum
 
Last edited:
Nice work plotting the results.

I'm a bit surprised Teensy 3.0 is so much better at small data sizes. Of course, for over 64 bytes (1 USB packet), Teensy 3.0's faster CPU, DMA-based USB and much better buffering (many packets instead of just 2) give it a huge advantage over AVR.

If you repeated these tests adding Linux and included some of the newer official Arduino boards, I'm sure a number of the major blog sites like Hack-a-Day would find it very interesting!
 
Hey,


I have been trying to get this code to work, but I have had no success. I am new to microcontrollers, so I am not sure if I have missed something fundamental. I have downloaded the code that is longer active. I have coped the pde code to Arduino, and I have installed the code to my teensy 3.0. I have then tried running the latency_test.exe in cmd. All I get is usage:latency_test3 <comport>


Any help is much appreciated.
 
No, I dont know how or where to type the comport for the teensy. I saw there was a section to input the os type in the .makefile when compiling the exe., but I was not sure how to get the c code to compile. I tired using visual studio, but i was not able to compile, only attach.
 
You simply type the COM port name after "latency_test", before you press Enter to complete the command. Put a space between the command the COM port. See the 4 examples in message #10 above.
 
Thank you for all the help. I finally got the data.

I have windows 8.1 64 bit and a 2.5 dual core i5 and a ssd

Here is a screen shot of my data,

Capture.PNG


Also, can you explain to me how to compile the C code and makefile to make an the latencytest.exe for linux?


thank you
 
Also, can you explain to me how to compile the C code and makefile to make an the latencytest.exe for linux?

On Ubuntu 12.04, run these commands to install the mingw cross compiler.

Code:
sudo apt-get install mingw32 mingw32-binutils mingw32-runtime
sudo apt-get install mono-devel wine

These might work on other distros? I can't confirm for any other than Ubuntu 10.04 and 12.04.

Edit the makefile to select the option for a Windows build. Then run "make". You should end up with a .exe file, which of course needs to be copied to a Windows system to be used.

Linux is not generally a beginner oriented system. Each distro can be a bit different too. Odds are, you'll run into minor issues where things aren't quite as expected and you'll need to figure out how to resolve some issue. I can't get heavily involved in that sort of stuff. Of course, if you post detailed info about the steps you've taken and screenshots, your changes improve that someone will be able to recognize a problem.
 
I ran the latency tests on teensy 3.0 and 3.1 with Ubuntu 12.04 and Mac OSX 10.9
Code:
ubuntu  teensy 3.0

       latency_test /dev/ttyACM0
       port /dev/ttyACM0 opened
       waiting for board to be ready:
       .ok
       latency @ 1 bytes: 0.12 ms average, 0.25 maximum
       latency @ 2 bytes: 0.10 ms average, 0.18 maximum
       latency @ 12 bytes: 0.13 ms average, 0.25 maximum
       latency @ 30 bytes: 0.17 ms average, 0.65 maximum
       latency @ 62 bytes: 0.26 ms average, 0.43 maximum
       latency @ 71 bytes: 0.29 ms average, 0.37 maximum
       latency @ 128 bytes: 0.39 ms average, 0.50 maximum
       latency @ 500 bytes: 1.12 ms average, 1.23 maximum
       latency @ 1000 bytes: 2.13 ms average, 2.30 maximum
       latency @ 2000 bytes: 4.09 ms average, 4.19 maximum
       latency @ 4000 bytes: 7.81 ms average, 7.99 maximum 
       latency @ 8000 bytes: 15.30 ms average, 15.46 maximum

       teensy 3.1
       latency @ 1 bytes: 0.10 ms average, 0.19 maximum
       latency @ 2 bytes: 0.10 ms average, 0.23 maximum
       latency @ 12 bytes: 0.10 ms average, 0.17 maximum
       latency @ 30 bytes: 0.14 ms average, 0.21 maximum
       latency @ 62 bytes: 0.19 ms average, 0.30 maximum
       latency @ 71 bytes: 0.21 ms average, 0.34 maximum
       latency @ 128 bytes: 0.26 ms average, 0.38 maximum
       latency @ 500 bytes: 0.64 ms average, 0.84 maximum
       latency @ 1000 bytes: 1.07 ms average, 1.23 maximum
       latency @ 2000 bytes: 2.03 ms average, 2.10 maximum
       latency @ 4000 bytes: 3.88 ms average, 9.62 maximum
       latency @ 8000 bytes: 7.45 ms average, 7.54 maximum

 ---- mac os 10.9   latency_test /dev/tty.usbmodem22631
            teensy 3.0
        latency @ 1 bytes: 0.14 ms average, 0.26 maximum
        latency @ 2 bytes: 0.14 ms average, 0.22 maximum
        latency @ 12 bytes: 0.17 ms average, 0.27 maximum
        latency @ 30 bytes: 0.23 ms average, 0.40 maximum
        latency @ 62 bytes: 0.31 ms average, 0.41 maximum
        latency @ 71 bytes: 0.35 ms average, 0.44 maximum
        latency @ 128 bytes: 0.43 ms average, 0.52 maximum
        latency @ 500 bytes: 1.24 ms average, 1.41 maximum
        latency @ 1000 bytes: 2.23 ms average, 2.33 maximum
        latency @ 2000 bytes: 4.12 ms average, 4.21 maximum
        latency @ 4000 bytes: 7.89 ms average,  7.97 maximum
        latency @ 8000 bytes: 15.48 ms average, 15.56 maximum  

  teensy 3.1
       latency @ 1 bytes: 0.14 ms average, 0.27 maximum
       latency @ 2 bytes: 0.14 ms average, 0.23 maximum
       latency @ 12 bytes: 0.14 ms average, 0.22 maximum
       latency @ 30 bytes: 0.19 ms average, 0.28 maximum
       latency @ 62 bytes: 0.25 ms average, 0.40 maximum
       latency @ 71 bytes: 0.27 ms average, 0.35 maximum
       latency @ 128 bytes: 0.29 ms average, 0.36 maximum
       latency @ 500 bytes: 0.66 ms average, 0.83 maximum
       latency @ 1000 bytes: 1.11 ms average, 1.20 maximum
       latency @ 2000 bytes: 2.01 ms average, 2.13 maximum
       latency @ 4000 bytes: 3.82 ms average, 3.91 maximum
       latency @ 8000 bytes: 7.49 ms average, 7.61 maximum
 
Hi,

I have problems with my teensy 2.0 Serial device.
On one USB Port of my MacBook Pro it works ok and at the other one not.
If I boot the machine with Windows both ports works.
The problem on OSX is that the left USB port seams to have a delay. So the serial communication breaks often.
Dose anyone has an idea what I can do?

thanks
Wolfram
 
Piero, most of this thread has been about latencies, I guess mostly as an idea of what kind of performance character you can expect from Teensy3.

It seems to me you also were asking about general methods for going about making a Teensy into something like a little USB slave that can control voltages from your program running on a general-purpose computer.

https://github.com/WardCunningham/Txtzyme

I think this uses Teensy2 and isn't (yet?) compatible with Teensy3 (which might not be a bad thing, since the 5V output and higher current capacity of the Teensy2 might be useful), but you might want to take a look at Ward Cunningham's "Txtzyme" project. (Or maybe Txtzyme is a DorkbotPDX project that Ward's merely curating, but at any rate it's on Ward's Github).

Txtzyme might be useful as-is (provided you don't mind putting your Teensy3 aside and buying a Teensy2), or might be useful for inspiration for your own code. At any rate, I found it to be a very interesting idea along the lines of what you were asking. I believe it should allow you to use the Teensy as a USB-connected slave with digital outputs/inputs, but will also allow you to send little micro-programs that will allow very precise timing of output pulses and waveforms. Using the Txtzyme language, you might even be able to entirely sidestep whatever latency concerns you are worried about by describing exactly the timing of output pulses you want.

I have never met Ward or visited DorkbotPDX and I haven't used Txtzyme, but I read about it and it seemed relevant to what you're talking about (and I find Forth-like languages interesting... I've used the concept to make command-line parsers for my AVR projects that give reasonable power, flexibility, and extensibility in minimal code space, though I've never actually made a threaded interpreter for Forth, only little postfix command-line text interpreters).

Cheers,
Dave
 
Hi,

the results for Windows with mean and maximum look very very good :)
After some search i could find, the measured latency is the time from sending some bytes until getting back some response bytes over virtual serial interface.
I would prefer to build a device with Teensy 3.1 sending a small message (1 or 2 bytes) to PC when 2 digital pins change their state.

Now, the big difference: i would prefer to use a Raw HID device, because it would not need any driver installation.
Is it possible to avoid polling RAW HID via hid_read(), just get informed with some callback? Probably an extra thread, designated for synchronous/blocking reads, may do the job.
Important is: what latency could be achieved using RawHID with Windows 7/8?

I'm currently waiting that some devices with header pins get available in a german shop.

kind regards,
Coder


TEENSY 3.0 – Windows 8 x64

C:\temp\latency_test>latency_test COM3
port COM3 opened
waiting for board to be ready:
.ok
latency @ 1 bytes: 0.25 ms average, 1.01 maximum
latency @ 2 bytes: 0.25 ms average, 1.12 maximum
latency @ 12 bytes: 0.25 ms average, 1.01 maximum
latency @ 30 bytes: 0.35 ms average, 1.12 maximum
latency @ 62 bytes: 0.50 ms average, 1.19 maximum
latency @ 71 bytes: 0.50 ms average, 1.25 maximum
latency @ 128 bytes: 0.76 ms average, 1.28 maximum
latency @ 500 bytes: 2.38 ms average, 3.41 maximum
latency @ 1000 bytes: 5.00 ms average, 5.79 maximum
latency @ 2000 bytes: 10.30 ms average, 11.07 maximum
latency @ 4000 bytes: 20.92 ms average, 21.92 maximum
latency @ 8000 bytes: 42.09 ms average, 43.09 maximum
 
With HID, the host polls automatically at a regular interval. In RawHID, the default is every 1 ms frame. So the best you'll achieve is 1 ms average latency.

Of course, there are many ways you could end up doing much worse, with poor coding. Teensy is plenty fast enough to meet 1 ms latency, as long as you use it in a smart way.

Not much benchmarking has been published, but I have heard from several people (who didn't publish their code) that it performs well. Perhaps if you put some work into benchmarking, you'd publish the results and code?
 
Hi Paul,
thank you for that quick response.

I would be very happy with a delay from device to PC (better software) below 2 ms.
On the other side, i have no idea how to measure single way latency. For sure a two-way latency of 1 ms is perfect and i could measure this one.

Yes, i could publish the code and benchmark results .. after getting a device, developing the desired application - besides the usual work. That will take a "small" while.

Coder

With HID, the host polls automatically at a regular interval. In RawHID, the default is every 1 ms frame. So the best you'll achieve is 1 ms average latency.

Of course, there are many ways you could end up doing much worse, with poor coding. Teensy is plenty fast enough to meet 1 ms latency, as long as you use it in a smart way.

Not much benchmarking has been published, but I have heard from several people (who didn't publish their code) that it performs well. Perhaps if you put some work into benchmarking, you'd publish the results and code?
 
Hi Paul and others,

meanwhile i've written the benchmark. 1000 iterations of transmitting a 64 byte buffer to the Teensy and all 64 bytes back.
I've tested on a Windows 8.1 Notebook and have played around with the Energy settings. Energy settings don't make a difference.
Benchmark was performed with Teensy 2.0 and 3.1. The Teensy model doesn't make a difference, too!

TEENSY 2.0 at 16 MHz:
transmitted 1000 request packets and received same amount of responses, each 64 bytes
min latency : 1.82
max latency : 2.37
mean latency : 2.00

TEENSY 3.1 at 72 MHz:
transmitted 1000 request packets and received same amount of responses, each 64 bytes
min latency: 1.86
max latency: 2.16
mean latency: 2.00

i wondered about the exact mean of 2.00 ms. But several measurements did only differ a bit in min and max, but mean latency was always the same!

publication of firmware/test programs take some more time, because i integrated latency measurement into my application.
 
Last edited:
Status
Not open for further replies.
Back
Top