View previous topic :: View next topic |
Author |
Message |
OSUschap
Joined: 26 Sep 2005 Posts: 4
|
Low frequency measurement |
Posted: Mon Sep 26, 2005 11:50 pm |
|
|
Hello,
I am attempting to measure frequency with 16F876 or 877 using a 20 MHz crystal. The frequencies range from very low say 100Hz to a max around 3.5kHz. Since the frequencies are so low, a sampling time method would cause too much delay. My current plan is to use external edge triggered interupts and the standard timers (16 bit). I plan to use the timers to keep track of the constantly changing period of the incoming signal. Every time the trigger occurs, the frequency value would be updated and then the timer could be reset or left running I suppose. However, I do not plan on using any pre-scalers, and so my question is this. At the higher frequencies, will the interrupts be coming in too fast for the PIC to be able to perform other functions that may be needed, such as a pulse modulated output. Is this a really bad way of doing this, or does it sound solid at all? As I'm sure it shows, I do not have a lot of PIC experience so any replys will have to be at somewhat of a beginner level. Any suggestions or at least confirmation that this would work would be appreciated. Thanks |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Tue Sep 27, 2005 12:17 am |
|
|
How much delay is too much? Say, your frequency of interest changes from 200Hz to 100Hz. How fast do you want to rect? |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
Re: Low frequency measurement |
Posted: Tue Sep 27, 2005 6:04 am |
|
|
OSUschap wrote: | I am attempting to measure frequency....
I plan to use the timers to keep track of the constantly changing period of the incoming signal. |
Not intending to be picky but this is not measuring frequency. Frequency is measured by counting the number of cycles (such as low to high transitions) that occur over a given period. _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
sseidman
Joined: 14 Mar 2005 Posts: 159
|
Re: Low frequency measurement |
Posted: Tue Sep 27, 2005 6:52 am |
|
|
asmallri wrote: | OSUschap wrote: | I am attempting to measure frequency....
I plan to use the timers to keep track of the constantly changing period of the incoming signal. |
Not intending to be picky but this is not measuring frequency. Frequency is measured by counting the number of cycles (such as low to high transitions) that occur over a given period. |
Measuring the period and taking it's reciprocal is most assuredly a valid way to measure frequency (by definition), as is counting cycles during a given period of time, as is taking the fft and looking for the peak, as is using a frequency-to-voltage converter and reading the voltage, and a slew of other methods that don't spring immediately to mind. Each method will have advantages and disadvantages, and be susceptible to different types of errors.
Scott |
|
|
asmallri
Joined: 12 Aug 2004 Posts: 1634 Location: Perth, Australia
|
Re: Low frequency measurement |
Posted: Tue Sep 27, 2005 7:54 am |
|
|
Quote: |
Measuring the period and taking it's reciprocal is most assuredly a valid way to measure frequency (by definition). Scott |
No. Neither is this the definition of frequency. Frequency is defined as the number of cycles per second. However the period method is a means of determining the frequency of a constant waveform. Consider for example a waveform with a mean period of 1ms but with a jitter of 100us. This wavform has a freqency of 1KHz. The result of measuring the cycle by cycle period would give you a varying frequency but with the same average frequency.
I did say I did not mean to be picky... _________________ Regards, Andrew
http://www.brushelectronics.com/software
Home of Ethernet, SD card and Encrypted Serial Bootloaders for PICs!! |
|
|
cbrock Guest
|
|
Posted: Tue Sep 27, 2005 9:45 am |
|
|
Check out this months Circuit Cellar. There is an article using the CCS compiler and a simple DSP algorithm. |
|
|
OSUschap
Joined: 26 Sep 2005 Posts: 4
|
|
Posted: Tue Sep 27, 2005 11:02 am |
|
|
kender wrote: | How much delay is too much? Say, your frequency of interest changes from 200Hz to 100Hz. How fast do you want to rect? |
Some delay is ok, but it needs to react in ms if not us. I cannot sample for so many seconds and count pulses there. However, if my output will simply continue to output the old data until the new calculations are complete, that would be desired. |
|
|
Humberto
Joined: 08 Sep 2003 Posts: 1215 Location: Buenos Aires, La Reina del Plata
|
|
Posted: Tue Sep 27, 2005 12:01 pm |
|
|
OSUschap wrote:
Quote: |
The frequencies range from very low say 100Hz to a max around 3.5kHz. Since the frequencies are so low, a sampling time method would cause too much delay.
|
You didnīt tell us the time the measuring signal takes to shift from 100Hz to 3500Hz.
Quote: |
Some delay is ok, but it needs to react in ms if not us.
|
For an incoming (assuming constant freq as asmallri well stated) signal of 100Hz
you need at least 10ms to get a measurable event.
If the signal is changing in frequency, you need another 10ms just to know that is changing.
The key is not to measure high frequency, (you can measure 50Mhz with a 20Mhz crystal)
the key is if the input frequency is stable enough at sampled times and the extra time
needed to do some task.
You would define this tradeoff before start coding.
Humberto |
|
|
OSUschap
Joined: 26 Sep 2005 Posts: 4
|
a look at what I'm trying |
Posted: Tue Sep 27, 2005 1:46 pm |
|
|
The signal is one with constantly but slowly changing frequency. I understand that when waiting for an edge, I will have to wait 10 ms to get a frquency measurement for the worst case scenario (100Hz). However, this is probably well below what I will bet getting anyhow and if the frequency changed to such a value, the 10 ms would be an acceptable delay on the output as long as it didn't just go to 0 or something for that 10 ms. Here is what I started with, maybe it will give an idea of what I'm trying to do, although now that I've typed it, the code doesn't look quite right.
[/code]
//global variables:
long freq = 0.0;
#int_CCP2
CCP2_isr()
{
int period = CCP_2;
freq = 1/period;
set_timer1(0)
}
void main()
{
// Setup:
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // 200ns resolution
setup_ccp2(CCP_CAPTURE_RE); // interrupt on rising edge
enable_interrupts(INT_CCP2); // interrupt on CCP2 rising edge
enable_interrupts(global);
enable_interrupts(global);
and then of course main will be doing other things |
|
|
kender
Joined: 09 Aug 2004 Posts: 768 Location: Silicon Valley
|
|
Posted: Tue Sep 27, 2005 8:21 pm |
|
|
Initially I thought that you could sample the signal at a high rate for the amount of time less then one perion, do an FFT, and then look for the peak. If the signal is slow, there is plenty of time to do the FFT. Bu then I came to realize that the bin size will be big, and it can make the method not work.[/code] |
|
|
OSUschap
Joined: 26 Sep 2005 Posts: 4
|
code didn't work |
Posted: Wed Sep 28, 2005 11:15 am |
|
|
Well, I wrote some code and you guys are probably not surprised that it didn't work. Can anybody tell me if I just made a rookie mistake or if this method is simply invalid? Thanks a lot for the tips guys, but I still have no idea if i'm approaching this in a reasonable way. Code: |
//global variables:
long freq = 0.0;
long period = 1;
#int_CCP2
CCP2_isr(){
period = (CCP_2*0.0000002);
freq = (1/period);
set_timer1(0);
}
void main()
{
// Setup:
setup_timer_1(T1_INTERNAL|T1_DIV_BY_1); // 200ns resolution
setup_ccp2(CCP_CAPTURE_RE); // interrupt on rising edge
enable_interrupts(INT_CCP2); // interrupt on CCP2 rising edge pin_c1
enable_interrupts(global);
while (true){
if (freq <400)
output_high(pin_b0);
else if (400<freq<1500)
output_high(pin_b1);
else if (1500<freq<3000)
output_high(pin_b2);
}
} |
|
|
|
sseidman
Joined: 14 Mar 2005 Posts: 159
|
|
Posted: Wed Sep 28, 2005 11:30 am |
|
|
Have you considered using a Frequency to Voltage converter like the AD650? |
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Sep 28, 2005 1:44 pm |
|
|
Code: | period = (CCP_2*0.0000002);
|
Dividing CCP_2 by 5 million? CCP_2 is a 16 bit number that can't exceed 65535.
It would have to be a float and you wouldn't want to do that. Just figure out what the CCP values would be and use those in your if statements. Also, you probably want to turn off the other LEDs when you turn on one. Otherwise, they might all be lite at once. |
|
|
PCM programmer
Joined: 06 Sep 2003 Posts: 21708
|
|
|
Mark
Joined: 07 Sep 2003 Posts: 2838 Location: Atlanta, GA
|
|
Posted: Wed Sep 28, 2005 2:13 pm |
|
|
Actually, 65535 at 20ns resolution would allow a 76Hz signal to be read so he doesn't really need to extend the resolution unless he wants to measure less than say 80Hz. Also, there is a mode for the CCP that will automatically reset timer1 to prevent latency problems. |
|
|
|