A more complex method is reciprocal counting.
Frequency is defined as (Number of events) / (time in seconds) and measured in Hz.
To make calculations trivial using a 1 second gate time (T) gives a direct reading of frequency from the edge counter.
Making a frequency counter for frequencies up to 65.536kHz is easy as the counters in a PIC chip can count up to 65535 without overflowing.
Up to 65.535kHz all you do is wait for 1 second while the count accumulates, read the value and display it. It will be the frequency in Hertz. Above 65.536kHz you have to monitor the overflow value while at the same time making an accurate delay time (T).
Note: Using a 1 second measurement period results in the frequency counter count value being a direct measurement of frequency requiring no further processing. It also means that the measurement is resolved to 1Hz. (Increasing T to 10s resolves to 0.1Hz while using T=0.1s gives a resolution of 10Hz).
For the following projects the crystal oscillator (of the microcontroller) is used as the timebase. In these projects measurement of T (set at one second) is made by executing a delay that takes a set number of machine cycles.
Using a 4MHz oscillator gives a machine cycle of 1MHz (a period of 1us) which makes calculating and setting time delays fairly easy since most PIC instructions execute in one machine cycle. So executing 1,000,000 of these cycles gives a delay of 1 second.
The accuracy of the frequency counter depends on the accuracy of the crystal driving the microcontroller.
This is specified in ppm or parts per million. Its actually quite simple: taking an example of ±50ppm for a 4Mhz crystal. The error that the crystal could have (assuming that the crystal is loaded with the correct capacitance) will be in the range :
Maximum possible error 4MHz + (4MHz x 50 x 1e-6) = 4.0002e6
Maximum possible error 4MHz - (4MHz x 50 x 1e-6) = 39998e6
So the crystal could oscillate at any frequency between 4000200Hz and 3999800Hz. Note that this frequency can be changed (a bit) by changing the loading capacitance on the crystal i.e. you can calibrate it.
The delay time is the important measurement so for the above crystal at fosc/4) for the cycle time of the PIC chip (nominally 1MHz) we have:
Max cycle time : 1/(1.00005e6) or 1/(1MHz + 50ppm)
Min cycle time : 1/(0.99995e6) or 1/(1MHz - 50ppm)
Multiply by 1e6 to give a 1 second period gives the delay time
Min delay time : 1e6/(1.00005e6) 0.99995s or (1s - 1s x 50ppm)
Max delay time : 1e6/(9.9995e6) 1.00005s or (1s + 1s x 50ppm) seconds.
So you don't have to calculate all the intermediate steps just use the ppm value directly.
Note: If you have a reference oscillator that is more accurate than the crystal used in the frequency counter project then you can calibrate the project crystal. You can do this by adjusting a variable capacitor on one side of the crystal oscillator circuit while reading the output frequency displayed. If you don't have a reference then just use a fixed capacitor to give the correct parallel load capacitance for the crystal you use.
Commonly available crystals have a ppm specification of ±30ppm to ±50ppm (part per million error) but you can buy crystals with a ppm of ±20ppm. The smaller the ppm value (the smaller the error) the more accurately you can measure frequency.
Note: The temperature coefficient is about ±50ppm unless you use a watch crystal which has a temperature coefficient of 0.034 ±0.006ppm/ºC. If the temperature does not change much then this will not affect the accuracy e.g. where the temperature controlled in a building or where the watch is worn i.e. your body temperature is acting as an temperature controller!
There are two other accurate systems that are usually very expensive,
certainly for extreme accuracy requirements these cost more money (and use more
power, and take up more space).
Temperature controlled Crystal Oscillator
These are simply crystals located next to a heat source and sensor to try and maintain a relatively constant temperature - sealed in a package.
Oven controlled Crystal Oscillator
Because they are so accurate a different measurement is used i.e. instead of ppm (parts per million) they use (ppb) parts per billion.
They use a chamber that is heated to a constant temperature regardless of the outside temperature and allows the electronics (and crystal) inside to operate with the most accurate output that you can get using a crystal.
Consequently OCXOs are very expensive.
Parameters to look out for are warm-up time (since it contains a heater it takes a few minutes to reach the correct temperature) therefore equipment can not be used immediately you turn it on.
|Type||Accuracy (ppm/ppb)||Accuracy||Aging /
|Aging / 10 Year|
|Crystal||10ppm-100ppm||10-5 - 10-4||10-20ppm||10x10-6|
|Rubidium Atomic||1x10-6ppm (0.001ppb)||10-12||0.005ppm (5ppb)||5x10-9|
Note: You will also come across another parameter : Aging which describes the change in frequency over time due to aging components. There is also drift over time. It can get very complicated and for the adventurous this site (febo.com) has useful information on these aspects of frequency stability.
Note: A new ultra accurate OCXO is available from IQD
(±0.2ppb OCXO) i.e. 100 times better than the above normal accuracy.
There are other ways of getting an accurate clock into a circuit e.g. use one belonging to someone else:
There are two requirements
Timer 1 is ideal for frequency measurement (counting edges) as it functions as a 16 bit counter taking its input directly from a port pin.
You could use Timer 0 if timer 1 is not available. The only difference is that Timer0 is an 8 bit counter (enhanced to 16 bit in 18F parts).
The maximum count for Timer one is 65535 with one more count setting the overflow flag (the timer then reads zero again). Counting the number of overflows gives the count in multiples of 65536 and reading the value of TMR1 at the end will give the total edge count over the period of measurement - T.
There are two ways to measure time.
The current design of the LCD frequency counter uses Timer 1 as the event counter and Timer 0 as the time counter. Using the LCD provides a fairly easy way to display the result as high level languages usually include drivers for the LCD. Using the LCD does not require any special techniques and it can be updated quickly.
It works as long as you don't miss an event (not too fast interrupts to Timer1 - but it can handle quite fast signals). Since the Overflow is for a 16 bit timer actual interrupts to the processor are slow anyway.
Time is counted using the 1MHz internal clock at 256 overflows (Timer 0) so that is not too fast either.
You can find the lcd counter project here.
This method is not recommended but it does work. Since the processor takes a defined time for each instruction you can create any delay that you want.
If you create a delay of one second then the number of events counted within that delay will be the frequency in Hz. You can see this method used in designs on the web that use the 16F84 (that only has 1 timer - Timer0). See also the 7segment display driver and frequency counter.
The 2nd project uses several Seven segment displays providing an 8 digit output which is far more complex to drive but it is so much more satisfying than the LCD display.
You can find the seven segment led counter project here.
To display numbers on multiple 7 segment displays you rely on persistence of vision (a way of describing how your eye perceives light).
With a single 7 segment display you can wire all its connections directly to the microcontroller and you need a total of 8 connections, with 2 segments you need 16 connections and with 8 segments you need 64 connections.
Obviously most microcontrollers don't have 64 pins so you need a different method.
The answer is to use multiplexing which is a way of recycling pins. All the seven segment displays are connected to the same 8 bit port. Then the displays are multiplexed i.e. each display is turned on for a short period of time and then off. You usually switch the seven segment display on by turning on a transistor connected to the common cathode (ground) of the display. When the transistor is on all the LEDs are enabled - the corresponding LED lights up when a bit in the 8 bit port is high.
The following example shows four multiplexed seven segment displays using only 12 pins (without multiplexing you would need 32 pins).
To make the illusion that the LEDs are on all the time the LEDs must be refreshed faster than your eye notices. You need to refresh the display at about 50Hz relying on persistence of vision i.e. the image you see does not need to be constant as long as it is repeated quickly enough.
The trick with driving the multiplexed display for the frequency counter application is that the multiplex routine must work in a constant time. The delay period T can then incorporate refreshing the seven segment display. The constant time is needed in the same way that it is needed for polling the overflow flag of timer 1 (see earlier).
Jump from frequency counter to
Best Microcontroller Projects Home Page.
Find out how to use the AD9833 to generate sine, square and triangle waves at 0.1Hz resolution.
Arduino Nano ISP: How to program an ATmega328P using an Arduino Nano as the ISP programmmer. One common problem: Programming a sketch into the chip without a reset control - solved here.
Arduino Voltage reference: Both the Uno and Nano have a built-in voltage reference: Find out how to make it more accurate. In addition find out how to use it to measure the supply voltage 1V8 ~ 5V5
Arduino EEPROM: How to use it and How to preserve the life of EEPROM. Two examples sketches to save multiple values to EEPROM.
A tutorial on using the ADS1115 precision 16 bit ADC for low power use.
Learn how to use the TP4056 properly. There's a right, and a wrong way, to use it to safely charge Lithium Ion batteries.