Introduction: Fading RGB Keyboard Light
Old electronics are widely available and can usually be recycled into cool gadgets and incorporated into other projects. This Instructable will go through the process of using an old scanner to make a fading rainbow keyboard light. The inspiration for this project came when I was playing with the scanner light bar and noticed that the light from it came out at an angle, instead of straight out. I used this property to place the light behind my keyboard (on my monitor), rather than above it. The light shines down at an angle, illuminating my keyboard for all those late-night programming sessions.
This Instructable will teach a few skills, including:
- Circuit creation and PCB making
- Low-cost component harvesting and acquisition
The result will be a smoothly fading rainbow light to brighten your keyboard and provide a pleasant glow even in the darkest hours of night. It also has light sensing capabilities, so it can turn on and off automatically! The finished product can be seen working here:
Step 1: Scanner Harvesting
By far, the most crucially important part of the project is the RGB scanner light bar. You should be able to get one (or a bunch) for free off of Craigslist or Freecycle, or you could buy some cheaply at a thrift store. Some scanners contain fluorescent light bars, and while these will work for a keyboard light, they will not provide the coveted smooth rainbow effect. Thus, they will not be covered in this Instructable.
If you found the right scanner, you can dismantle it to reveal the long RGB light bar with the plastic lens. It should have a ribbon cable attached. Using a 3V AA battery pack, probe the ribbon cable terminals until you find one that makes a color light up. My LED was common-anode, so all the colors shared a positive terminal. I heard somewhere that the common terminal is usually the leftmost or rightmost trace on the ribbon cable, so you could start there by applying the positive or negative battery lead (if your LED turns out to be common-cathode) and then testing the other contacts. If you don't find the right one on the first try, don't worry - these small reverse voltages shouldn't harm the RGB LED.
Once you have determined which colors and common terminals correspond to which contacts on the ribbon cable, solder wires (they don't have to be different colors) onto each terminal, noting which ones lead where, and seal the mess up with hot glue. This will prevent the fragile traces from breaking later on. I added a female pin header and color-coded the pins with permanent markers to enable easier identification.
I noticed on my light bar that the LED is actually only at one end - the plastic lens distributes the light somewhat evenly along the width of the bar, elmininating the need for multiple LEDs. I found that quite interesting.
Step 2: Part Acquisition
I sourced my parts from multiple places and was surprisingly able to keep my costs to $0. I will list the parts needed below:
- ATTiny85 microcontroller: this is the brain of the project - get a free sample from Atmel
- OPT101 light sensor: this reads the ambient light in the room - get a free sample from Texas Instruments
- USB connector and wire: powers the project - take one from a broken USB gadget
- Pin headers and plugs: connect power & LED to circuit board - source them from junk circuit boards
- Copper-clad circuit board: can be substituted with protoboard - cut off a large ground plane or "pour" from a junk circuit board, or use new copper-clad if you have it
- 0.1uF ceramic capacitor: protects the OPT101 from spikes - get it from a junk circuit board
- 10uF electrolytic capacitor: smooths out USB voltage (optional) - get it from a junk circuit board
- 130Ω, 140Ω, 150Ω resistors: protect LED from burning out (values are general, not exact) - get them from junk circuit boards
You may have many of the components lying around, and most ones that you don't already possess can be easily bought or sampled online. As you can see, I extensively recycled old circuit boards, even taking the large copper-clad traces to use as mini-sized circuit boards. You should be able to get everything for free or near to it.
Step 3: Circuit Design
Once you have acquired all the parts, it's time to determine how to connect them all. I have attached a circuit schematic in the images section, so you can look there for instructions.
If you don't enjoy scrutinizing schematics, the circuit is simple enough that you can just read off which pins to connect where. The 10uF capacitor smooths out the USB voltage from the USB power male pin header, so it gets connected between +5V and ground (GND). The side with the stripe goes to GND. The ATTiny Vcc and GND pins go to +5V and GND, respectively. Pins 0, 1, and 4 of the ATTiny go through the resistors to the RGB pin header, and an additional male pin is added to the end of the header to supply the positive voltage to the light bar (this supplies negative if you have a common-cathode LED). On the OPT101 light sensor side of the circuit, pins 4 and 5 are connected together and then go to the ATTiny pin 3. Pin 1 is connected to +5V and pins 3 and 8 are connected together and to GND. The 0.1uF capacitor is connected between +5V and GND close to the OPT101 - this smooths out the voltage to make the chip run more smoothly.
Once you somewhat understand how the circuit goes together, it may help to lay it out on a breadboard. That way, you can make sure everything works before committing to a printed circuit board or protoboard.
Phewft! That was a lot, but I hope that it helped. Electronics can be trickly little stinkers every now and then. On to the fun stuff!
Step 4: Etching
Once you understand the circuit (more or less), it is time to etch the circuit board. I used the toner transfer method to etch my piece of recycled copper-clad, but other methods exist, including the photo-resist method and simply using a permanent marker to draw your circuit onto the board.
To etch the board, first make the layer that resists the acid by drawing the circuit traces either in Paint or in a dedicated PCB design program. I made mine in Paint just by transferring the schematic into real-life routes for traces, with the correct spacing for components (see picture for example). If you choose the toner transfer method, print this off on the waxy side of some sticker paper using a laser printer (inkjets will not work) on the highest toner density setting - this is found in the printer preferences, which may be online. I had to adjust the percent size that my picture printed at to get correct component spacing. After it has printed, check that the component pins line up with the pads and heat your clothes iron to a medium-high heat. While it heats up, wipe the board with acetone and set the paper on top. Holding the paper firmly so that it won't smudge, smoothly press the iron over the surface. Make a few passes, pressing strongly. After a couple minutes, set the iron aside to cool and soak the board in water to loosen the paper. After 10 minutes, peel the paper off. If everything worked, you will have a circuit resist! If it didn't work, don't be discouraged - I had to try multiple times to get my technique right and prevent squishing the toner excessively.
After your resist is applied, it is time to get your hands dirty and etch the board. This is one of the most fun parts of circuit board creation. Watch NurdRage's video on circuit board etchants, and then pick whichever one suits you best. Most people use ferric chloride or hydrochloric acid with hydrogen peroxide, but as I had neither, I used diluted nitric acid, as NurdRage describes in his video. Place the board in the etchant and let is sit for a few minutes, monitoring the progress of the etching. Once all the copper has been removed, take out the board (and please wear gloves!) and wash it in water. Swab the etch off with acetone or alcohol and admire your handiwork! The copper will be very nice and shiny!
Step 5: Circuit Board Population
With your board etched to expose the pretty copper, you can now begin building the circuit. To begin, drill holes for all your components on the pads. I used a 3/64" wood/metal drill bit, but I am sure that a proper circuit board drill bit would work better. I just didn't have any smaller sizes available.
Once you have drilled the holes, you can do the optional step of tinning the board. Putting a thin layer of tin on the copper improves corrosion resistance and makes soldering easier. To tin the board, simply smear flux on it and then tin the tip of your soldering iron (flat tips work better for tinning). Drag your soldering iron tip over the traces of the board. Almost magically, they will turn silver as the heated flux cleans the traces and allows solder to wet the copper.
Now you can actually populate the board. Following the instructions on building the circuit from step 3, add the components. I provided pictures of the process. Population is quite simple - just find a component, pop it in to its place, double-check that you got it right, and then heat the leads with the iron and apply a small amount of solder. I found that when adding the cut-up bits of the large IC socket for the smaller ATTiny, it helped to put the chip into the socket parts to ensure correct alignment.
While you're soldering, attach a two-pin female header to the red and black wires coming from the USB plug. Be sure to extend the cord, if necessary, so that your keyboard light can extend from your computer's USB port to your monitor (or wherever you choose to mount it).
As a side note, I used jumpers in designing my board. Sometimes, when routing the physical traces, it is necessary to have one trace cross another while not having electrical contact. A jumper is a wire that physically goes over the trace, allowing such designs to work. I used some bits of single-core wire to connect pads (and pins 4 &5 of the OPT101) together over other traces, as seen in a few of the pictures. It is a helpful little tip for designing your own circuits.
Step 6: Preparation for Coding
To program the ATTiny, by far the easiest way is to use an FTDI programmer. This device plugs into your computer's USB port and programs the ATTiny, without any extra hassle. SparkFun has a good FTDI programmer, but spending $20 isn't the goal of this project, so I didn't go with this option.
The second-easiest approach would be to use an Arduino with a tiny bit of extra circuitry to program the ATTiny. The website 42 Bots has a good tutorial on this, which can be found here.
However, I also do not own an Arduino, so that left me with some extremely creative options. I used the parallel port (and a hacked parallel cable) on my Linux computer, along with three 220Ω resistors and a breadboard, to program my ATTiny85 chip. If you decide to go this route, having exhausted all other "normal" options, here are some instructions:
- Make these connections on your breadboard
- Parallel pin 1 to ATTiny85 pin SCK, through one 220Ω resistor
- Parallel pin 2 to ATTiny85 pin MOSI, through one 220Ω resistor
- Parallel pin 11 to ATTiny85 pin MISO, through one 220Ω resistor
- Parallel pin 16 to ATTiny85 pin RESET, through no resistors
- Parallel pin 18 to ATTiny85 pin GND, through no resistors
- USB connector +5V to ATTiny85 +5V
- USB connector GND to ATTiny85 GND
The above instructions can also be followed if using other programmers, omitting the step about connecting the parallel port to the ATTiny. Be sure to also select the right programmer.
One of the best parts of the Arduino Tiny core is that it allows you to program the ATTiny85 chip in the very user-friendly, intuitive Arduino programming language. This enables younger minds, as well as somewhat nontechnical people, to learn programming while having fun. I honestly don't know if I would have completed this project if I was unable to use the Arduino language. It simplifies the process greatly.
The core also enables a 3rd pin to be a PWM output on the ATTiny85. PWM stands for Pulse Width Modulation and is commonly used to control the intensity of lights and the speed of motors. Using PWM on the ATTiny, it is possible to change the brightness of each LED color, effectively creating a smooth rainbow of all possible two-color combinations.
Step 7: Coding!
Coding is one of the most enjoyable parts of this entire project. As stated previously, the Arduino IDE was used for coding, which greatly simplified the process. Once you have a programmer set up and have your software ready to go, you are ready to get typing! Or copying and pasting, as the case may be. :)
This will be long, but I hope it will also help, and if nothing else, spark an interest in coding. I attached the Arduino .ino file, as well as the PastBin link with line numbers. I will also go through generally what each bit of the code does.
This code assumes that you are using the schematic laid out in step 3.
First off, lines 1-11 set up some variables that will be used throughout the program. It is mostly general stuff like which inputs/outputs correspond to which numbers, the rate at which the rainbow should fade, and the threshold which the light-sensing should respond to. I'll get to lines 8-11 in a moment.
Lines 13-18 simply set up all the pins as outputs (the light sensor pin is input by default). Line 17 changes the color to be completely off, using the function described in the next paragraph.
Lines 49-53, the changeColor() function, provide the base for this program. Basically, the function takes a value 0-255 for the individual light value for each color and then writes it to the correct pin, using the PWM signal discussed previously. However, since my LED is common-anode (common positive), so a value of 0 (off/ground) means that the color will be on full brightness. Thus, to create the desired effect where 255 indicates full brightness, the colors are subtracted from 255 to invert them.
Going back up the program, the loop() function begins at line 20. After that, lines 21-27 check to see if it is dark using the threshold value set in the variables section. The if/else statement has the added functionality of checking whether the dark variable is already set - if it is already dark, then the program won't set it to be dark again.
Line 26 is part of the most complicated and awesome part of this program. I didn't want my keyboard light to stay on all night (because I'm rarely up at 3 A.M. on the computer), so I decided to add some pizazz with an auto-off feature. I had to try multiple angles of approaching the problem before I found one that worked. The elapsed time functions didn't seem to do the job, and as the ATTiny doesn't have a real-time clock, I couldn't just read the time. This system works by calculating the time it takes to do one rainbow in line 8. Then, based on the number of hours I input as the time the light should remain on, it calculates how many rainbows it should complete after it gets dark. The if statement before the main ranbow program (line 28) checks if it is dark and also checks that the program still has more rainbows to run. Line 41 increments the counter each rainbow. And finally, line 26 resets the rainbow cycle counter when it becomes light.
This demonstrates the incredible power of code. By simply adding a few lines of text to a program, you can add amazing functionality that would be next to impossible to make with hardware. This is one of the reasons I love programming so much. It enables me to put my ideas into action in a world where the only real thing limiting me is my imagination.
To wrap up this lenghty explanation, lines 29-40 cycle through all the colors of the rainbow. Basically, the rainbow code works by starting with one color (red for example) at full brightness. Then, the for loop gradually moves the red value down and moves the green value up, until green is at full brightness. The process repeats until blue fades out and red is once again the dominant color. The last part of the program is the else statement in lines 43-46 that turns off the light if it isn't dark or if it has been on for more than 8 hours (the timeout_hours variable).
Step 8: Finishing Touches
Sorry about the ultra-long explanation of my code! I hope it has helped you, though. I tried to explain it because knowing how to program is such a valuable skill - it opens up doors to new projects, jobs, and capabilities, and above all, it's fun!
Once you have your code done and your circuit board created, plug in the USB and RGB plugs and try it out! When you cover the light sensor with finger or turn the light off, the RGB strip should turn on and begin to smoothly fade through the rainbow. If you want it to turn on at a brighter ambient light, you can adjust the threshold variable, and to make it fade faster or slower, you can change the rate variable. My keyboard light can be seen in action here:
After you are happy with your finished gadget, install it! I used some double-sided foam tape to attach the circuit board to the back of my monitor where it reads the light behind my monitor. I attached the light bar facing down onto my keyboard. The USB connector conveniently tucks away behind my desk and plugs into the back of my computer.
This has been one of my favorite projects, and I hope you will enjoy it too, if you decide to replicate it. I learned some awesome new skills along the way, like circuit board creation, Arduino programming, and perseverance (the code didn't always come easily). However, I am most pleased with the result - a pleasant light-activated rainbow to brighten my keyboard as I stay up way too late typing this very Instructable. ;)