# Measuring frequency of 3-wire 12V fan on Arduino Uno

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() {
Serial.begin(9600);
pinMode(pin, INPUT);
}

void loop()
{
duration = pulseIn(pin, HIGH);
Serial.print(duration);
delay(1);
}
``````

My schematics:

• 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;
``````