View previous topic :: View next topic |
Author |
Message |
Vinch
Joined: 24 Feb 2007 Posts: 7
|
IIR Filter |
Posted: Sat Feb 24, 2007 9:50 am |
|
|
Hello,
I'm trying to find a good code for an IIR filter which will select the 440Hz frequency of an audio signal.
Can you help me?
Thank you |
|
|
Vinch
Joined: 24 Feb 2007 Posts: 7
|
|
Posted: Sun Feb 25, 2007 8:52 am |
|
|
In fact, I want to use the PIC16F876A to detect a certain frequency...
What is the best method to do that?
Thank you |
|
|
Ttelmah Guest
|
|
Posted: Sun Feb 25, 2007 10:21 am |
|
|
Trting to do this in software on a standard PIC, is going to be very hard indeed. Personally, I'd say 'add an NE567'.
Best Wishes |
|
|
jma_1
Joined: 08 Feb 2005 Posts: 147 Location: Wisconsin
|
|
Posted: Sun Feb 25, 2007 10:32 am |
|
|
Greetings,
One method of detecting a frequency would be to sample an analog input and perform an FFT (FFT-> DFT discrete fourier transformation). Try searching for DFT or FFT on the web. In my search I came up with numerous code examples. This is a well known algorithm, but the implementation is very dependent upon the hardware platform (PC; embedded microprocessor; data acquisition).
DFT suggestions:
sample sizes should be in powers of 2
floating point arithmetic is slower than integer
make sure you can sample the data fast enough to detect your frequency (Nyquist criteria)
include a hardware low pass filter to prevent sampled high frequencies 'folding' back into your data
investigate if over-sampling or decimation is appropriate for your hardware / software application
Resources:
Oppenheim & Schafer textbook (bible)
Microchip application note on FFT (dsPic; 30 series)
Microchip application note on DTMF (example for detecting frequency)
As a proof of concept (off topic slightly) some of the data acquisition products offered by National Instruments give examples on using an FFT on an analog input channel to measure frequency.
Original questions:
IIR vs FIR filter -> IIR might be slightly harder to implement in software due to the feedback element; FIR can implement a constant delay element; A signal will tend to ring/oscillate due to the feedback element in an IIR (more of a hardware consideration of the filter)
Cheers,
JMA |
|
|
jma_1
Joined: 08 Feb 2005 Posts: 147 Location: Wisconsin
|
|
Posted: Sun Feb 25, 2007 10:36 am |
|
|
Greetings Ttelmah,
I like your suggestion of using a tone decoder / phased lock loop chip. Without more information on the original problem, I didn't know if a hardware or software solution would work.
Cheers,
JMA |
|
|
Vinch
Joined: 24 Feb 2007 Posts: 7
|
|
Posted: Sun Feb 25, 2007 11:13 am |
|
|
In fact, I can't use an analogic filter. The filter has to be implemented in the PIC.
Some people have said to me that FFT will be too heavy for the PIC16F876, they have advised me to use a dsPIC. But for me, the PIC16F876 is imposed.
So, I will have to implement a digital filter in the PIC.
A FIR filter is better than an IIR? Or easier to implement?
After the filtering, I think I'll transform the sinusoïdal signal to a square signal and then try to make a clock detection of the period. Then I'll compute the corresponding frequency...
Is it possible to do that with a PIC16F876A?
Thank you |
|
|
Ttelmah Guest
|
|
Posted: Sun Feb 25, 2007 11:49 am |
|
|
There is a very big problem. What filtering is present outside the chip?. Remember that unless the signal is filtered to below half the sample frequency of the chip being used, you run the risk of aliasing producing a 'false positive' from higher frequency signals. So, some external filtering will be needed, and it seems silly not just to do the whole job with this!... However, that having been said, you then need to consider how to save time, and how to get the sample interval repeatable. I think you would probably need to sample on a timer interrupt, run the ADC, in 8 bit mode, and on each interrupt, read the last ADC value, and trigger a new conversion. This would really need to be done with yout own int_global handler, to avoid the large overheads otherwise involved in the CCS handler.
Now, I then have to agree with the suggestion of another poster, to consider using FFT. If you restrict the input bit range (trim to perhaps only 16 levels from the ADC), a lot of the work for this can be done using look up tables, and is more likely to be achievable in this processor.
Best Wishes |
|
|
Richard Arroyo
Joined: 04 Apr 2006 Posts: 22 Location: Sebastopol, CA
|
|
Posted: Sun Feb 25, 2007 5:55 pm |
|
|
Hello,
I suggest to at least use an 18F MCU.
The PIC16F876A doesn't have a hardware multiplier thus
making multiplication cumbersome. Where multiplication of
IIR filer coefficients, real and imaginary values
are the majority of the processing time don't
expect any fast sample rates on a 16F MCU.
Of course, you could sample the data into ram and post process the data though the PIC16F876 doesn't have much ram.
Did you know that some PIC18 and DsPic MCU's are actually cheaper than the mature PIC16f876A?
Do you have any specifications besides the frequency your trying to detect?
I.e., Sample rate, ENOB, SNR, SINAD, ect. _________________ RAA |
|
|
Vinch
Joined: 24 Feb 2007 Posts: 7
|
|
Posted: Tue Feb 27, 2007 5:36 am |
|
|
The sample rate is 8000.
I'm trying to find a bandpass IIR filter which will be centered on 440Hz and will have a very small bandwidth (about 2Hz).
It is normally possible to have this result with a 3 order Tchebytchev IIR digital filter.
Then I think I will try to implement it on the PIC16F876. The calculation would not be too heavy.
What do you think about it? |
|
|
Richard Arroyo
Joined: 04 Apr 2006 Posts: 22 Location: Sebastopol, CA
|
|
Posted: Tue Feb 27, 2007 7:41 pm |
|
|
With these requirement, it is highly unlikely to accomplish this on a 16F MCU.
You didn't mention how many poles or the passband ripple (Ap) of your Chebyshev
filter. A 2Hz Fc and 440Hz Fo require precision coefficients. Scaled 16 bit+ integers or
some fixed point data type with a few digits of mantissa might work but provided with only 125us of time
and no hardware multiplier good luck.
Are you good at assembler, have dry ice on hand and a few 100Mhz clock oscillators?
Here's a chart displaying the time of math operations on a 16F MCU running at
20Mhz Using CCS C:
http://www.ccsinfo.com/faq.php?page=time_for_math
You might save a few instructions in assembler.
_________________ RAA |
|
|
RobertB
Joined: 01 Nov 2007 Posts: 1 Location: New Jersey
|
|
Posted: Thu Nov 01, 2007 2:37 pm |
|
|
You can detect one tone on a PIC 16Fxxx processor using a somewhat modified Goertzel algorithm. If you make the sample rate exactly 6x the desired tone detection frequency, the needed coeifficients all work out to +1 and -1, eliminating any multiplication in between samples (as you have probably discovered, there's not enough horsepower perform even integer multiplications at the sample rate). I've successfully detected a DTMF tone using this technique (had to switch the interrupt timer between two sample rates to alternately detect the two tone frequencies). A description of Goertzel tone detection can be found in Lyons' book pg. 529. also in Wikipedia. |
|
|
ntype
Joined: 01 Nov 2007 Posts: 9
|
|
Posted: Thu Nov 01, 2007 2:41 pm |
|
|
Ttelmah wrote: | There is a very big problem. What filtering is present outside the chip?. Remember that unless the signal is filtered to below half the sample frequency of the chip being used, you run the risk of aliasing producing a 'false positive' from higher frequency signals. So, some external filtering will be needed, and it seems silly not just to do the whole job with this!... However, that having been said, you then need to consider how to save time, and how to get the sample interval repeatable. I think you would probably need to sample on a timer interrupt, run the ADC, in 8 bit mode, and on each interrupt, read the last ADC value, and trigger a new conversion. This would really need to be done with yout own int_global handler, to avoid the large overheads otherwise involved in the CCS handler.
Now, I then have to agree with the suggestion of another poster, to consider using FFT. If you restrict the input bit range (trim to perhaps only 16 levels from the ADC), a lot of the work for this can be done using look up tables, and is more likely to be achievable in this processor.
Best Wishes | #
How about a simple analogue filter on the input to solve this. A RC 2 pole or such like might do the trick |
|
|
|