Intro: RGB LED Ceiling Mood Light With Hacked IR Remote Control
This instructable documents the design and construction of a giant RGB LED ceiling light, controlled by a hacked GE remote control.
After building a couple smaller RGB lamps, I decided I wanted to see how far I could take the concept. The control circuitry is basically the same, it's just a matter of using a beefier LED driver!
My finished lamp measures 30"x30" square and is 3.5" tall. It hangs 5.5" off the ceiling, and uses 9x 3W RGB LEDs controlled by a PIC 16F1829 microcontroller.
Originally the lamp had an attached control panel for color and speed adjustment. Then one day I found a perfect IR remote control with Power, R/G/B, and Up/Down buttons and even a built-in switchable backlight! I decided this would be a fun and functional addition so I wasted no time hacking the IR output signal and interfacing it to the controller.
The lamp starts out in white-light mode (like a normal ceiling light). At the press of a button, it switches to RGB Color Fading. From here, you can adjust the speed with the Up/Down buttons or even pause the color at any point in the RGB fading cycle.
Hopefully this instructable will give you some construction ideas or inspiration for your own large-scale RGB LED project!
Step 1: Parts List
Single-wall corrugated cardboard
Plastic sheet rock corner bead
Rivets and Riveting tool
White Paint (optional)
Qty 1 - PIC16F1829
Qty 1 - 16MHz TTL Oscillator
Qty 1 - IRM 8410 or GP3U10X IR Decoder
Qty 1 - LM7805 +5V Linear Voltage Regulator (or equivalent +5V supply)
Qty 1 - 12.1V Zener Diode >= 1W Power rating
Qty 1 - 4.7k Ohm, 1/4W, Resistor
Qty 3 - 1k Ohm, 1/4W, Resistor
Qty 3 - TIP121 Darlington Transistor
Qty 9 - 3W RGB LEDs (1W per color) (Buy 'em on Ebay, search for "3W rgb led", ~$6/ea)
Qty 1 - Power supply(s) (See Step 3) (I used Part# 418-CFM60S300 30V 2A supply from Mouser for $34.25)
Qty 3 - Current Limiting Resistors (See Step 3)
GE AREM4000-X Executive Remote (Ebay)
Hot Glue Gun
Storage Oscilloscope (Optional, but VERY helpful!)
Step 2: Building the Lamp
The lamp itself is built out of single-wall corrugated cardboard reinforced with sheetrock corner bead and held together with rivets. I found the plastic corner bead from lowes was very convenient, because the holes in the bead were perfectly sized to accept a 1/8" size rivet!
My lamp measures 30"x30" square and is 3.5" tall. This size was arbitrary, you can adjust it based on the size of the room or number of LEDs.
1) To start with, cut 4 pieces of the sheetrock bead 30" in length. Using these pieces, form a box as shown in the picture and install a rivet in each corner. I recommend using a square to make sure all the corners are even.
2) Next, cut 4 pieces 3.5" in length for the vertical wall supports. Again, the height of the walls was arbitrary.
3) Place one 3.5" piece in each corner and rivet into place. This adds rigidity to the square, as well as vertical support for the walls.
4) Now cut cardboard pieces to fit in the bottom of the square and the four walls. The cardboard can also be riveted to the sheetrock bead. Just poke a little starter hole through the cardboard before inserting the rivet, and be sure to use a washer on the side of the rivet that presses against the cardboard (otherwise the rivet will pull through).
5) (Optional step) Paint the inside of the lamp a bright color to help reflect the light. I used white semi-gloss paint since I had it on the shelf.
6) Finally I suggest wrapping the outside of the lamp with your fabric of choice. I chose a flat black fabric to match the room decor, but you could really pick any fabric. Just pull the fabric tight and affix it with hot glue!
Step 3: Control Circuitry
The control circuitry is about as simple and it gets (See the attached schematic). There is a PIC 16F1829 microcontroller with three PWM outputs, and each output uses a bipolar transistor driver and current limiting resistor to interface to the LED strings. If you're looking for more electrical efficiency, you could try using a specialized LED control IC like the ZXLD1350.
I opted to run each LED string in series for ease of wiring, ease of control, and greater efficiency (only one current limiting resistor for 9 LEDs). You do give up some freedom, since now you can only control each color channel instead of each LED individually.
I used a crystal oscillator to provide the microcontroller clock because a) I had one laying around, and b) I wanted to make sure I had accurate timing for the remote control decoding. There is an internal oscillator in the PIC 16F1829 that you could potentially use to reduce parts count.
The IR detector/decoder is one I found in the parts bin. You could use any type of IR detector, but I like the can type since they have built-in filters and amplification.
Power Supply and Current Limiting Resistors:
You want to select a power supply voltage for the series LED strings that is as close as possible to the total series voltage of the LEDs to minimize power dissipated in the current limiting resistors. Once you have selected a voltage, use Ohm's Law to calculate the resistance needed for each LED string. According to the LED datasheet, each LED can handle 0.35A of current for full brightness and the TIP121 Collector-Emitter saturation voltage is 0.75V. Remember that the LED voltage drop for each color will be different.
R = (Supply_Voltage - (9*LED_Voltage_Drop) - 0.75V))/(0.350)
And, calculate power dissipated:
P = R^2 * 0.350
I used a 30V power supply, so this required a 29 Ohm 3.6W resistor for the Red string and 6.3 Ohm, 0.7W resistor for the Green/Blue strings. I dug around in the junk box and ended ended up with 30 Ohm 10W and 6.8 Ohm 2W respectively.
If you can find a power supply with an additional +5V output then you can eliminiate the LM7805 linear regulator and power the digital circuitry directly.
I assembled the final circuit on perfboard (See picture in step 6).
Step 4: Hacking the Remote
I bought a big old GE component video monitor at an auction about 10 years ago. Earlier this year I finally found a use for the monitor, but lo and behold when I hooked it up the thing was dead. The good news is that the monitor came with this awesome remote control!
Measuring the IR Signals:
To understand the remote control I hooked up my IR detector to a storage oscilloscope and started pressing buttons. The nice thing about a storage scope is that it saves the IR code on the screen for you to analyze. Taking it a step further, I actually saved the traces for each button as a .CSV file to import into an Excel or OpenOffice Calc Spreadsheet. See the attached file for my IR signal spreadsheet for the Power button.
Analyzing the IR Signals:
To use the remote, I wasn't necessarily interested in decoding the whole message structure. Mainly, I wanted to find the differences in the signal for each button press.
Using the spreadsheet and the time-stamped scope data, I discovered each IR signal had three parts - a start pulse, a 16-bit Remote ID (which is the same for all buttons), and then a 16-bit Button Code which is unique for each button. By looking at the last 16-bits of the IR signal, we are able to discern which button was pressed.
The one tricky part to using the remote code is when you hold down any button, the remote sends out an identical "repeat code" until the button is released. This repeat code is very similar to the start pulse, but with different time durations.
Using the IR Signals:
I have the IR signal connected to the PIC Interrupt-On-Change pin. Using the internal Timer 0 module, we can count the time period between falling edges on this pin. Everytime there is a falling edge, the PIC saves the state of the TMR0 register (to record the previous period) and then restarts TMR0 (to record the next period). Using this information, we can determine whether a 1, 0, Start pulse, or Repeat pulse was received.
Step 5: Writing the Code
The code for this project was written in Microchip's Assembly language. Both the commented source code and compiled hex file are attached. A rough flowchart of the program flow (related to each button) is attached in the pictures below.
The program consists of three main parts:
1) IR Code Buffering
2) IR Code interpretation
3) PWM Control (RGB Fixed color, color fading, and white-light mode).
IR Code Buffering:
Using the process described in Step 4 - "Hacking the Remote" I learned that the length of a 0, 1, Start Pulse, and Repeat pulse were all unique and repeatable values. Every time the PIC sensed a falling edge on pin 17 (Interrupt-on-change) it would record the time since the last falling edge and then compare that value to a series of time "windows" to determine which type of pulse just came in. You can see a rough flowchart of this process in the images below. The window comparison code is not original, I found it at the excellent PICLIST Website (http://www.piclist.org/techref/piclist/index.htm). If the length does not fall into any window, I set a Bad Code (BC) flag and ignore everything until the next start pulse.
IR Code interpretation:
Every time a 1 or 0 is detected, the PIC pushes that value into an 8-bit FIFO register. Even though the pulse train from the remote is more than 8 bits, we always end up with the last 8 in the register, which happens to contain a unique value for each key of interest. I compare this code to the known digital value for each key (these were measured on the oscilloscope in Step 4) to figure out which button was pressed and which action to take (White light mode, RGB mode, Increase Fader Speed, etc). This 8-bit value is saved into a second register so that if the repeat pulse shows up, we will know which command is being repeated.
The PIC 16F1829 has 4 10-bit hardware PWM registers which makes it ideal for RGB color control. By using the hardware PWM modules the PIC is free to do other stuff while the PWM is going in the background.
The intensity of each color is controlled by 10-bits. When the lamp is turned on, each value is at max to give white light. When the "CONV" button is pressed, a 3-part loop begins in the software.
Part 1) Red Decrementing, Green Incrementing, Blue = 0
Part 2) Green Decrementing, Blue Incrementing, Red = 0
Part 3) Blue Decrementing, Red Incrementing, Green = 0
The program continues to loop through these three parts until either white light mode is selected, or the "STATIC" button is pressed to pause the lamp at the current color.
Step 6: Putting It All Together
Now that we have covered the major pieces of this project, it's time to put it all together.
You are going to want to attach the LEDs to some sort of heatsink, as they tend to get hot. I mounted them onto spare TO-3 size transistor heatsinks, and then press-fit the fins of the heatsink onto another piece of drywall corner bead hot-glued to the base of the lamp. This gives the LED light a good exit angle for getting out of the lamp (so the light disperses around the room).
Stash the power supply in the corner or on the edge of your lamp where you have the best frame strength. The circuit card is pretty light, and can be hot-glued anywhere.
I mounted my IR sensor in the middle of the lamp by cutting a hole in the cardboard and hot-gluing it in place. I didn't have to cut a hole in the fabric outside because it was so thin the IR light went right through it.
Attach a piece of string to each corner of your lamp, tying it through a couple holes in your corner bead frame.
How you attach it to the ceiling is a matter of personal preference. Make sure you mount it to the solid ceiling joists so it doesn't fall down and break! See the attached picture for my method - I made four custom hangers which I nailed into the ceiliing, then tied the string onto a washer which catches on the hanger.
You will also need to get power to your lamp. For a long time I used an extension cord run discretely up the wall. Recently I installed an always-on AC outlet above the lamp.
Put it all together, and there you go - a giant ceiling-mounted remote-controlled RGB LED moodlight!
Watch a video of the lamp in action here: http://www.youtube.com/watch?v=BINE3xcdq_M