Test InstrumentationEnter Your Electronics & Design Project for a chance to win a Grand Prize for Originality, a Tool Set, and a \$100 Shopping Cart!Back to The Project14 homepage Project14 Home Monthly Themes Monthly Theme Poll

Arduino or any other controller need TTL signal levels at input to count pulses and only work with square wave.

So what if we want to find out the frequency of sine ,triangular or low voltage square wave?

We can solve this problem with the help of comparator IC like lm339 which can operate down to 2V (Fig. 1) and also we can use separate power supply to power up the IC and use TTL voltage to pull up the output of comparator. (FIG. 2)

FIG. 1

FIG. 2

If we look at arduino UNO R3 specification we can find that it has 3 timers TMR0 (8-bit), TMR1 (16-bit) and TMR2 (8-bit) also shown in block diagram of ATmega 328P (FIG. 3). And Only TMR0 and TMR2 can be used as input.

TIMERArduino IO - pin
TMR0IO - 4 (INPUT)  IO - 5 & 6 (OUTPUT)
TMR1IO - 5 & 8 (INPUT)  IO - 9 & 10 (OUTPUT)
TMR2IO - 3 & 11 (OUTPUT)

We can use use either TMR0 or TMR1 as frequency Input. To choose the best option between these two timers we can opt TMR1 as input because it is 16-bit. And use other two timers in cascading to calculate elapsed time for better accuracy. (After editing TMR1 setting we cannot use millis and micro)

FIG. 3

Connect the arduino UNO with 16x2 LCD as shown in FIG. 4.

FIG. 4

We can use TMR0 and TMR2 to generate 1 second time. To use both timer we have to physically link the output of TMR2 to TMR0. (IO - 3 to IO - 4). The Arduino record the no of pulses at TMR1 input (IO - 5) for 1 second, for each time if TMR1 overflow during 1 second record time the overF variable is incremented by 1. After recording number of pulses for 1 sec it calculate the frequency and time period of input signal.

```#include <LiquidCrystal.h>

byte overF=0;
unsigned long freq;
double period;

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(12, 11, A2, A3, A4, A5);

// the setup function runs once when you press reset or power the board
void setup() {

lcd.begin(16, 2);   // set up the LCD's number of columns and rows:

//4*250 = 1000 ms - timer0
OCR0A = 249;
TCCR0A = _BV(WGM00) | _BV(WGM01); // (Normal port operation, OC0A disconnected.)
TCCR0B = _BV(WGM02) | _BV(CS02) | _BV(CS01);  //  Fast PWM mode, input T0 pin D4 (External clock source on T0 pin. Clock on falling edge.)

//4 msec - timer2
OCR2A =249;
OCR2B = 125;
TCCR2A = _BV(COM2B1) | _BV(COM2B0) | _BV(WGM21) | _BV(WGM20);  //output B in phase, fast PWM mode (Set OC0B on compare match, clear OC0B at BOTTOM, (inverting mode))
TCCR2B = _BV(WGM22) | _BV(CS22) | _BV(CS21); // set prescaler to 256 and start the timer
pinMode(3, OUTPUT);

//  counter input T1 pin D5
OCR1A = 32767;   //32768 counts
TCCR1A = _BV(WGM10) | _BV(WGM11); //   Fast PWM Mode (Normal port operation, OC1A/OC1B disconnected)
TCCR1B = _BV(WGM12) | _BV(WGM13) | _BV(CS12) | _BV(CS11); //input pin D5 (External clock source on T1 pin. Clock on falling edge.)

lcd.setCursor(7, 0); // top middle
lcd.print("hi");

}

// the loop function runs over and over again forever
void loop() {

//wait for 1-sec
TIFR0= _BV(OCF0A);
while(!(TIFR0 & (1<<OCF0A)));

TIFR1 = _BV(OCF1A);    //reset TMR1 overflow flag
OCR1A = 32767;
TCNT1=0;
overF=0;
TIFR0= _BV(OCF0A);
TCNT2=0;
TCNT0=0;
//start the count
while(!(TIFR0 & (1<<OCF0A))){
if(TIFR1 & (1<<OCF1A)) {++overF; TIFR1 = _BV(OCF1A);}   //overflow
}
//count end
freq = (unsigned long)TCNT1 + ((unsigned long)overF * 32768);
period = 1000000 / (double)freq;
if(freq == 0){period=0;}
overF = 0;
lcd.clear();
lcd.setCursor(3, 0); // top line
lcd.print(freq,DEC);
lcd.setCursor(11, 0);
lcd.print("Hz");
lcd.setCursor(3, 1);
lcd.print(period,DEC);
lcd.setCursor(10, 1);
lcd.print(" uS   ");
}

```

Source of Arduino Code: An Arduino Uno 6 MHz Frequency Counter with LCD

Test Instrumentation