Friday, November 27, 2015

Measuring frequency with Arduino

by / Wednesday, 02 March 2011 / Published in Arduino

arduino megaThere are many signals that contain necessary information in frequency. For instance, SparkFun's HH100D humidity sensor outputs measurements via frequency signal (although it has i2C interface, those pins are used for reading calibration values. Actual measurements com via FOUT line).


There are two ways to measure a frequency with Arduino:

  • Using FreqCounter library. It can measure frequencies up to several MHz, and is very precise. However, measurement pin is fixed to digital pin 5. Also it may affect Arduino PWM outputs, increasing their duty cycles. In case you don't use PWM and you need to measure frequency of just one signal, FreqCounter is an excellent choice
  • Using pulseIn() function from standard Arduino libraries. The technique I'm suggesting below is free from FreqCounter limitations, so you can use it on any pin. However, it's minimal wave period is 10 uS, with corresponding maximum measurable frequency of 50 kHz

Here you can find
 official documentation for pulseIn() function.

PulseIn function returns the length of the pulse (in microseconds) or 0 if no pulse started before the timeout. To get the frequency you can use f = 1 / T equation, however, that depends on duty cycle of the signal.

We suggest that we have a square wave with 50% duty cycle, and measure the length of the pulse by using pulseIn function. Then we will multiply that value for 2 to obtain signal period: (the distance between red lines on the image):


To get frequency in Hz for a 50% square wave you can use 

freq = 500000/pulseIn(5, LOW);

Notice the value of 500 000 uS instead of 1 000 000 uS (= 1 second), because I need to use signal's period (T) in the formula, not pulse length(tpulse) that pulseIn returns.
With duty cycle of 50% signal period will be T = 2*tpulse, so the formula will finally look like
f = 1second / ( 2*tpulsemicroseconds) = 500 000 microseconds / tpulse = f Hertz


However, using pulseIn has several peculiarities that you need to consider.

The first one is the necessity of obtaining average values.

Most people usually take only one measurement with pulseIn() function. In many cases, frequency is not very stable, so we need to calculate an average value over time.

Something like 1024 samples will be enough, however, for better results, you may increase the value - even up to 20-30k samples (however, in case with HH100D sensor, there's almost no difference in frequency for 4096 and 32767 samples).

 Use this function to get more accurate frequency value:

long getFrequency(int pin) {
  #define SAMPLES 4096
  long freq = 0;
  for(unsigned int j=0; j<SAMPLES; j++) freq+= 500000/pulseIn(pin, HIGH, 250000);
  return freq / SAMPLES;

We wait for the pulse to occur in 250 mS. If you are using very slow signals, increase this value as you need. (pin, HIGH, 250000)


The second peculiarity is lesser precision than FreqCounter library can provide.

I recommend using FreqCounter, and switch to pulseIn only in cases when FreqCounter is unavailable.
As an alternative, you can increase accuracy of you pulseIn measurements even more. Read this article to learn how to do this.


Read 2436 times Last modified on Saturday, 21 March 2015 10:58

Do you like this? Please share!

Simon Tushev

Simon is IT professional with interests in web design, electronics, photography and astronomy. He writes about PHP, Yii, Joomla!, Arduino and several other topics.


Here I publish articles related to my areas of interest, my brief notes that may save some time to others, as well as some of my works.

This site is a work in progress. I will add more sections in the future, such as

  • More photos to photogallery
  • More Joomla!-related articles
  • ...



New Posts

Visual difference between pseudo and true random data

This is is "random" image generated using PHP rand() function: And this is an image...

20-11-2015 in Blog


Best EEPROM practices

(this article is a work in progress). My own advice will be added later...   Having...

12-10-2015 in Arduino


nginx - solve 'An existing connection was forcibly closed by the remote…

If you run nginx on Windows (for development purproses, for instance), you may often...

09-10-2015 in Blog

Scroll to top

We use cookies, just to track visits to our website, we store no personal details Privacy policy