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.