Frequency Meter with 74HC4060 Prescaler

There are a number of HF capable frequency counters that use an Arduino, but most rely on one of the many slightly different version of #include <FreqCounter.h>

This frequency counter is different because it uses a pre-scaler and timing is based on the Arduino's own internal Epoch counter. The Epoch counter is a continuous running clock inside an Arduino that can be accessed with the "micros()" command and returns the number of microseconds since the Arduino was restarted. This clock on a 16 MHz Arduino wraps around to zero after approximately 70 minutes, so the software needs to test for wrap and handle it appropriately. For best accuracy it is best to use an Arduino that has a real crystal oscillator instead of the more popular ceramic resonator based clock oscillator.

Purpose of the 74HC4060 as a pre-scaler is two-fold. (1) The input gate serves as a signal conditioner, and (2) it provides division by up to 2^14 which is division by 16384. Other outputs of this ripple counter chip provide division by smaller factors. If you make the division too small there will not be enough milliseconds caught between interrupts for reliable conversion to frequency. Starting with a division factor of 4096 seems an appropriate place to start for a 7 MHz signal input.

[ Schematic Goes Here ]

---- CODE START ----

/* arv_counter

* uses an Arduino with divide-by-N prescaler and interrupts to measure

* time between input cycles. Then the calculated frequency is multiplied by

* the prescale value and any IF Offsets are included in the calculations.

* Resulting frequency indication is shown on an attached 1602 type LCD and

* sent to a serial/USB terminal if one is connected.

* It is recommended that the Arduino use a real crystal oscillator instead

* of the ceramic resonator that is common in most Arduino boards.

* The "compensate" variable is used to add an offset if your Arduino clock

* oscillator is slightly off-frequency. It can be negative or positive.

*

* 2017 Arv K7HKL

*

* This is example code, and as such is in the public domain. You can

* use it for free. It would be nice if you credit me with the code

* base, but not really mandatory. I don't drenk beer, but if we ever

* meet, a cup of coffee would be appreciated. 8-)

* =================================================================

*/

#include <LiquidCrystal.h> // assume that we have an LCD display

LiquidCrystal lcd(7, 8, 9, 10, 11, 12); // setup LCD interface pinout

long int f, freq, frequency;

long int compensate = 0; // positive or negative value to improve epoch clock accuracy

long int prescale = 4096; // division value of prescaler, set to "1" if no prescaler

long int offset = 0; // IF offset in Hz, if any. Probably BFO frequency.

long int p, oldp; // p = microseconds between interrupts. oldp = prior value of p.

void setup() {

Serial.begin(57600); // set your ttl/USB monitor for "57600" data rate.

lcd.begin(2, 16); // activate the 1602 type LCD

attachInterrupt(0, isr, FALLING); // Pin D2 (INT0) trigger to get periods

} // each time INT0 triggers it calls the ISR to calculate and display frequency.

// This means that the frequency counter is driven by interrupts and does not

// need to be put inside loop() for continuous running. Neat stuff! 8-)

void isr() { // interrupt handler uses epoch clock to measure period of input cycles

p = micros(); // read epoch clock

if (p > oldp) { // use this sample unless epoch count has wrapped

p = p + compensate; // include compensation for Arduino clock inaccuracy

oldp = p; // make this p the new oldp for next p sample

f = 1000000 / p; // convert period to frequency

frequency = f * prescale; // factor in prescale value

frequency = f + offset; // include any IF offset

lcd.print(frequency); // show frequency on LCD

Serial.println(frequency); // show frequency on serial monitor

} // all the frequency counter work is done via this ISR and is driven by INT0.

}

void loop() { // this space is available for H&P stabilization and metering functions

}

---- CODE END ----