A few years ago, my wife and I were planning to take a two week vacation. At that time, we lived in a less-than-ideal neighborhood (we were once awoken at 2am by the sound of a SWAT team a few houses down the block, though that was certainly more extreme than a typical day in the 'hood). Anyway, we didn’t want anyone to know that our house was empty while we were gone. So, like most folks, we considered purchasing a few inexpensive lamp timers to give the appearance that we were home. The only problem… we didn’t have any lamps! All of our lighting was overhead.
However, we had recently remodeled a few rooms in our 95-year-old house, and decided to “go modern” by installing dimmer switches with infrared remote control in a few key areas (see Figure 1). These dimmers are drop-in replacements for your existing light switches, and are sold at most home-improvement and lighting stores. They are ideal for reading before bed, or controlling the lights on movie night.
Figure 1. Lutron Maestro dimmer switch with infrared remote control.
Being a typical tinkerer, it didn’t take long for the wheels to start turning. I figured, why not put together a gadget to automate the lights via infrared control? And it would be better than lamp timers, because I could synchronize the lights to make it appear as if people were moving from room to room! The living room lights would go out after the evening news, then the bedroom light would come on for a while, and eventually all lights out until morning.
The simplest way would probably be to wire up some kind of controller to the manufacturer’s remote control to simulate button-presses, but where’s the fun in that? Besides, tampering with the remote would have earned me some serious time in the doghouse (wives tend to frown on that sort of thing)! So instead, I decided it would be fun to generate the infrared signals on my own.
I had recently purchased a Xilinx Spartan3E Starter Kit, so this seemed like the ideal place to start. I could use the FPGA as the ‘brain’ of the gadget, and simply wire up a few infrared LEDs to the I/O pins on the development board. I could run some cables to each room, with an LED on the end of each cable to point toward the dimmer switch. Additionally, the development board had buttons and knobs for input, as well as a Character LCD for convenient information display. (Photos of the completed system are attached at the bottom of the article).
Figure 2. Block diagram of the light controller.
I had already made use of the Xilinx MicroBlaze soft-core processor on a few projects at work, but so far had only used the built-in IP cores when interfacing to the outside world. I was eager to try writing my own custom logic core to drive the infrared LEDs. Of course, before I could write an IR Control module, I would have to reverse-engineer the IR signal.
A quick internet search revealed that most consumer IR remotes tend to use a modulation scheme, usually with a carrier frequency between 10kHz and 100kHz, which is modulated by a low-bitrate signal (the data). The low-speed signal can be coded in a number of different forms, including biphase coding, space width modulation, pulse code modulation, and (in this case) simple digital amplitude modulated. Figure 3, below, illustrates the signal that I was able to measure with an inexpensive USB logic analyzer hooked up to the leads of the IR-LED on the remote control (while my wife wasn’t looking, of course).
Figure 3. Infrared signal.
In the figure, the top row shows the carrier frequency. In this case, it is 40kHz with a 40% duty cycle. So for each pulse, the IR-LED is ON for 10µs and OFF for 15µs.
The second row shows an entire 32-bit code transmitted by the remote. The code shown in the diagram turns the dimmer switch ON to full brightness. I have marked each bit in the trace, and also included the hexadecimal translation (FF8884B8h). For each ‘1’, the IR-LED blinks at 40kHz for 2.25ms (90 pulses). For each ‘0’, the IR-LED remains off for 2.25ms.
The third row shows that the 32-bit code is repeated multiple times when you press a button on the remote. Presumably, this helps increase the chances of the signal getting through to the receiver. (NOTE: The space between each 32-bit code is a 4-bit-wide sequence of zeros. So technically, you could think of the signal as being 36 bits long instead of 32bits-plus-spacing. This is how I ended up implementing it, as you will see below.)
The next step was to implement the logic core that would generate the IR signals. I wanted to make the logic reusable for future projects (with different remotes), so I decided to implement a set of registers that I could use to configure the core as illustrated in Figure 4.
Figure 4 - IR Logic Core Register Map
- IR_CODE_HI / IR_CODE_LO: Actual bits to transmit (up to 64, based on NUM_CODE_BITS).
- DUTY_CYCLE_HI / DUTY_CYCLE_LO: Number of 50MHz clock cycles that make up the high and low portion of the carrier duty cycle.
- PULSES_PER_BIT: Number of carrier pulses (at 25µs each) that make up each bit of IR code.
- NUM_CODE_BITS: Number of bits per IR code.
The Spartan-3E Starter Kit has a 50MHz clock source. Using DUTY_CYCLE_HI/LO, I can divide that as low as 381Hz. In this case, I needed 40kHz at 40% duty cycle. So here are the settings:
- DUTY_CYCLE_HI = 500 (10µs) 10µs*50MHz = 500
- DUTY_CYCLE_LO = 750 (15µs) 15µs*50MHz = 750
- PULSES_PER_BIT = 90 (2.25ms) (10µs+15µs)*90 = 2.25ms per bit
- NUM_CODE_BITS = 36 (32bits of IR code, plus 4 bits of spacing between repetitions of the code)
- IR_CODE_HI/LO = FF8884B8_00000000h (Left-justified code for “ON to full brightness”)
After placing the logic core at base address 80000000h, it is easy to send an IR signal from the MicroBlaze code:
After successfully verifying that I could turn the lights ON and OFF with the above code, all that remained was to write a user interface. The interface had to allow the user (me) to:
- Set the current time.
- Set on/off times for the lights in each room (plus or minus some randomization time to make it realistic).
- Manually turn lights ON/OFF, for testing purposes or setting initial states.
Below are some photos of the completed system:
Figure 5. Controller and two IR LED circuitsFigure 6. LED circuit mounted to a photo standFigure 7. Closeup of LED circuitFigure 8. LCD and button/knob interface
After a few days of testing, we noticed that the clock drifted slightly… a little under one minute per day. That was certainly accurate enough to make it through our vacation without issues. So, being satisfied that everything was working great, we were able to take our holiday with peace of mind.
Next step: support for Ethernet and NTP (grin).About the author
Robin Findley, founder of Findley Consulting, is a consultant/contractor with 15+ years' experience in software and electronics systems. Robin’s career was inspired at age 8 by his father, with the help of the computer enthusiast magazine “The Rainbow”. As a high school student, Robin was offered his first contract job developing material utilization software for Knapheide Mfg Co. After studying Electrical Engineering and Computer Science at the Missouri University of Science and Technology, Robin worked as a manufacturing test engineer at Harris Corporation. In 2005, Robin started Findley Consulting, where he provides embedded systems design and consulting services. Robin can be contacted at firstname.lastname@example.org
If you found this article to be of interest, visit Programmable Logic Designline
where – in addition to my Max's Cool Beans
blogs – you will find the latest and greatest design, technology, product, and news articles with regard to programmable logic devices of every flavor and size (FPGAs, CPLDs, CSSPs, PSoCs...).
Also, you can obtain a highlights update delivered directly to your inbox by signing up for my weekly newsletter – just Click Here
to request this newsletter using the Manage Newsletters tab (if you aren't already a member you'll be asked to register, but it's free and painless so don't let that stop you [grin]).