Need advice building a frequency counter - Page 1
Forum section: electronics / projects

author: MegaWatt
author_rank: Contributor
timestamp: June 20, 2013, 08:46:12 am
content: Hello everybody, I am relatively new to electronics and have just built my own variable power supply. For my second project I am building a frequency generator but I would like to have a frequency counter in it as well. I have no experience with this matter and I am a little lost. Online I see a lot of people doing it with microcontrollers but I don't really know how to begin. I also like Dave's approach (http://alternatezone.com/electronics/freq.htm) but to be honest I am not experienced enough to understand what's going on. Can anyone of you give some advice after what I should be searching or what I should try? I want my frequency counter in the range of DC-20MHz. Thank you in advance!

author: FrankBuss
author_rank: Unknown
timestamp: June 20, 2013, 10:02:46 am
content: Nice video on the webpage. Reminds me to this:http://xkcd.com/356/Regarding your question: Dave's schematic from the page looks interesting, I have no idea how it works, looks pretty clever. But the basic concept of most frequency counters is to count the number of impulses per second, or the time between two rising (or falling) edges when the frequency is low. If you are interested in microcontroller programming, I can give you an example, because I have an (unfinished) frequency counter project with a PIC.

author: MegaWatt
author_rank: Contributor
timestamp: June 20, 2013, 11:59:16 am
content: Yes a microcontroller example would be very helpfull to me! I read somewhere that the PIC Timer0 can detect rising or falling edges, but that's as far as I have gotten

author: richard.cs
author_rank: Super Contributor
timestamp: June 20, 2013, 12:14:19 pm
content: Daves approach looks interesting but I haven't got it totally figured out yet either. The divide-1000 prescaler is obvious, but the way to two counters and the displays are multiplexed is much less so. I can tell that it displays pairs of digits in turn but and that somehow the first counter is used for 1s 10s and 100s and the second for the rest, but I think I need to stare at the 4553 datasheet for a while.Also typical fmax for the prescaler chips is closer to 60 MHz and I suspect faster versions are availiable.Edit:I think I've got it. The 4521 produces a 0.5 Hz clock, and so is low for 1s during which time the disable input of the first 4553 is low and the two counters scream along. That then goes high stopping the counting, a short time later (delayed by the 74hc132) a pulse triggers the latch on both counters, and then shortly after that a further-delayed pulse resets the counters. The internal clock of IC5 also clocks IC4 and they rotate around displaying the outputs of their 3 internal counters one by one. uite a nice circuit really, I'm tempted to build one.

author: psycho0815
author_rank: Regular Contributor
timestamp: June 20, 2013, 01:31:51 pm
content: There is an Appnote on how to do this with AVRs.http://www.atmel.com/Images/doc8365.pdf. The basic principle is pretty much the same on any microcontroller so it shouldn't be to hard to do it on a pic or whatever.cheers, Psycho

author: FrankBuss
author_rank: Unknown
timestamp: June 20, 2013, 01:58:35 pm
content: Found my project again:http://www.frank-buss.de/counter/index.htmlMore complicated than I remember, if you are new to electronics, because it uses a CPLD to measure time between events and frequency with high resolution and still work in progress without any documentation.But searching Google for frequency counter PIC results in this nice project, which looks good for beginners and which is very well documented:http://www.qsl.net/dl4yhf/freq_counter/freq_counter.htmlInstead of the DIY PIC programmer I would recommend using a PICKit, they are cheap at eBay ($20-$30).And I would use C instead of assembler. Maybe you can try to implement it in C with the program flow description which is provided on the page? I've created a small tutorial how to install and use the PIC IDE and the C compiler, with an example project for a PIC16F628A board:http://www.frank-buss.de/SkinnyLatte/index.html

author: jimmc
author_rank: Frequent Contributor
timestamp: June 20, 2013, 06:50:00 pm
content: Quote from: FrankBuss on June 20, 2013, 01:58:35 pmCan you use C?The timebase of a most micro based counters is set by the number of instructions between enabling and disabling the gate.As I understand it the use of assembly language is required to ensure that the number of instructions is correct (for at least part of the program).There is a whole class of PIC based counters based on Microchip AN592Dhttp://ww1.microchip.com/downloads/en/AppNotes/00592d.pdf. Terry Weeder did an early version, a search for 'Weeder Frequency Counter' should bring lots of results.'Silicon Chip' did a nice versionhttp://home.exetel.com.au/marknac/50MHz-Frequency-Meter.htmJim

author: FrankBuss
author_rank: Unknown
timestamp: June 20, 2013, 07:11:21 pm
content: Quote from: jimmc on June 20, 2013, 06:50:00 pmYes, C is no problem. I would implement the gate with another timer and an interrupt, if not possible with the hardware (have to read the datasheet again). First thing you could do in the interrupt function is to read the counter value and the last thing to do is to reset the counter for the gate interrupt. This should reduce the inaccuracy to some low jitter, depending on interrupt latency and when an instruction of the main program (if any) is interrupted, maybe 2-3 clocks. Then there are some additional fixed number of cycles for resetting the gate counter and for the interrupt header until you read the input counter. This could be just measured with a reference clock. Of course, it will be very low, too, so without the correction the error will be very low.PS: this was one reason for my project to use a CPLD: No instruction cycle jitter, no sometimes cumbersome microcontroller registers to use, and guaranteed maximum error of 1/clock (for 1 second gate time), with clock >=50 MHz.

author: Jeroen3
author_rank: Super Contributor
timestamp: June 20, 2013, 08:17:20 pm
content: I'd recommend counting flanks in a interval slower than your input signal. This reduces cpu processing and interrupts. And gives you time to do something else, your LCD for example.You'd just configure a timer to run on external clock (your input, filtered) and use an timer interrupt or RTOS to reset it once every x time. The readout interval x can be changed for range settings.Measuring the time between flanks can only work on low speed signals, or you'd need to go really fancy with your DMA.

author: marabut
author_rank: Contributor
timestamp: June 20, 2013, 09:39:30 pm
content: For beginner, building verified project is a better option than designing new counter from scratch and microcontroller based counter can be easier to get running than pure hardware based design.But before you start, check what microcontroller you have at hand (and programmer for it - of course). From my experience I can recommend as first approach one of variants of Weeder Frequency Counter mentioned by jimmc earlier in this thread. It uses PIC16F84(A) which is convenient because of hardware type prescaler built in. There are many of variants, ready to build, with simple PCB and HEX file for MCU. Take a look athttp://www.qsl.net/om3cph/counter/counter.htmland check links marked as "contribution". These are mostly custom made boards - very useful for beginner (one sided PCB, additional options etc.).Some time ago I built one of such variants, from SQ8CBY:http://www.gregorkarnas.com/radio/projekt/skala/index.htm. It uses 1x16char LCD, but software easily can be modified to support 2x16char LCD (as I did) much more popular and easier to buy. There was no problem to get it running. Just supply power, do some calibration with trim capacitor and your'e done. Site is not in english but pictures are worth a thousand words. If you want detailed description how it works, check OM3CPH site.Otherwise, If you want use ATMEL MPU's, the circuit will be more complicated as ATMEGA's internal counters can't count frequencies higher than fxtal/2. This is serious limitation and can be omitted by using external TTL/HCMOS counters (like in this design:http://www.avr-asm-tutorial.net/avr_en/fcount/fcount_m8.html). However, it means higher parts count and more complicated circuit.Personally, I think that it's better to stick to PIC in this case (however I use ATMEGA's in most of my designs).And last, but not least, it can be step to build excellent frequency meter published by S53MV (http://lea.hamradio.si/~s53mv/counter/counter.html).

author: alank2
author_rank: Super Contributor
timestamp: June 20, 2013, 11:04:39 pm
content: I've gone through the entire process and tried many different techniques for frequency counting using an AVR. If you search some of my posts over at the AVR forum (same username) and look for ones related to frequency counting, you'll see a lot of questions and a lot of learning.In the end I am using an atmega328p overclocked to 26MHz using a very small OCXO off of eBay that warms up quickly and is very stable. I posted a link here to this oscillator a few days ago in another thread.Here are some notes from my project (not finished, so they might be rough):Design______This project uses an AVR ATMega328. It is unable to capture at higher speeds so it requires a prescaler to slow down the fast signals to slower signals it can handle. By enabling or disabling this prescaler, it can measure signals from 0.5 Hz to 100 MHz with the same precision and accuracy. Many frequency counter implementations rely on very carefully written assembly code that is timed precisely, but this design is based on a ISR that executes once per millisecond. Two uC hardware resources make this possible.TIMER1 is a 16 bit timer that is clocked directly with the uC clock. It is used for 3 tasks. The first is to execute an ISR every millisecond by setting the compare register an appropriate number of cycles ahead. The second is to keep track of the signal clock. Up to 20000 uC clock cycles may have occurred each 1ms with a 20 Mhz clock, but this is no problem because it is a 16 bit timer that can go to 65535 clock cycles. The third is that when a signal occurs, the input capture unit stamps the event with a timestamp that can be used to track the distance between signals in precise uC clock cycles.TIMER0 is an 8 bit timer being clocked with the signal directly. Similar to the signal clock, each time the ISR runs, it must process the number of signals to keep them from overflowing. This limits the frequency it can handle to 255 kHz, but a safer maximum of 240 kHz is selected instead. This is no problem because the prescaler using the Q10 tap (2^10=1024) reduces 100 MHz to only 97.656 kHz.It is critical to get the TCNT0 (signal count) and ICR1 (signal timestamp) at the same time, but this is impossible since only one instruction can be run at a time. So, it is accomplished by grabbing TCNT0, then ICR1, and then TCNT0 again to make sure it has not changed. If it has changed, then they may not represent the same event and another attempt at grabbing them synchronized must be attempted. At a maximum of 240kHz and a much faster uC clock, it shouldn't take too many attempts.Once the number of signals and number of clock cycles have been captured, then the frequency can be calculated.The prescaler never needs to be reset because measurements are taken from one signal to the next signal.Autoranging (enabling or disabling the prescaler) is handled by using the Q12 tap fed into the INT0. The INT0 interrupt is disabled, but the INTF0 flag is checked during each ISR execution and the number of ISR executions between INTF0 flags is used to determine a rough frequency. This can determine if it is faster than 240.941 kHz (enable prescaler) or slower than 204.800 kHz (disable prescaler). The dead space between these two frequencies is to prevent oscillation of enabling/disabling the prescaler.All measurements are from signal to signal with no signals lost unless autoranging occurs. This is important because it allows the measurements to fully represent the signal and this is especially important for the low/avg/hi mode. This is only possible because of the separate Q12 tap/INT0 autoranging. Without that, some of the signal would have to be used to determine whether the prescaler should be enabled or not ahead of time before taking the measurement.Precision is determined by how fast the uC's internal clock is. A 10 MHz clock for a 1 second measurement is log10(10000000*1) which is 7 digits. A 20 MHz clock for a 10 second measurement is log10(20000000*10) which is 8.3 digits. The two ways to increase precision are to make the uC internal clock faster or increase the gate time. It supports 3 gate times (0.1s, 1s, and 10s) and also a precision mode that can be enabled or disabled. Since the clock will likely be between 10 Mhz (7 digits) and 20 Mhz (7.3 digits), it makes sense that for a 1s measurement we 7 digits of precision are displayed. This would mean that 0.1s=6 digits, 1s=7 digits, and 10s=8 digits. The precision mode simply increases by one digit if there is room (0.1s=7 digits, 1s=8 digits).One thing that is absolutely critical is an accurate jitter free uC clock. This is at the heart of every measurement and if it is off, jittery, or temperature sensitive, so will the measurements be off, jittery, or temperature sensitive.

author: richard.cs
author_rank: Super Contributor
timestamp: June 21, 2013, 10:01:31 am
content: I would suggest that the choice between a hardware counter and a microcontroller should come down to whatever you are most familiar with. Microcontrollers do make changes easier but there's a bit of effort involved in getting setup to program them. If you do decide to build a counter in hardware then the one you linked in your first post looks like the simplest you will get.I really like that design actually, as i said yesterday I'm thinking of building one but I will likely modify it to use a 10 MHz oscillator (74 series logic for the initial divide-10, two extra 4553s for the divide-1e6, and a final flip flop to get 0.5Hz with accurate duty cycle). That allows the use of the most readily available OCXOs.Edit: Just bought myself a 10 MHz OCXO.