Intro: CPU Fan Hack - RGB LEDs - Arduino & TLC5940
In this Instructable, I will be guiding you through the process of hacking and converting a clear, 120mm PWM cooling fan used in common household PCs from a single color LED to individually addressable RGB LEDs. The applications of this hack are not only limited to 120mm cooling fans, but anything your creative mind can fabricate. Accent lighting creates a unique aura, customizing the object you are illuminating and creating a profoundly different perception. In this guide, I will be modifying my computer tower to remove large amounts heat generated by the high performance CPU and GPU, in style. With the use of Texas Instruments' TLC5940 - a 16 channel PWM controller - and use of the finely crafted 5940 Arduino library - embedded design becomes extremely simplified for those of us more hardware inclined hobbyists. Additionally, we can stack TLC5940's in parallel, easily allowing us to add more fans to hack and customize all of the fans in your computer!
This is a really fun, simple, safe, and affordable weekend project. In this project, you will learn how to properly solder and tin wire leads, how to create a secure wire harness with strain relief and a sleek, manageable appearance. You will learn how to wire RGB LEDs, how to adapt common cathode or common anode LED depending on the application and hardware being used. You will learn how to configure the TLC5940 and associated hardware, as well as basic operation from a software perspective. You will finally learn how to install a CPU into a computer system, and what techniques are best for dispelling heat from within your PC tower. Finally, you will take this knowledge and gain the ability to apply accent lighting to any object your heart desires, wow to your family, and show off to your friends with your magical ambiance of mystical colorful lights.
Experience Level: Beginner to Intermediate
Cost Level: Low
Estimated Build Time: 3 Hours
-Standard 5mm RGB LEDS (common cathode(-) is preferred but not required)
-120mm cooling fan
-x12 3906 General Use Transistors
-Zip Ties or Twist Ties
-Super Glue or Tape
-x1 2kohm Carbon Film 1/8w (or larger) Resistor
-DC Supply (for more LEDs or higher power LED applications)
-TLC5949 Arduino Library
-USB A to B cable
Step 1: 120mm Fan Preparation
The first step is to prepare the fan to installation of the RGB LEDs we will be replacing with the boring single color provided. For the fan, I used a generic eBay fan - found for 5$ (with free shipping).
They are low in cost, easy to work with, and operate fairly quietly. The LED's are very easy to access, remove, and replace. Many times, when purchasing the fans, it is not mentioned what size the LED is that comes OEM from the manufacturer. My fans particularly came with green 5mm LEDs - voltage drop and current will be somewhere between 2 or 3vdc at 30mA (max).
Luckily, I had 5mm RGB common cathode(-) LEDs laying around from previous projects. They are a terrible quality LED, but they are great for prototyping because they are so affordable. You can find them in bulk on eBay - I believe mine came 10$ for around 100 of them. Sometimes, they can even be found in the "top hat" style -- or wide viewing angle for maximum light dispersion. This is great for because the light is "thrown" around more than the traditional directional LEDs. The top hat style will not fit securely into the LED sockets of the fan, so glue may be needed if you choose wide viewing angle LEDs.
Identify and Remove LEDs
Begin by identifying the four LEDs of your fan, located in each corner. There will be a very thing + (red) and - (black) wire going to each diode (LED) from the PCB.
-Take a small pick, probe, or screwdriver to gently push the LED out of the socket - from the inside of the fan pushing out. Placing the tip of the pointed object, and placing it on the center of the LED and pushing outward. The LED should slight out very easily.
-Repeat this process and remove all 4 LEDs.
-Clip the LEDs off leaving enough lead length to potentially use the leads coming from the fan if we decide. Also leave enough lead length coming off the LEDs to use them if we require them for any future projects: we don't want to be wasteful!
With the single colored LEDs removed, you should have four empty 5mm sockets, one on each corner. These sockets are where we will be placing the RGB LEDs. But, do not place them yet. We have to prepare the LEDs for the install. We don't want to do any soldering in close proximity of the plastic fan. Lets move to the next step and prepare the LEDs and the wire harness.
Step 2: LED and Wire Harness Preparation
Lets begin preparing the LEDs by testing them. Every product has a factory defects that make it out to the customers. The last thing we want is to go through the motions, and discover at the very end - after all of our hard labor, that the red diodes in our RGBs are defective and not working. Taking the project apart due to avoidable errors can often times delay a project, or even persuade me not to complete the project at all. Lets take a precautionary step and test our LEDs before we prepare them.
Please note: it is always wise to have extra LEDs. Having extras assures that if an unexpected issue arises, you won't be finding yourself on hold, waiting for replacement parts. Many times, Test your LEDs by using a resistor, sized anywhere between 200 and 1000 ohms - in series with 5v. You can use the Arduino's 5v supply and Ground to test each leg.
-Most LEDs are similar in regards to the package the come in. For standard 5mm LEDs, the longest LED is the common lead between all 3 colors. There are actually 3 diodes inside this single package, all sharing a common cathode+ (or anode-, depending on which you have purchased). My LEDs are common cathode, so they share a common negative. If we ground the longest pin using a 200 ohm resistor, we can apply +5vdc to any of the remaining 3 leads to test and confirm functionality and verify each leads corresponding color.
-Take note as to which lead corresponds to which color while testing, we will use this when soldering the wire harness to the LED leads.
-Also at this time, it is wise to test and ensure that your 5mm LEDs will fit snug into the 5mm sockets of the fan. Do this now.
-Spread apart the leads of the LED, making sure to keep track of which pin is which, and clip them shorter as depicted in the picture.
-Tin the ends of the leads of the LEDs carefully. Keeping the iron against the leads of the LEDs for extended periods of time can heat the diodes internally and damage them. It should not take long, press the iron against the lead, immediately after touch the solder directly to the end of the lead and it should flow onto the lead almost instantly.
-Cut the wire you will be using for your harness into four 18" (or greater) sections. Each section of wire will control one LED. I use 22g stranded, ribbon-ed, Red-Green-Blue-Black wire to help make the appearance look sleek, and to simplify troubleshooting. No need to worry, if you have a single color wire, just make sure you tag each wire with the corresponding color or you will find yourself with a bird-nest of wires. Nobody wants to spend their weekend tracing wires.
-Pull apart each wire leaving around 1/2" to 1" of free movement from the ribbon.
-Strip each wire roughly 1/4" back.
-Tin the ends of the wire:
-When soldering the leads of the of the harness, again - do not hold the iron to the wire for long as this could burn the insulation
-Touch the soldering iron against the stripped wire strands. Immediately after, touch the solder to the strands and the solder should liquify and flow, absorbing into the center of the wire.
-Apply solder until the entire stripped area is smooth.
-Applying too much solder can cause the solder to glob on the ends, avoid this stopping when there is a consistent smooth flow of solder absorbed into the strands.
Soldering the Harness to the LEDs
-I use a device called Helping Hands to hold components. It has two alligator clips and allows me to hold the harness with one clip, while holding the lead with the other clip. This frees both hands to hold the iron and guide the wires.
-I have found through my experience, holding the individual harness wire to be soldered with one hand, directly against the LED lead is the easiest method. Using the other hand, press the soldering iron down - sandwiching the tinned harness lead in between the tinned LED lead. Almost instantly, the solder should flow and unify the two together.
-Perform a brief stress test, and give a gentle pull to ensure the connection is mechanically solid.
-Repeat this process for the remaining 3 wires, Take note which wire you are soldering to which lead, keeping consistent with your test - ensuring the correct color wire is soldered to the corresponding lead of the LED.
-Once the first harness has all 4 connections soldered, reinforce these connections with electrical tape or heat shrink. Although I do not have this depicted in the pictures, it is highly suggested to avoid the leads bending and potentially shorting together during install. This can cause the diodes to malfunction and possibly even damage them.
-Repeat this process for all 4 LEDs.
Once you have 4 LEDs soldered to their individual ribbon harness', we can move on to begin installing them into the fan.
Step 3: Install RGBs Into Fan
Step 4: Building the Circuit: Theory
Bill of Materials (BOM) per 1 fan:
-x12 3906 General Purpose PNP Transistors (x25 for 3$)
-x1 2kohm Resistor (pennies)
-x1 TLC5940 (3$)
-x1 Breadboard (10$)
-x1 Arduino Uno (15$)
-22g Wire (3$)
For this project, I will be dedicating an entire breadboard and Arduino Uno. Although I tend to prefer not to use a pre-made Arduino board for the final construction, nor to I like to keep the final design on breadboard - to keep this project simple and available to the vast majority of people - I kept this route. If there is enough interest, I would consider designing and printing PCBs for this project to avoid use of the breadboard and to create a standalone discreet Arduino.
The LEDs I had chosen, are common cathode. As we previously discussed, this implies they share a common negative. There is some confusion in the LED world when comes to digital logic, which type of LED (common cathode- or anode+) depending on the logic levels and hardware being used. Let me explain in terms of the TLC5940 that we will be using.
The TLC5940 is a 16 channel PWM controller from Texas Instruments. It can be used to generate 16 different Pulse Width Modulated signals. In the LED world, this is a common and efficient way to dim LEDs. Rather than traditionally lowering the voltage or current to dim the LED, with a PWM signal - we apply very fast pulses of voltage to the LEDs. By changing the width (or on time) of the pulses, we can effectively turn the LEDs on and off faster than the eye can see. Increasing the pulse width increases the off time - creating a dimmer light level. Decreasing the pulse width decreases the off time, thus turning the LED on for longer periods and creating a brighter light level. These PWM signals can also be used to tell motor servos to move to a specific angle of rotation, however that is for an entirely separate Instructable.
There are 16 channels that output a PWM signal on the TLC5940. Using the associated library, we can directly address each pin, and label them with the reference designators 0 through 15. The question comes into play, when observing the output channels. They do not apply a logic level of a HIGH. They operate with a LOW TTL logic level, meaning the PWM signal is under 2vdc. This is opposite for what we need for common cathode LEDs.
Picture the output sitting at what we refer to in digital terms, at a HIGH level (or +5vdc). The PWM signal goes LOW, down to under 2vdc. Turn turn our LEDs on, we need to ground the common negative pin, and apply 5vdc to each positive pin of the LEDs. By simply putting the output of the TLC5940 channels directly to the each + pin, the diodes will not function properly because they need a HIGH +5vdc from thly positive voltage to the anode (+), and a lower potential: at least 2vdc lower, to the cathode (negative) of the LED. This is called biasing. We need to forward bias the diodes to turn them on, and the output of the TLC does not output a HIGH to achieve our forward biased conditions: meaning the LEDs will not turn on from the PWM signals.
Because there is a clash between the LOW logic level output of the TLC5940 channels, and the HIGH logic level required by the LEDs positive pins. To avoid this issue, I use PNP 3906 transistors. By connecting the base of the transistor to the output of the PWM channel,the transistor will wait for a LOW logic level. When it received it, it will effectively saturate the transistor, turning it on. The transistor, in this application, works exactly like a switch: only turning on when a LOW TTL logic PWM signal is transmitted from the TLC5940 to the base of the transistor. When a HIGH level is recieved from the TLC, the transistor opens like a switch, and prevents current from flowing into the LEDs -- turning them off.
We can now connect the Collector of the transistor to a separate 5vdc supply than the Arduino's, and connect the Emitter directly to the positive pins of the LEDs. I use one transistor for each color: Red, Green and Blue. So each LED gets 3 transistors, one controlling each color: converting the LOW logic of the TLC, into a +5vdc PWM signal that will turn the LEDs on.
This same logic can be applied to any situation. If you need to "reverse" -- or invert -- a logic level, we can use devices such as NPN or PNP transistors, inverters, or other digital devices like AND gates and OR gates, that take logic levels, and convert them to a signal we can actually. If you have common anode, you can place the common positive of the LEDs directly to a 5vdc source, and ground each colored negative pin to the TLCs PWM channels. This will work sufficiently. If you are like me, and have common cathode LEDs, you have many options to invert this logic to fit your load type.
This is the route I chose, due to the extremely low cost of the 3906 PNP transistors, decently fast switching speeds (how quickly can it turn on), and ease of use.
There is a well written website fully explaining the operation of the TLC5940, however we will only be using its basic functions.
Although the schematic may appear complicated - the theory is simple. Each PWM output channel of the TLC5940 will go to the base of a PNP transistor. The collector of that transistor is tied high, to the +5vdc output of your computer's ATX power supply. The emitter of each transistor is tied to a single anode (+) lead of one LED. Repeat this process for each of the three LED leads: one for red, one for green, and one for blue. Each LED will have three transistors, controlled by three PWM channels of the 5940. Apply this same logic to all four LEDs of the fan. All LEDs' cathodes (-) will be tied low to the ground of your computer ATX power supply.
In the next section I will begin showing circuit construction.
Step 5: Building the Circuit: Construction
I begin every new prototype design by using a breadboard, and eventually move the final design to an etched PCB or a protoboard for stability. For the sake of simplifying this design and reaching out to more people, I will keep this design on a breadboard. By the nature, our circuit will be fragile choosing this method - please be mindful of this as I am currently designing a PCB layout to etch - as well as an enclosure (via 3d printer!) to protect our hard work!
For now, we will keep it on a breadboard. I start off by taking the Arduino Uno and securing it to the breadboard as to leave as much of the breadboard open and usable as possible. I use two small screws and two plastic spacer via two portals on the breadboard. Self tapping screws grab very well, however this renders the portal useless.
Install the TLC5940 first, as depicted in the photograph. You may also refer to the schematic.
Pin 27 = Ground
Pin 26 = D12
Pin 25 = D13
Pin 24 = D9
Pin 23 = D10
Pin 22 = Ground
Pin 21 = +5vdc of Arduino
Pin 20 = 2kohm Resistor to Ground (or Pin 22)
Pin 19 = +5vdc of Arduino
Pin 18 = D2
For my later slides - I am repeating this process with two TLC 5940s, and two fans. The circuit is the same for both chips, however you will have to jumper each pin, 25, 24, 23, and 18 from the first 5940 to the second. Then jumper pin 16 of the first 5940 to pin 26 of the second 5940. The second IC will be configured exactly the same as the first IC - with a 2kohm output current limiting resistor, and all ground/power connections same.
I then place all 12 PNP 3906 transistors - 3 for each LED. With the flat side facing upwards, the collectors will be on the left, bases will be center, and the emitters will be on the right. Connect all the collectors together or to 5vdc that will be coming from the ATX power supply. For initial tests, before installing into the computer - I would highly suggest testing with a separate 5vdc supply. The ATX power supply's 5vdc line is usually a red insulated wire, easily identified. For ease, I took my 5vdc off the spare jumper connector of the 2nd fan. You can always measure with a DMM first to assure yourself.
Also, Please note that the left bus of my breadboard is dedicated for 5vdc from my ATX supply. Do not, at any time - connect 5vdc from your Arduino to 5vdc from your ATX supply - while both the ATX supply is on and the Arduino is connected by the USB cable and on. For proper function, do not forget to connect your ATX power supply's ground to ground of your Arduino and circuit.
So we now have the transistor network in place, and all their collectors are connected to +5vdc from our ATX power supply. Next, I begin connecting our PWM output channels of the TLC5940 directly to the base of each transistor cluster of 3, in order. Although this is not depicted in my photographs, I highly suggest tagging each RGB cable to you can keep organized and know which corner of which fan will be coming from which channels of the TLC5940. In the future steps, programming will be much easier if you stay organized.
I designate the PNP transistors they are being controlled by as Q1 through Q12.
Top Left LED:
Red Q1 base to 5940 pin 28
Green Q2 base to 5940 pin 1
Blue Q3 base to 5940 pin 2
Top Right LED:
Red Q4 base to 5940 pin 3
Green Q5 base to 5940 pin 4
Blue Q6 base to 5940 pin 5
Bottom Left LED:
Red Q7 base to 5940 pin 6
Green Q8 base to 5940 pin 7
Blue Q9 base to 5940 pin 8
Bottom Right LED:
Red Q10 base to 5940 pin 9
Green Q11 base to 5940 pin 10
Blue Q12 base to 5940 pin 11
By connecting the PWM output channels to the bases of each transistor, this will effectively turn the transistors on, allowing current to flow from the collector's +5vdc input to the emitters' output to the LED's anodes' (+).
Starting with the TOP LEFT LED of your fan (mark this corner and remember to keep it in the upper left corner when mounting) and moving the the TOP RIGHT LED, followed by the BOTTOM LEFT LED, then BOTTOM RIGHT LED - this is how I address them.
Top Left LED:
Red Q1 emitter to Red LED Anode (+)
Green Q2 emitter to Green LED Anode (+)
Blue Q3 emitter to Blue LED Anode (+)
Top Right LED:
Red Q4 emitter to Red LED Anode (+)
Green Q5 emitter to Green LED Anode (+)
Blue Q6 emitter to Blue LED Anode (+)
Bottom Left LED:
Red Q7 emitter to Red LED Anode (+)
Green Q8 emitter to Green LED Anode (+)
Blue Q9 emitter to Blue LED Anode (+)
Bottom Right LED:
Red Q10 emitter to Red LED Anode (+)
Green Q11 emitter to Green LED Anode (+)
Blue Q12 emitter to Blue Anode (+)
Your circuit is now done! Simple enough. Its a very easy circuit, replicated numerous times. To add more fans, simply lay another 5940 - connect the previously mentioned pins together - and wire your 2nd fan exactly the same. The benefit of pulling our 5vdc from the ATX power supply - is that we know our ATX supplies can handle larger currents if we choose to expand to higher power LEDs or simply want to add more - we won't have to worry about loading down the Arduino's 5vdc linear regular and risk damaging our Uno.
As previously mentioned - I am planning both a UV PCB etching Instructable, as well as a 3d printed project enclosure Instructable to follow this project, depicting how to etch your own PCB (for this design) as well as how to print an enclosure for the project too.
Moving on to our next section, programming - lets see some of the benefits of addressing each LED individually.
Step 6: Writing the Software
I am by no means software inclined. Using the basic TLC5940 examples can result in some very cool effects. I have taken some of these examples and modified them for particular uses. Head over to the following link to download the source code library for your Arduino IDE.
Test first by loading an example. The Fades example has a very cool effect, this was my favorite to start off with. I stress that you test before installing because I experience a few LED failures throughout the process, and we don't want to be desoldering components and rewiring circuitry while the project is inside of our computer (if we don't have to).
If you see colored lights, on power-up - you're off to a good start. I've provided a small handful of examples showing how easy it is to adapt the TLC5940 source code examples and modify them to your own needs. In one example, I make the LED's pure blue to accommodate other accent lighting in my room - when I have them set to blue as well - my computer will match the accent lighting of my room.
In another example, I fade the LEDs from one color to the next, and loop this code so your computer will scroll through different colors. There are many ways to achieve any effect you are looking for, your mind and creativity are the limit. My inept abilities to design software may not be impressive, and in that I am hoping some of you out there will take this project and share your own software effects! I am curious to see what others may come up with.
mils - Fade Rate
STEP - Gray scale step size
RC - Reference Color
r - Red Variable
g - Green Variable
b - Blue Variable
To help simply testing and developing new color fades - I have defined two control variables in the setup portion of our code, mils and STEP.
Mils controls the delay time in the for loop - by increasing the value of mils, we increase the delay between loop iterations, and decrease the rate at which we fade our LEDs. By decreasing the value of mils, we decrease the delay between loop iterations, and increase the rate at which we fade our LEDs.
STEP controls the gray scale step size for each loop iteration. By increasing the value of STEP, we increase the step size of our gray scale code, thus making our LEDs take larger increment steps and fading faster. By decreasing the value of STEP, we decrease our step size of our gray scale code, thus making our LEDs take smaller steps and fade slower.
RC is our reference color. When combining LED combinations, our reference color will be our brightest color. We can then make our secondary color smaller than RC, via a math function (or larger) - this will allow us to establish different hues with more ease and control.
R, B, and B are ultimately the variable that will contain the gray scale code for each set of Red, Green, and Blue LEDs. A value of 0 contained in the variable will equate to the LED being off, while a value of 4095 will be maximum light level for that LED.
For the structure, I use a simple for loop. What the loop is doing first is initializing our three variable: r, g, and b to an off state of 0. Then we initialize our RC reference color variable to a 0, also off. The loop will then say, for each iteration (each instance the loop performs 1 cycle), it will look at RC. When RC is equal to a value of between 0 and 4095, we will add the value of STEP to our RC variable. If STEP contains a value of 1, our RC will step a value of 1 gray scale code per loop iteration. We then write the gray scale value contained in the variable RC to our R, G, or B variables to be written to our LEDs. In this case, I am using Red as our example. I make, via math function, r = RC which makes our r variable now hold the actual light level value, in terms of gray scale code, to be updated to our TLC channels and output to our LEDs.
We then update the TLC, making the outputs follow our variable we configured - and insert a small delay. The loop will then go back to the beginning, and begin the process over until r reaches a value of 4095 (maximum light level).
We then reverse this code with some small manipulation - and run the code backwards - dimming our red LEDs back down to off. The cycle then repeats.
#define mils 10
#define STEP 1
//There are 4095 steps from off 0 to max on 4095.
//Reference Color defined as RC
//The color you would like to be the dominant color will be the reference color
//Secondary dim colors to be combined will be referenced to RC
int r = 0;
int g = 0;
int b = 0;
r = RC;
r = RC;
If all has worked, and you now understand the hardware, and software behind the design - then it is now time to install the fans into your computer and begin enjoying the benefits. The installation process is simple, as you would install with any other PC fan - only now we have a circuit to tuck away.
Step 7: Installing the Fans
Make sure to mount your fans facing in opposite directions. I prefer to push the air out from the top, and pull the air in from the bottom. Being as heat rises, I like to push as much air out from the top of my computer, keeping fresh cool air pulling in from the bottom - thus keeping the air circulation flowing well.
Being as this circuit is on a breadboard - it will be very fragile. I highly suggest placing the PCB into a bay used to hold your DVD drive or other drives - assuring to keep it away from touching your motherboard. A project enclosure is on the future list of features to add.
I ran a USB cable from a rear port, through a rubber grommet provided by my full sized tower - to the inside of the computer - connecting to the USB of the Arduino. I also now take the extra connector provided by the 2nd fan I am using to jumper in 5vdc and Ground from my ATX supply.
Seal it up and turn on your computer. You will now be able to program your Arduino on the fly without opening your computer to change anything. We can easily change the color of our PC fans now with a few preset sketches written. Also on the future list of features will be a visual studio project to control our PC fans with a windows application.
If I have missed anything, or there are any questions or concerns - please feel free to ask away!
Also, please share your sketch examples, improvement ideas, or anything else you feel like sharing!
Thanks for reading.