Introduction: Computer Fan Speed Modifier (in Under 30 Minutes)
I discovered that my hard drives were running hot, so I wanted to add an additional fan to my PC. I had the perfect sized fan, so I mounted in the case, connected it to the fan header, and thought I was all set, until my fan started cycling up and down making way more noise than needed.
It turns out that my motherboard didn't like the fan. If the fan spins slower than the preset limit, the motherboard thinks there's a problem and go into a failsafe mode, running the fan at full speed. Then it will see that the fan is now spinning fast enough (since it's now going full speed) and exit the failsafe mode, putting the fan back to the original speed (which the motherboard still won't like), resulting in your fan speeding up and slowing down even 10-15 seconds. It gets very annoying very quickly. Google "Supermicro fan cycling" and you'll see a ton of people complaining about this.
You can fix this is software, setting up IPMI and modifying the thresholds. Unfortunately, that didn't prove as straightforward as it sounds, and so after 15 minutes of googling how to configure IPMI, I gave up and decided there had to be a hardware solution, and it turned out to be pretty straightforward.
I took an Arduino board I had lying around (I used an old BareBonesBoard from ModernDevices, but you can use an Uno with no changes, and you should be able to use any other Arduino with very minimal changes). I cut the PWM wire on the fan and fed that to an input on the Arduino. I then had the Arduino board time the rising and falling edges of the PWM input to measure what the PWM duty cycle was. I connected the fan to one of the Arduino's PWM outputs, and then just added an offset to the PWM input to make the fan run fast enough to make the motherboard happy.
Step 1: Get the Spec for Your Arduino Board and Your Fan
If you don't know how PWM (Pulse Width Modulation) works, and you'd like to learn a little more before proceeding, there's a quick tutorial on arduino.cc: https://www.arduino.cc/en/Tutorial/PWM. They are discussing it in terms of LED brightness, but the same principles directly translate to fan speed.
The first thing that you'll want to do is get the spec for your particular fan.
In the spec, it will list the color of the wire for the PWM/Speed Control input. It will also say what the range of PWM frequencies that will work, and what the optimal frequency is (for my fan, it was 25kHz).
Next, you'll want to look at the spec for your Arduino board - specifically what PWM outputs are available and what input voltage it can take. The fan operates from 12V, so you'll want to make sure that your Arduino can take 12V on the VIN pin.
For the PWM output, it is very likely that the default frequency will be too low for your and it will need to be increased. Luckily, there's code already available that does just this: http://playground.arduino.cc/Code/PwmFrequency (this code is already in the attached image)
Step 2: Program Your Arduino
If you're using an Uno, you should be able to upload the code exactly as is. If you're using a different board, you may have to change the pin number for you input and output (lines 3 and 4 of the code), and if your fan PWM frequency needs to be very different than 31kHz or if you're using a different PWM output, then you may need to change line 32.
If you need any help modifying the code for your particular case, feel free to post questions in the comment section.
Other than that, you're welcome to poke around in the code. I have it take 64 samples and average them to get the incoming PWM duty cycle value, and that seemed like a value that filtered out any spurious data I was getting. After each measurement-and-update cycle, I have it sleep for 1 second (line 137). And I have a 2 second timeout (line 9) for deciding that the input has gone to 100% or 0%. I have the offset set to 60% (line 8), which seemed like a good value for my fan and motherboard.
Download the image to the board and then you're ready to begin the wiring.
Step 3: Wire Your Arduino Into Your Fan
First, cut the fan PWM/Speed Control signal. On my fan, this was the yellow wire, but on other fans, it's the blue wire. Just see what color wire is connected to pin 4 of the fan header connector.
Connect the half of the wire that's coming from your motherboard to your input (in my case, it was Pin 2).
Next, connect the half going to your fan to your PWM output (in my case, it was Pin 9)
The only tricky part is splicing in power. You'll want to remove some of the insulation from the middle of the black (GND) and red (12V) wires, so that you can solder wires from there to your GND and VIN pins of your Arduino board, respectively. After you've soldered the wires, you'll want to wrap them in electrical tape so the solder connections cannot touch each other.
Step 4: Mount Your Arduino and You're Ready to Go
I did a quick 3d print for a base for my Arduino board (.stl attached), which allowed me to double-stick tape the board to the inside of my PC case.
I closed up my case, and now I have a fan that still responds to PWM changes from the motherboard if things get to warm, and yet it's much quieter than if I were to just run the fan at full speed.
I didn't have to buy a new fan and it took me less time than figuring out how to get IPMI configured and running.
Question 4 years ago on Step 2
I'm noticing that when I choose a different pin other than pin 9, pin 5 for example, I see pauses in the waveform, but when I use pin 9 it's nice and smooth. (I'm using an Arduino Uno) Any ideas on why the PIN number would matter? https://youtu.be/k42J9kzzfaw
6 years ago
I have 2 systems in one case and want to be able to run the case fans irrespective of which system is on and which off. This means I can't use the fan controller on either mobo as if that was off then there would be no case cooling for the other system. Would this project be able to control a number of fans via a fan hub? I have 2 x 140mm fans, 1 x 120mm fans and want to add another 1 or two fans as well. I have a fan hub that allows up to 6 fans to be connected.
Reply 6 years ago
I could see a couple ways of approaching your problem. I think the simplest would be to take the code and add a second input. Duplicate the code that measures the PWM signal and have it measure the PWM signal from both motherboards. Have the code take the greater of the two results and drive that out to the fan hub which would then drive all the fans. If you find an Arduino with enough PWM outputs, you could even replace the fan hub with the Arduino and have it drive the PWM signals to all the fans.
Reply 6 years ago
I like that idea. Will give it some thought. Will have ro find some hood tech info on how PWM works to build something like thay.
What arduinos have sufficient outputs for such a thing
Two front fans would be tge same but other 2 or 3 may need to run at different speeds... hmmmm.
6 years ago
It seemed it but too much for me at first glance, but with al the cheap 'duino clones about... I say: "Thank you my good man, for pointing this solution out to all of us.".
Furthermore, the sketch you provided is pretty darn elaborate.
Thanks for sharing BricCrafts!
6 years ago
I own a big gigabit switch for which I changed the
fans that were too noisy. With the new fans, the air flow is good, but
the router go in safe mode and logs an error such as "low speed fan".
was thinking to do the same thing you did in order to let think the
switch the fans were running at the right speed: so thanks a lot for
sharing this project !
Reply 6 years ago
You're very welcome, hope it works out for you.