This is the code I used for driving PC fans on a Uno. Use this code in setup:
// Only timer/counter 1 is free because TC0 is used for system timekeeping (i.e. millis() function),
// and TC2 is used for our 1-millisecond tick. TC1 controls the PWM on Arduino pins 9 and 10.
// However, we can only get PWM on pin 10 (controlled by OCR1B) because we are using OCR1A to define the TOP value.
// Using a prescaler of 8 and a TOP value of 80 gives us a frequency of 16000/(8 * 80) = 25KHz exactly.
TCCR1A = (1 << COM1B1) | (1 << COM1B0) | (1 << WGM11) | (1 << WGM10); // OC1A (pin 9) disconnected, OC1B (pin 10) = inverted fast PWM
OCR1AH = 0;
OCR1AL = 79; // TOP = 79
TCCR1B = (1 << WGM13) | (1 << WGM12) | (1 << CS11); // TOP = OCR0A, prescaler = 8
OCR1BH = 0;
OCR1BL = 80; // max fan speed (i.e. pin 5 initially low all the time)
TCNT1H = 0;
TCNT1L = 0;
Call this code to set the speed:
// Set the fan speed
void setTransistorFanSpeed(uint8_t fanPercent)
OCR1BH = 0;
OCR1BL = (fanPercent * 80u)/100;
PC PWM fans are designed to be driven from an open collector or open drain output, so I drive them from the Arduino pin using an NPN transistor, or 2N7000 mosfet, or an opto isolator if I need isolation. It's safest to use a separate transistor to drive each fan, although the PWM fans I have bought come with cables that just connect the PWM input in parallel with the one for the CPU fan.