High Frequency Counter with Arduino

 Here it is shown how to build a high frequency counter with Arduino and LM311 comparator to measure the frequency of a signal. The frequency counter shown here can measure frequency upto and above 6MHz which is quite high. There are several methods which can be used to build a frequency counter like using the input capture feature of Arduino(see Programming ATmega328p Input Capture) but they don't yield such high frequency measurement capability. This design uses counter to count the signal input waveform or pulses. It can measure of all kinds of waveforms like square wave, sine wave, sawtooth, triangle signals. The signal frequency measurement is important in electronics circuit design and such a DIY frequency counter could be helpful to many.

Arduino Frequency Counter

The circuit diagram of the frequency counter.

 Arduino with LM311 frequency counter circuit diagram

The Arduino frequency counter is based on measuring the number of pulses or count using the timer 1 T1 pin which is for Arduino Uno located at pin 5(PD5). It means that the Timer 1 is setup as counter which measures external events. The frequency of the signal to be measured is applied via 0.1uF capacitor at noninverting terminal pin 2 of the LM311 comparator. Here LM311 was used because it is a fast comparator. One can also use LM393 comparator or uA741 operational amplifier configured as comparator. When the signal input is higher than 0V then around 5V is output from the comparator and when the signal is lower than 0V then 0V is output from the comparator. The output appears at pin 7 which is then feed into the pin 5 of Arduino via the 6.8KOhm resistor. The output is also pulled up using a 10KOhm resistor. The LM311 actually is also performing voltage level shifting. The input signal amplitude can be low in milli volts range. The LM311 takes in that low voltage and outputs high level signal which can be detected by Arduino input pin. The frequency remains unchanged.

The following shows animation of how this Arduino frequency counter works.


In the above animation of the frequency counter, a signal generator applies signal of different amplitude and different frequency to the LM311 comparator whose output is connected to the Arduino pin 5. In the animation, there is missing 10KOhm and 6.8KOhm at the output pin 7 of the LM311 comparator. These resistors are necessary. See the connection in the circuit diagram shown above.

The program for the Ardiuno Frequency Counter is as follows.

#include <FreqCounter.h>
#include <LiquidCrystal.h>
#include <stdlib.h>

#define countdelay 1 // measurement delay
#define calibration 0 // adjusts frequency for variation in Arduino
#define gatetime 100 // gate time in milliseconds
#define onems 1000 // alias for 1000 milliseconds

LiquidCrystal lcd(12, 11, 9, 8, 7, 6); // setup the LCD interface pins
char units[][5] = {"Hz", "KHz", "MHz"};	//units of frequency to be used later

void setup(){
	lcd.begin(16,2); // initialize the LCD
	lcd.print("** Frequency **"); //initial message
	lcd.setCursor(0,1);
	lcd.print("**  Counter  **");
	delay(100);	//100ms startup delay
}

void loop() {
	char Freq[16];	//to store frequency
	unsigned long Fcalc=0;
	float Fval;
	FreqCounter::f_comp=calibration; // calibrate with known source
	FreqCounter::start(gatetime); // count pulses for specified gating period
	while (FreqCounter::f_ready == 0)
		Fcalc = FreqCounter::f_freq;
		delay(countdelay);
		Fval = (float) Fcalc * (onems / gatetime); // scale the input
		lcd.clear();
		lcd.setCursor(0,0);
		lcd.print("Freq.:");
	
		//check and display in frequency correct units
		if(0 <= Fval && Fval < 1000){
			dtostrf(Fval, 3, 2, Freq);
			strcat(Freq, units[0]);
                        lcd.setCursor(0,1);
			lcd.print(Fval);
			lcd.print(units[0]);
		}
                else if(1000 <= Fval && Fval < 1000000){
			Fval = Fval/1000;
                        dtostrf(Fval, 3, 2, Freq);
                        strcat(Freq, units[1]);
                        lcd.setCursor(0,1);
                        lcd.print(Freq);
		}
		else if(1000000 <= Fval){
			Fval = Fval/1000000;
                        dtostrf(Fval, 3, 2, Freq);
                        strcat(Freq, units[2]);
                        lcd.setCursor(0,1);
                        lcd.print(Freq); 
		}
		else{
			lcd.setCursor(0,1);
			lcd.print("Out of Range");
		}
}

In the program code above, we have used the FreqCounter(FreqCounter.h header) library which you can download at the following url:

https://github.com/Arduino-IoT/libraries/tree/master/FreqCounter

We have used the #define to use alias name for some of variables required later in the program. A 16x2 LCD is used here to display the frequency and to use the LCD we have used the LiquidCrystal library. In the setup() we have initialiated and started the LCD library. Then we print out some initial message.

In the main loop() we start with calibration of the frequency counter library. Here calibration is done such that a known frequency is applied to the frequency counter. Using this known frequency calibration of timing is done internally by the frequency counter library. Then frequency counter is started with a certain gate time which is 100ms here. The gate time is the time over which sampling of the input signal is done. After this the frequency is calculated and then the frequency measured is scaled properly to get frequency in Hz. Using if else statement the measured frequency count is displayed in Hz, KHz or MHz.

Testing of Frequency counter

Here Arduino Mega frequency generator described in earlier tutorial Arduino 8MHz Signal Generator with ISR is used to generate signal and fed that signal into this Arduino Uno frequency counter. 

The connection is as shown.

frequency measurement with Arduino frequency counter

In the above diagram, the potentiometer on Arduino Mega is rotated to change the frequency of square wave which appears at Pin 13. This pin 13 of Arduino Mega is connected to the LM311 via the coupling capacitor.

The following video demonstrates how the above Arduino mega function generator with Arduino Uno frequency counter works.

Here we have used Arduino Uno Timer 1 in counter mode to measure the frequency of a signal with arbitrary amplitude. Another method suitable to measure frequency of a signal with Arduino is using the input capture method. This is explained with code in Programming ATmega328P Input Capture with Interrupt

Also if you want DIY home electronics testing tools then see the following tutorials.

DIY LCR meter using PC

- High Frequency Counter with Arduino

- Arduino 8MHz Variable Frequency Generator  

- How to use Matlab Simulink as Oscilloscope 

- Arduino UNO sine wave generator

 

6 Comments

Previous Post Next Post