Hello all,
I have run into a sort of wall when it comes to reading the RPM of a PC fan. I have followed the playground guide titled ReadingRPM (sorry for not linking, posting restrictions)

I am using an opto-isolator and it works very well to control the speed with a simple analogWrite(pin,speed) command.

Everything works normally, but as I drop from 255(full on) the analogWrite value to anything below 248ish the RPM is way out of whack, like at 230 the RPM reads as 11750.

I am not sure if this is due to the opto-isolator dropping the power or if the program execution is getting messed by the interrupt.

I goal is to have a temperature control scheme that allows me to monitor the fan speed in the middle of a program.

If anyone has attempted this or similar before please shed some light on whats going on here.

Many thanks :slight_smile:

I'd like to see your sketch. The RPM code is only +/-20 accurate to begin with. I'd also like to know the part number of your opto-isolator.

Here is my sketch:

volatile byte rpmcount;

unsigned int rpm;

unsigned long timeold;

void setup()
attachInterrupt(0, rpm_fun, RISING);

rpmcount = 0;
rpm = 0;
timeold = 0;

void loop()
analogWrite(11,255); //Setting speed of fan
if (rpmcount >= 20) {
//Update RPM every 20 counts, increase this for better RPM resolution,
//decrease for faster update
rpm = 30*1000/(millis() - timeold)*rpmcount;
timeold = millis();
rpmcount = 0;

void rpm_fun()
//Each rotation, this interrupt function is run twice

This code was taken from the previously mentioned ReadingRpm on the Arduino:Playground.

I am using a 4n26 Opto chip Génie des systèmes | ÉTS Montréal

I can insert a bit of code to control the fan speed with a pot and it works very well. When i have to pot maxed out, ie 255 then the RPM is accurate again.

The hall sensor in the pc fan does not work if there isn't any power (the off part of the pwm).

I've played with various 'solutions';

  • give pwm off 255, count some (20 or so)hall sensor ticks, return to previous pwm setting, keep track of the time it took.
    Works well but with acceleration while reading. With very low rpm's the speedup actually keeps the fan from stalling. Got a 1400 rpm fan down to 40 rpm while reading.

  • Doing a digitalRead from the hall pin at the moment there is power (the on part of the pwm) using the TOVn interrupt (Interrupt on Bottom).
    This works fairly well for rpm's above 1000 upto 11000 (small 6500rpm fan with blades broken off). Problem i had is with lower rpm's. The hall signal doesn't go low enough to sense a low on the arduino.

Hope this gives some help.


You might need to do some signal conditioning to the hall signal. If you can get access to a scope that would help. You might be able to use a schmitt trigger to clean up the waveform. There are optocouples with them built in but you may need to make one from an op-amp based on what the scope tells you.