Sunday, July 8, 2012

Project: IRXlate - IR Code Translator/Repeater

IRXlate is an infrared remote control  extender and translator.  The vision is to create a device that will both allow me to locate my A/V equipment any where I want, and also make my multitude of remote controls easy and intuitive to use.

It has always bothered me that when I pick up a remote control to turn the volume of the TV down, it is never the right one, or if it is it takes a while to find the correct volume control button.

Volume is just an example of course, but one that should resonate.  Realistically, there are only a few components where a volume control makes sense, and it is reasonable to send the appropriate volume up or down command to each of those components.  That's what IRXlate is designed to do.

The same thing works for the left, right, up down buttons, play and stop, etc.  Some of these will require storing and making decisions based on the current device "state" - all of which I will eventually do in firmware.

The design is based on a PIC microcontroller (currently a 16F689).  The input side is from a GP1U58Y IR detector that I had in my junk box.  This is a 5V three terminal detector centered on a 38khz detection frequency.  While the PCB footprint is laid out for that particular device, any of the similar detectors with the same pin layout will do the same job.

While working on the breadboard developing the circuit and writing the basic firmware, I found that the device is fairly unstable and sensitive to noise on the ground line as well as random light.  That all went away when it was properly grounded.

The hardware is fairly simple.  It consists of a discrete input board and output board.  

The Input Board:

The input side, which is made up of the GP1U58Y with a bypass capacitor on the 5V power line, and a 5V to 3.3V translation circuit to adapt the 5V output of the IR detector to the 3.3V inputs on the microcontroller.  The IR output has a 1k pullup to the 3.3V line, a 10k series resistor to the RA2 line on the microcontroller.  The RA2 input is diode clamped to the 3.3V line to prevent it from exceeding the 3.3v input.  The RC0 output line on the uC connects to an Error LED via a 470 ohm current limiting resistor.

The input board also has a microprocessor power supply circuit based on a SA57000-33 3.3V LDO regulator in a SOT23/5 package.  

The 3.3v supply feeds the 16F690 uC, and a SST25VF010A 1Mbit SPI Flash memory that is used to hold the IR code translation memory.  These complete the input board, except for the connectors for in-circuit serial programming (ICSP), a SPI header for debugging, a 5V power supply input, the UART connectors, and five IR output lines.

There is a footprint for a current limiting resistor and IR LED that can be populated for testing and debugging, but it is not generally intended to be populated.

The connections that go to the output board are on two .100 spaced headers - one with 8 connections - UART RX, UART TX, Ground, and five IR outputs (RC1 - RC5).

The second connector that goes to the output board is a 5V power input and ground connection on a 2x1 .100 spaced header.

The input board was designed to fit in a small box that I bought on sale from a surplus website -- I can't remember which one.  For my usage, I just soldered a ten conductor cable salvaged from a modem cable directly to the board.

The Output Board:

The output board was designed to be the interface point to the actual IR emitters, the power supply, and the serial communications to the microprocessor.  All of the wires are connected via screw terminal blocks.

It is a very simple design.  It includes a 5V power supply based on an linear regulator (78L05).  It has a polarity protection diode, footprints for input and output bypass capacitors, and an additional footprint for a electrolytic capacitor to handle extra power requirements of five simultaneous IR outputs if needed.

The UART rx/tx lines are routed to a 5x1 .100 header that has a pinout for the Pickit2 UART tool.  Unfortunately I failed to route the power to the appropriate pins, partially because the output board has only 5V power, and the rx/tx signals from the input board are at 3.3v level.  I ended up using my Bus Pirate for most of the debugging, and built a Wixel Adapter to allow wireless connectivity.  At some point in the future I'm planning on wiring all my devices up to a RS-485 network - at which point I'll build another adapter with the same pinout and footprint.

The rest of the board is made up of five copies of a simple transistor booster on the IR outputs.  Each has an NPN transistor pulling the sleeve of a 3.5mm jack to ground.  The base of the NPN transistor is driven by the uC output.  The tip of the 3.5mm jack connects through a limiting resistor to the 5V line.


As mentioned before, the input side was mounted in a IR case with a red IR transparent window in the front.

