I am using a PC 12V fan (40x40mm), which I control speed with voltage (with adjustable power supply). I would like to measure the frequency of the fan with Arduino and read it on serial monitor.

I've googled over some results and I came across pulseIn(), which I don't quite understand. I've also used this code, which I found here, but it doesn't work for me. I've added serial.print and delay line.

My output of this program is: "0000000" etc. and nothing else.

My goal is to set the frequency of the fan to around 50-500 Hz somewhere.

int pin = 7;
unsigned long duration;

void setup() {
  pinMode(pin, INPUT);

void loop()
  duration = pulseIn(pin, HIGH);

My schematics:

enter image description here

  • Edited. I hope it helps. I power supply arduino through USB cable from PC and instead of battery I just use variable bench power supply.
    – Jakey
    Dec 18 '17 at 12:16
  • Thanks. Try changing pinMode(pin, INPUT); to pinMode(pin, INPUT_PULLUP); and tell us what happens. If it works, I'll write an answer explaining why.
    – Mark Smith
    Dec 18 '17 at 12:21
  • @MarkSmith: Yes and no. But this is a step further for sure. Yes: I do get values from arduino, but not some kind of useful. No: As I raise the voltage (and raise the turning speed) the lower values I get by reading the input. At about 4.85V I got the value of 2800, but at voltage 2.48V I get value of 5740 (about). How can I get RPMs from this?
    – Jakey
    Dec 18 '17 at 12:29
  • You should not connect the ground wire to the other side of the potentiometer! That will just waste energy.
    – Gerben
    Dec 18 '17 at 16:25

The pulseIn measures the duration of a high pulse on the pin. The reference page explains it as well as I ever could. If there is a specific thing you don't understand from it, please ask. However, I don't think it will achieve what you want.

The circuitry in the fan connects the third (yellow?) wire to ground twice per revolution of the fan. To make this into a "pulse" you need to pull the pin high. Twice per revolution, the fan will pull it low.

What you now have is a signal which, for every revolution of the fan, goes HIGH, LOW, HIGH, LOW. We want to measure the time from one rising edge to the next. This is the time for half a rotation of the fan.

Here's some untested code:

// Wait for signal to go low
while (HIGH==digitalRead(pin)) { /* Do nothing */ }

// Start timing
unsigned long start_time = micros();

// Wait for signal to go high and low again
while (LOW==digitalRead(pin)) { /* Do nothing */ }
while (HIGH==digitalRead(pin)) { /* Do nothing */ }

// Stop timing
unsigned long end_time = micros();

// How long did that take?
unsigned long duration  = end_time - start_time;

That code can be improved in various ways but I hope it will let you understand what's going on.

That tells us how LONG half a cycle takes. You can easily find how long a whole cycle would take -- double it. If you want the frequency in revolutions-per-minute, you need to work out how many whole cycles you can get in a minute, which is the same as the number of half-cycles in half a minute:

unsigned long rpm = 30000000L / duration;

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.