Go Down

Topic: Frequency Counter Library (Read 49821 times) previous topic - next topic


I use the frequency library on both Mega ADK ( modified library)  and Nano board.
When i measure a precise 1.000.000 Hz signal I get 1.000.169 on the display.
I try to correct this with f_comp but it seems that i can only increase the displayed reading.
How can I decrease the reading to 1.000.000 ??

Thanks for a nice frequency library. Very usefull.


Hello dc42.

I just tested your improved version of a frequency counter sketch (Reply#35).
http://forum.arduino.cc/index.php?PHPSESSID=25artcic6a44jl71kf4a1kevo7&topic=64219.30 .
It works great!. Is is possible to modify it to read frequencies between 1Hz to 3Hz. So far, I can measure with your code frequencies over 2.99Hz.

Thank you.


Can I detect a guitare sound frequency with it?


Can anyone help me?

I have a bipolar signal from 40mVp to 4Vp (it has 2Kohm impedance too as it comes from an inductance). I want to measure his frecuency. I tried all configurations possible withouth succesful.

My first approach was plug into V+ and V- in an operational with open loop (so i have an square output and a single edge detector with a timer will measure). The output is not consistent due to the small voltage of the signal i guess.

I tried a transistor with the signal attached to the base and collector so it enables. It does not work either. The solution with the biestable is not possible due to the small Voltage of the signal when low frecuencies.

Thanks in advance.

Mladen Bruck

Jun 07, 2014, 01:38 am Last Edit: Jun 07, 2014, 01:40 am by Mladen Bruck Reason: 1

I'm trying to measure frequency, and display always return on decimal place less. It should show 26640, but show only 2664. I also tryed to increase/decrease frequency, but same error occur.

I'm using FreqCounter library.  

This is the code:

Code: [Select]
#include <FreqCounter.h>

unsigned long frq;
int cnt;
int pinLed=13;

void setup() {
  pinMode(pinLed, OUTPUT);

  Serial.begin(115200);        // connect to the serial port

  Serial.println("Frequency Counter");

void loop() {

  // wait if any serial is going on
  FreqCounter::f_comp=10;   // Cal Value / Calibrate with professional Freq Counter
  FreqCounter::start(100);  // 100 ms Gate Time

  while (FreqCounter::f_ready == 0)

  Serial.print("  Freq: ");
  digitalWrite(pinLed,!digitalRead(pinLed));  // blink Led


Please help !

BR !



while (FreqCounter::f_ready == 0)

is this really what you meant  ?
or is the  ;   missing

while (FreqCounter::f_ready == 0) ;

the difference is effectively a different loop

while (FreqCounter::f_ready == 0)


while (FreqCounter::f_ready == 0)  {}
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Mladen Bruck


I didn't notice missing ; since compiled without error.  But I have found yet another post with similar problem. I'll try your both proposal.   Thank you.

There is a workoround for use with servo library?

I have not yet tried this code yet, so if it doesn't work I am sorry!  When I thought of a workaround, I was thinking external.  I found the liked below chip on adafruit that takes an I2C signal and can create PWM without using the AtMel's PWM.  As long as the communications clock is not disabled or messed up, something like this might work for you. 



I am trying to make that library work with the leonardo / Micro but can't figure it out. I replaced the code below in the FreqCounter.cpp found here : http://interface.khm.de/index.php/lab/interfaces-advanced/arduino-frequency-counter-library/

Does anybody actually ever sucessed to measure frequency using TIMER 3 on a Leonardo?

Now the library also works for leonardo
Code: [Select]
#include "FreqCounter.h"

volatile unsigned long FreqCounter::f_freq;

volatile unsigned char FreqCounter::f_ready;
volatile unsigned char FreqCounter::f_mlt;
volatile unsigned int FreqCounter::f_tics;
volatile unsigned int FreqCounter::f_period;
volatile unsigned int FreqCounter::f_comp;

void FreqCounter::start(int ms) {

#if defined (__AVR_ATmega32U4__)

    f_ready=0;                  // reset period measure flag
    f_tics=0;                   // reset interrupt counter
    if (f_comp ==0) f_comp=1;  // 0 is not allowed in del us

    // hardware counter setup ( refer atmega32u4)
    TCCR1A=0;                  // reset timer/counter1 control register A
    TCCR1B=0;                 // reset timer/counter1 control register A
    TCNT1=0;               // counter value = 0

    // set timer/counter1 hardware as counter , counts events on pin T1 ( arduino leonardo pin 12)
    // normal mode, wgm10 .. wgm13 = 0
    TCCR1B |=  (1<<CS10) ;//CLOCK ESTERNO su fronte di salita
    TCCR1B |=  (1<<CS11) ;
    TCCR1B |=  (1<<CS12) ;
    // timer0 setup / usato per la generazione del tempo di lettura
    // timer3 presaler set to 256 / timer3 clock = 16Mhz / 256 = 62.500 Hz
    TCCR0B = (1<<CS02);

    //setta il timer0 to CTC(Clear Timer on Compare)  Mode with OCR3A is top counter value (arrivato a OCR3A si resetta)
    TCCR0A = (1<<WGM01);  // CTC mode, normal (no Output compare)
    GTCCR |= (1<<PSRASY);  // reset prescaler (undocumented bit in mega32u4?)
    TCCR0B = (1<<CS02);  // timer0 on clk/256 == 16MHZ / 256 = 62500hz..
    OCR0A = 124;  // 125 counts of 62500 Hz before an output compare interrupt...

    TCNT1 = 0;
    TCNT0 = 0;

    TIMSK0 = (1<<OCIE0A);

//  Timer3 Interrupt Service is invoked by hardware Timer3 every 1ms = 1000 Hz
//  16Mhz/256/124 = 500 Hz (corretto con il dimezzamento del period)
//  here the gatetime generation for freq. measurement takes place:

// multiple 2ms = gate time = 100 ms
if (FreqCounter::f_tics >= FreqCounter::f_period) {         
                            // end of gate time, measurement ready

    // GateCalibration Value, set to zero error with reference frequency counter
    //  delayMicroseconds(FreqCounter::f_comp); // 0.01=1/ 0.1=12 / 1=120 sec
    TCCR1B = TCCR1B & ~7;    // Gate Off  / Counter T1 stopped
    TIMSK0 &= ~(1<<OCIE0A);    // disable Timer3 Interrupt(timer del gate)
    //TIMSK0 |=(1<<TOIE0);      // enable Timer0 again // millis and delay
    FreqCounter::f_ready=1;             // set global flag for end count period
                                        // calculate now frequeny value
    FreqCounter::f_freq=0x10000 * FreqCounter::f_mlt;  // mult #overflows by 65636
    FreqCounter::f_freq += TCNT1;      // add counter1 value
    FreqCounter::f_tics++;            // count number of interrupt events
    if (TIFR1 & 1) {          // if Timer/Counter 1 overflow flag
    FreqCounter::f_mlt++;               // count number of Counter1 overflows
    TIFR1 =(1<<TOV1);        // clear Timer/Counter 1 overflow flag

Go Up