Freq. counter Algorythm advise

Go To Last Post
12 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am working on creating myself a simple frequency meter (mainly for the challenge of doing so although I may have a few projects that might make use of it later) and I am trying to decide which is the best approach

 

1)  count the number of pulses received during a fixed interval (timer Interrupt & pin change interrupt)

2) record the to to receive X pulses.

 

Any opinions on which approach would be better, or is it a "You pays your money & Takes your choice" type of decision.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

3) the time between rising and falling edges - inverse is the frequency (assuming a 50:50 duty cycle).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

i think there may be a flaw in your opt 3

 

Time between rising & falling edge would only be half a cycle so would give twice freq, time between rising Or falling edges would be fine.

This is similar to my option 2, I think timing a count (100 or 1000) pulses would be better as it would reduce the effect of ISR timing & smooth out frequency variations on the source signal.

this would probably be ok for low frequencies though.

I am expecting to be working with Approximately Audio Frequencies or lower certainly (higher would not be an issue).

 

   

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Use the input capture to avoid the problem of interrupt timing.
You can also clock a timer externally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IPguru wrote:
so would give twice freq

Gee! If only C had something like "/ 2" or something equally clever eh? cheeky

 

The point about timing edge to edge is that you get an "instant answer". You don't have to accumulate a number of samples before you can determine the frequency and it reacts immediately if the frequency is changing (possibly rapidly).

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You can also clock a timer externally.

+1

 

And perhaps even a counter in front of that. 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IPguru wrote:
Any opinions on which approach would be better

It depends on your requirements.  What are the minimum and maximum frequencies to be measured?  What resolution is needed?  What accuracy? 

 

For low frequencies, then I'd suggest input capture to measure between rising (or falling) edges.

 

clawson wrote:
The point about timing edge to edge is that you get an "instant answer". You don't have to accumulate a number of samples before you can determine the frequency and it reacts immediately if the frequency is changing (possibly rapidly).

But y'all sound like you have never used input capture.  Yes, you can time rising to falling edge--but only if you have a chance to change ICES1 in time.  So why not go ring-to-rising and now there is no race to change ES and no worry about duty cycle?!?

 

"Low frequency" here is in the eye of the beholder, but it becomes inconvenient or impractical to try to service ICP every cycle above a few kHz.  At that point, using timer-as-counter Tn pin with an aux time base of a fraction of a second works better IME.  Properly done it can be very accurate.  I usually use an array of about a seconds worth of samples, and the total is the sum of the 1/10, 1/16, or whatever second intervals.

 

So I route the signal to both ICP1 and Tn, and "switch ranges" as needed.

 

Often discussed over the years.  Try to search out the prior threads.

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Count pulses over a 1 second period via T1 pin.   Gives you 1Hz resolution from 1Hz to 8000000Hz (assuming F_CPU = 16MHz)

Measure cycle time e.g. Rising to Rising with ICP1 pin.    Gives you period with 125ns resolution.  

 

Counting cycles is more suitable for 1000Hz - 8MHz range.   Period is more suitable for 1Hz - 1000Hz range.

 

Your 16MHz crystal is likely to only have 30ppm accuracy.   So any measurements are limited to this.    Of course you can calibrate your crystal against a "better" Frequency Counter.

 

david.

Last Edited: Thu. Apr 7, 2016 - 02:55 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Many thanks

These are just the sort of sugestions I was looking for,  seems my opt 1 & opt 2 were almost there ecept I overlooked the fact that the Hardware can do most of the grunt work for me :-)

 

I am now going to experiment with both input capture & external cock, then maybe look at a hi/lo freq switch to select between them.

 

I am not worried about much more than a few KHz ( although if I can get to 20K + that would open up a bunch of other uses) so I suspect input capture would suffice anyway.

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Yes,  20Hz - 20kHz is appropriate for period.   i.e. 50us period is 800 cpu cycles.   You get a reasonable resolution and accuracy.

 

If you want to improve resolution,   you count several periods.

 

David.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

IPguru wrote:

1)  count the number of pulses received during a fixed interval (timer Interrupt & pin change interrupt)

2) record the to to receive X pulses.

....

I am not worried about much more than a few KHz ( although if I can get to 20K + that would open up a bunch of other uses) so I suspect input capture would suffice anyway.

 

Now I will confuse you by suggesting you use both 1) and 2)  :)

 

Simplest frequency counters have some fixed gate time, of say 100ms~1s and they count in that time.

A MCU single timer with an external clock, and carefully timed capture, can do that with minimal effort to modest precision

 

However, that design drops in precision at lower frequencies. - you cannot practically get 100.123Hz for example.

At lower frequencies, you may prefer to count X pulses and record the time.

 

Or you can combine these both, and build a Reciprocal Frequency Counter.

Same basic idea, but the finer details matter.

 

eg You have a Timer running, with SysCLK precision, and a second timer counting Fin Edges.

After some nominal minimum 'gate time', instead of immediate read, you wait until the next Fin edge, and then you capture both

values.

 

Now you have X whole cycles in Y SysClks, and Frequency is  K * X/Y.

 

If you have a very low freq in, the precision comes from the Time value, and for higher (MHz) Fin, the precision comes from the X Cycles.

At values in between, it is a mix of these, and this Auto-ranges.

 

Sadly, many MCUs timers/captures can only almost do this in HW, but not quite all of it.

 

 

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I Think I would prefer to "Keep It Simple" as high accuracy is not  currently important.

 

Input capture is currently working fine for >35Hz <37Khz.

 

Next up is to implement range switching for lower frequencies, it would be nice to get down to 0.1 hz, but 1Hz is probably more than sufficient.

(I also need to sort out some maths to avoid -ve figures due to high counts at low frequencies but that should bot be too big an issue :-) )