Go Down

Topic: FFT for picking out amplitude of a frequency band. (Read 4310 times) previous topic - next topic


I'm trying to use my arduino for a engine knock sensor, but I can't wrap my head around using FFTs. All I want is a single output representing the volume of a 3.5khz +-.3 signal, but everything I read is about creating graphical equalizers.  Could someone please point me in the right direction.


Rather than using an FFT you might want to research a Digital Bandpass Filter.

In either case you will probably be setting the ADC in free-running mode (take readings as frequently as possible).  The filter will depend on the sampling interval so you might need to work that out first.

Here is an example of a calculator that will write the code for you:

The generated code looks like this:
Code: [Select]

/* Digital filter designed by mkfilter/mkshape/gencode   A.J. Fisher
   Command line: /www/usr/fisher/helpers/mkfilter -Bu -Bp -o 3 -a 1.0000000000e-01 1.1875000000e-01 -l */

#define NZEROS 6
#define NPOLES 6
#define GAIN   5.485702260e+03

static float xv[NZEROS+1], yv[NPOLES+1];

static void filterloop()
  { for (;;)
      { xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = xv[5]; xv[5] = xv[6];
        xv[6] = next input value / GAIN;
        yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = yv[5]; yv[5] = yv[6];
        yv[6] =   (xv[6] - xv[0]) + 3 * (xv[2] - xv[4])
                     + ( -0.7899732587 * yv[0]) + (  3.8143619741 * yv[1])
                     + ( -8.6998844482 * yv[2]) + ( 11.5413569160 * yv[3])
                     + ( -9.4113261268 * yv[4]) + (  4.4637724618 * yv[5]);
        next output value = yv[6];

As an experiment I just shoved in a 32 kHz sample rate.  I don't know if the Arduino can sample that fast or not.  I think you will want to RMS average the "next output value" values (square them, add them up, and divide by the number of samples).

An alternative would be to make a hardware audio bandpass filter and integrator BEFORE the analog input.
Send Bitcoin tips to: 1G2qoGwMRXx8az71DVP1E81jShxtbSh5Hp


Probably, you mean graphical spectrum analyzers, equalizers usually based in FIR/IIR digital filters. +- 0.3 is about 0.6 kHz wide band, you also could use just filters, or may be Goetzel, instead of FFT. Are there any other "pattern" or temporal characteristics? because it's unlikely filtering a such wide band you can reliably detect anything in the noise.


Wow, Goetzel looks much closer to what I need. I'm just trying to convert the volume of a band into a usable output. There shouldn't be too much extra noise in the band, I just want to eliminate other components and come up with a numeric value. Thanks guys, I'm searching more now.


Volume itself can't be an indicator, as it would vary with RPM, at least. More informative a ratio : band of interest to overall, in this case you would need two values, representing in-band level and everything else, or overall. But look on filtering first, other value much easier to obtain:


Thanks guys got a Goetzel working great with my tone generator at the frequency I want. Thanks for the help!


Go Up