The output board will be mounted directly into the wall in a standard junction box.  The photo above shows the completed output board mounted to a blank outlet plate that has been drilled with holes for the 3.5mm jacks.  The board is mounted to a 1/2" piece of wood that is then mounted to the faceplate with screws to provide stability.  

The Printed Circuit Boards:

IRXlate "panel" - Top

IRXlate Panel - Bottom

For this project, I decided to order my first professionally produced board.  Seeedstudio offers a very reasonably priced service to produce boards.  This particular design required two separate boards - one for the input and one for the output.  The input board size was determined by the size of the case.  The output board size was determined mostly by the minimum space required by the five 3.5mm IR output jacks.  The only limiting factor is that it mounts to a standard outlet faceplate and fits in a standard outlet box.

After designing the minimum dimensions for both input and output, I found that they would not fit into the 5cm x 10cm size because of the space needed for the IR output jacks, so I arranged them into the 10cm x 10cm size ($25 for 10 copies).  I had quite a bit of unused space, which I filled with SMD adapters to break SMD footprints into standard headers for fitting onto a breadboard.  The final "panel" ended up with:

  • Input PCB
  • Output PCB
  • 3 x SOT23/5 to SIP5
  • 1 x SOIC20 / SSOP20 to DIP20
  • 2 x SOIC8 to DIP8
  • 1 x SOIC28/SSOP28 to SIP28
  • 1 x D2PAK to SIP4
Multiple that by ten copies and I should not be wanting for surface mount adapter boards for a while, at least for these footprints.

The boards ended up very nice - double sided with soldermask and silkscreen.  They are great to work with - especially for the small surface mount parts.  Okay - so none of these are really small surface mount parts - in fact they are huge as surface mount parts go, but they feel pretty small when you are used to dealing with DIP packages.

I did make a few mistakes on the board:
  • All of the TO92 parts - transistors and voltage regulators -- were reversed on the silkscreen.  This was easy enough to work around - simply by soldering the parts on "backwards" from what was shown on the silkscreen.  
  • There also was one pad on the footprint for the 3.5mm jack that was covered by soldermask.  It was an unused pin, so it really did not cause any harm.
  • As mentioned before, there was no power routed to the UART header.  Both of these have been fixed in the V1.1 board design that I'll reference here.

Firmware Development:

The firmware was originally hand written in 8 bit (16F) PIC assembly code for a 16F690 processor on a development board connected to a breadboard circuit.  In that form, I started by analyzing the IR waveforms using my digital storage oscilloscope.   That was not particularly easy to do, but let me get a basic capture and decode process written.  The firmware captures the mark and space timings of up to 100 cycles in RAM, then analyzes the results to encode the NEC or Panasonic formats.  If the format is not recognized, there is a debug mode that can dump the raw space and mark timings for development of additional protocol decoders.  The encoders just do the opposite - split the encoded value into mark and space timings, then send them to the selected IR outputs.

The initial development was done just using the on-chip EEPROM for storage.  It didn't take too long to figure out that I would need a lot more storage than that, so I added the Flash memory.

Partially through the development, I purchased an Open Workbench Logic Sniffer and things got much easier.  Using this inexpensive 32 channel logic analyzer, I found it much easier to capture the input and output IR signals and write them in formats that I could easily use in the MPLAB debugger.

The firmware is specific to my requirements.  The formats that it decodes and sends are the formats that my remote controls use (NEC and Panasonic).

I still intend to add some state specific logic, but I got to a point that I wanted to start using the device to make my life easier.  I have two problems - first I didn't want to have to continually connect and disconnect  the serial cables and use the ICSP connectors to load new firmware.  Second, I was running out of available program memory.

I ignored the second one and went searching for a serial bootloader to solve the first problem.  I still had a bit of memory left to work with.  Too bad that after I found and adapted the tiny bootloader to the 16F689/16F690, I found out that they can only read and not write the program flash memory while running.

The answer to both problems was to switch to a pin compatible PIC with more memory that can self-write program memory.  The 16F1829 fit that bill, so I bought one and soldered it onto a second input board to develop on.  When I get the firmware adapted to the new processor, I'll just swap out the processor chip.  That will be a topic for future blog post.

No comments: