USB IR Toy: Sampling mode

See the latest version in the documentation wiki.

The USB IR Toy test firmware v1.04 has a new infrared sampling mode that will be used by the upcoming WinLIRC plugin. This mode times the duration of infrared pulses and sends the measurements to the computer. It’s currently receive-only, but we’ll add a compatible transmit feature in a future update.

Work on the plugin will begin soon, but if you finish it first we’ll send you an IR Toy v1.1 prototype.

Protocol documentation follows.


The protocol is very simple, it might need to be updated in the future (see potential issues).

pulse1-high8 | pulse1-low8 | blank1-high8 | blank1-low8 | … | blankn-high8 | blankn-low8 |

The first IR pulse starts a timer that measures length of the pulse. The length is returned as a 16bit count, high byte first. Multiply the raw 16bit timer value by 21.3333us to determine the actual length in microseconds.

The IR Toy continues to spit out measurements of each pulse and the blank space between. Sampling stops when there is no IR change for a full (0xffff) period of 1.7seconds. This will hopefully end during a blank period, but could be a pulse period if an IR jammer were in use. After a full period of no change the IR Toy ‘sleeps’ and won’t send any more data until the beginning of the next IR pulse.

Calculate the duration in microseconds (us)

To get the actual width of each pulse or space:

  • Combine the high and low byte
  • Multiply by 21.3333us

Here’s an example:


  • 002b (first pulse duration) = 43 = 43 * 21.3333us = 917.3319us
  • 0028 (first blank duration) = 40 = 40 * 21.3333us = 853.332us
  • 002a (second pulse duration) = 42 = 42 * 21.3333us = 895.9986us
  • … 0xff 0xff = final blank space of 1.7seconds, end of data sequence

The measurements are all pretty close to the 889us bit period of an RC5 remote. We could probably improve accuracy by increasing the resolution of the timer measuring the pulse period to 10us or less. We won’t worry about this unless there are problems with the current scheme, but it could easily be made adjustable.

Enter IR sample mode

First send 0x00 (raw byte value 0) to reset from any other mode. It might be good to send it 5 times to be sure it’s out of SUMP mode too.

Next, send ‘s’ or ‘S’ to enter IR sample mode. The IR Toy will respond with the protocol version (currently S01).

Now the bytes start flowing on any IR activity.

Potential issues

Which byte is which? Tracking the byte stream.

There’s no easy way to sync to the byte stream unless you track it from the start or wait for the first 0xff 0xff terminator. This probably isn’t a huge deal in practice, just reset (0x00, ‘S’) and track the data from the beginning.

Alternatively, we could update the protocol to use a bit of the high byte to flag pulse and blank periods. The issue of determining which bytes in the stream are the high and low 8bits remains.

How to detect end of data? The long IR Toy timeout.

The IR Toy will send the 0xff 0xff terminator flag after no pin change is detected for one timer period, but that is nearly two seconds. A program will be really unresponsive if it depends on the terminator sequence to start processing the data.

Another issues is that the IR Toy doesn’t care if the timeout happens during a pulse or blank period, and it has no ability to let us know a pulse is longer than 1.7seconds. A continuous IR pulse, like an IR jammer, would really mess up the bytestream. We made the IR Toy somewhat robust against this situation by syncing only to the start of an IR pulse.

Taking it further

The next IR Toy firmware release will add a compatible transmit mode, and make the timer interval adjustable.

Now it’s time to write a driver to support the IR Toy sampling mode in WinLIRC. The new WinLIRC developer has already prepared a basic framework for us. The IR Toy protocol is somewhat similar to the UIRT2, so some source could be recycled from a plugin for that device. Follow development in the forum.

Work on the plugin will begin soon, but if you finish it first we’ll send you an IR Toy v1.1 prototype.

This documentation has not yet been moved to the IR Toy wiki.

Leave a comment

Your email address will not be published. Required fields are marked *

Notify me of followup comments via e-mail. You can also subscribe without commenting.