Computing stuff tied to the physical world

Decoding IR pulses

In Hardware, Software on Oct 13, 2010 at 00:01

After the last few posts, it must come as no surprise that I’ve been working on a new Infrared Plug – so now it’s time to start exploring the software side of things. Note that IR reception doesn’t really need a plug at all, I simply inserted a TSOP32238 IR decoder chip into port 2 while debugging the code:

Dsc 2129

Note: I’ll be using the TSOP34838 for the planned Infrared Plug. It only differs in pinout (!) – and both can be used at 3.3V, which is essential.

In preparation of that new plug (atoms need time!), I’ve added a new “InfraredPlug” class to the Ports library, with the following interface:

Screen Shot 2010 10 12 at 17.30.37

This allows receiving IR codes on the AIO pin of any port, as well as sending out IR bit patterns on the DIO pin.

There’s a new ir_recv.pde sketch to demonstrate reception of arbitrary IR signals:

Screen Shot 2010 10 12 at 17.33.59

Here is some sample output, using two different Apple remotes which send using the NEC protocol, as described on this excellent site by San Bergmans:

Screen Shot 2010 10 12 at 16.49.22

You’re looking at a decoded bit stream – some minor processing will be needed to extract the actual data bits from each packet. This was done to make the decoder as flexible as possible – allowing it to handle all sorts of remotes.

The basic idea is that you set up the InfraredPlug instance with “slot” and “gap” parameters. The slot value (1..255) specifies the granularity of the time slots used by the decoder (in units of 4 µs). The default slot value is 140, this corresponds to time slots which are 560 µs wide. De gap value tells the driver when to consider a data packet as being complete (in units of 256 µs). The default gap value is 80, i.e. treat a series of pulses as one packet once 20 ms have elapsed after the last pulse.

The values can be changed with the “configure()” method. In fact, ir_demo will change the slot value when it receives an integer followed by lowercase “s” on the serial port (not echoed). The default setting on startup is “140s”. For RC5 codes, use “222s”, for RC6 “111s”, and for Nokia remotes “125s”, to name a few.

Each time a packet has been received, ir_demo will send the decoded data to the serial port. The data consists of a series of hex digits, each representing one 4-bit nibble of data, as returned by the InfraredPlug class:

  • 0..9 = 1..10 slots
  • A = 10 = 11 or 12 slots
  • B = 11 = 13 or 14 slots
  • C = 12 = 15 or 16 slots
  • D = 13 = 17 or 18 slots
  • E = 14 = 19 or 20 slots
  • F = 15 = 21 or more slots

The nibbles at even positions correspond to pulse ON widths, the nibbles at odd positions are pulse OFF widths – both as a multiple of the configured slot time, with the above adjustment of longer pulses applied.

The “send()” method uses a different format. You give it a bit pattern and the number of bits to send. Each bit represents an ON or OFF signal value. The duration of each bit is the same slot value as used in the receiver.

That’s it. A simple design which should be able to support lots of different appliances and remotes.