This is the header file: #ifndef FreqCounter_h #define FreqCounter_h #include #if defined(ARDUINO) && ARDUINO >= 100 #include "Arduino.h" #else #include "WProgram.h" #endif namespace FreqCounter { extern volatile unsigned long f_freq; extern volatile unsigned char f_ready; extern volatile unsigned char f_mlt; extern volatile unsigned int f_tics; extern volatile unsigned int f_period; void start(int ms); } #endif This is the source file: #include 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; void FreqCounter::start(int ms) { f_period = ms; GTCCR = (1< TOV1 flag set at TOP = 0xFFFF TCCR1A &= 0x00; //reset TC1 control register A TCCR1B &= 0x00; //reset TC1 control register B //set TC1 to use external clock source, clocked on rising edge TCCR1B |= (1< counter cleared on reaching TOP TCCR2A |= (1< set value of OCR2A = TOP OCR2A = 124; //TOP is reached every 125 counts (starting from 0) //set TC2 to use a prescaler of 1 => 16MHz / 128 = 125kHz TCCR2B |= (1< triggered on reaching TOP = OCR2A TIMSK1 |= (1< triggered on reaching TOP = MAX = 0xFFFF GTCCR &= 0x00; //restart all timers => start counting } /* * This ISR is triggered by TC2 every 1ms because * TC2 increments with a frequency of 16MHz / 128 = 125KHz * and reaches TOP every 125 counts * => trigger frequency = 1kHz * => trigger period = 1ms * * This ISR handles the Gate Time generation */ ISR(TIMER2_COMPA_vect) { //increment number of TC2 interrupts (triggers when reaching TOP = OCR2A) FreqCounter::f_tics++; /* * If branch evaluates as true if given gate time (f_period) equals * amount of milliseconds TC2 has counted (= f_tics) */ if (FreqCounter::f_tics >= FreqCounter::f_period) { //end of gate time => measurement ready TCCR1B &= ~0x07; //set TC1 to no clk source => TC1 stops counting TIMSK2 &= ~(1< long frq; void setup() { //generate a 5 kHz square wave on OC0B = digital pin 5 = T1 DDRD |= _BV(PD5); //PD5 = OC0B as output TCCR0B = 0; //stop timer TIMSK0 = 0; //disable overflow interrupt OCR0A = 50 - 1; //period = 50 * 64 cycles OCR0B = 50 / 2 - 1; //50% duty cycle TCCR0A = _BV(COM0B1) //non-inverting PWM on OC0B | _BV(WGM00) //fast PWM, TOP = OCR0A | _BV(WGM01); //...ditto TCCR0B = _BV(WGM02) //...ditto | _BV(CS00) //clock at F_CPU / 64 | _BV(CS01); //...ditto Serial.begin(57600); Serial.println("Frequency Counter"); } void loop() { FreqCounter::start(1000); while (FreqCounter::f_ready == 0); frq = FreqCounter::f_freq; Serial.println(frq); }