USB IR Toy: Sampling mode

From DP

Revision as of 19:34, 24 August 2010 by Ian (Talk | contribs)
Jump to: navigation , search

USB IR Toy firmware v1.04+ has an infrared sampling mode that was added for a USB IR Toy 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.

Contents

Enter IR sample mode

The IR Toy appears as a serial port. Open it at any speed, 8/N/1.

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.

Timing information format

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:

{00}{2B}{00}{28}{00}{2A}{00}{27}{00}{2B}{00}{28}{00}{2A}
{00}{27}{00}{2B}{00}{27}{00}{2A}{00}{28}{00}{54}{00}{51}
{00}{2B}{00}{28}{00}{54}{00}{51}{00}{54}{00}{51}{00}{2A}{FF}{FF}

  • 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.

Error codes

If the IR Toy can't keep up with the IR data, or the USB connection gets congested, it returns 0xff six times. After the error code it resets and waits for the next infrared pulse before sampling again.

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.

See the USB IR Toy WinLirc how to.

Commands

By defualt the IR sample mode just sits and spits out infrared signal timing data according to the protocol described above. There are also commands that can be used to transmit data, or configure various aspects of the IR Toy.

0x00 Reset (returns to remote decoder mode)
0x01 Setup sample timer (not implemented)
0x02 Setup infrared modulation frequency (v1.06+)
0x03 Transmit (v1.06+)
0x04 FREQ report (future hardware only)

Commands available from raw sampling mode.

Reset (0x00)

Returns to IRman compatible decoder mode.

Transmit (0x03)

0x03 pulse1-high8 pulse1-low8 blank1-high8 blank1-low8 ... blankn-high8 (0xff) blankn-low8 (0xff)
  • Begins with 0x03, then send the same format as the timing data described above.
  • Transmit ends on no data, or 0xffff for the IR off (blank) pulse (same as receive protocol).
  • LED is on during transmit

FREQ report (0x04)

This command is for future hardware only.

t1-high8 t1-low8 t1-high8 t2-low8 t3-high8 t3-low8 count-high8 count-low8

The new 0x04 command is this:

  1. t1 H/L - start PIC timer count second rising edge of signal
  2. t2 H/L - PIC timer count third rising edge
  3. t3 H/L - PIC timer count fourth rising edge
  4. count H/L - total infrared modulated signal light pulses since last 0xff 0xff (will roll over at 0xffff)
{00}{F4}{02}{43}{03}{91}{01}{B3}

This is an example of a reply to the 0x04 command.

  1. 0x00f4 - start timer count
  2. 0x0243 - timer count 1
  3. 0x0391 - timer count 2
  4. 0x01b3 - total infrared modulated light pulses
  • PIC timer Period 1 count = 0x0243-0x00f4=0x14F (334)
  • PIC timer Period 2 count = 0x14E (333)
  • Total infrared pulse count = 0x01b3 = 435

The PIC has a 12MHz internal clock signal, so the actual time is:

(1/12000000)* PIC timer count = (1/12000000)*334 = 0.0000278333 = +0.20% of the 0.0000277778 actual 36KHz period.