Go Down

Topic: How to Adjust FFT Range and Bin Size (Read 1 time) previous topic - next topic

rickso234

I'm trying to do an FFT on the low end of the audio spectrum. Since I only want frequencies up to around 500Hz, I want to limit the FFT range to 500Hz since anything higher I'm just ignoring anyway. Would like 128 bins for about 4 Hz per bin resolution.

What are the general concepts for specifying range and resolution in the code. I believe the range is reduced from the default Arduino 4KHz using a timer/interrupt but not sure how. Also, don't understand how to specify number of bins. And what's the sine table used for?

johnwasser

If I understand my reading correctly you will need to sample at 1000 Hz to get valid data up to 500 Hz.  To get 128 bins across 500 Hz you will need to do the FFT on 256 samples.  I think you will want a low-pass filter to avoid aliasing (a 1.2 KHz signal sampled at 1 KHz looks just like a 0.2 KHZ (200 Hz) signal.  You will want to filter out as much as you can above 500 Hz.
Send Bitcoin tips to: 1L3CTDoTgrXNA5WyF77uWqt4gUdye9mezN
Send Litecoin tips to : LVtpaq6JgJAZwvnVq3ftVeHafWkcpmuR1e

rickso234

Thanks for the reminder on the filter. I've been using sinewaves so far but for music will need to filter out the higher frequency content. Still can't figure out how to get 128 bins across a 500HZ bandwidth. I haven't found any code that's well commented and describes the effects of changing values like
#define N_WAVE             1024    /* full length of Sinewave[] = 1024 */
#define LOG2_N_WAVE    10      /* log2(N_WAVE) */

#define FFT_SIZE             64
#define log2FFT               6

Magician

#3
Jan 01, 2012, 08:50 pm Last Edit: Jan 01, 2012, 11:28 pm by Magician Reason: 1
In your other thread: http://arduino.cc/forum/index.php/topic,82543.0.html
there is a link: http://101science.com/dsp.htm , my advise: take a course.
If you don't know how to set Timer, and don't want to use MsTimer2 library, there is other way around: take a several analog readings, than calculate average value and store it into array.
Sampling rate would decrease by averaging N, and you don't have to worry about aliasing much.
Code: [Select]

 for(i=0; i<N; i++ ) {    //  <---external cycle - "main"

   long temp = 0;
   for ( int8_t iner = 0; iner < AVRG; iner++) {  // <--- internal cycle

       ADCSRA |= (1<<ADSC);
       while(!(ADCSRA & 0x10));

       temp = temp + ADC;
       }
    x[i] = temp / AVRG;       // <--- store 1 value from 10 or so
}

Making AVRG = 10, sampling rate : 9 kHz / 10 ~= 900 Hz, which is good up F/2 = 450 Hz signal input.

#define N_WAVE             1024   //could be any size >= than FFT_SIZE below
#define LOG2_N_WAVE    10      /* log2(N_WAVE) */

#define FFT_SIZE             256 //  <<<-- for 128 bins
#define log2FFT               8     // <<<--- Log2 (256)

Sinewave size should be no less than your FFT_size: 256. You can create smaller sinewave table with help of Excell, LibreOffice, or Arduino, loading a scketch to print out values as a table.

rickso234

THanks, Magician. You're probably tired of seeing my postings for FFT help! Appreciate your suggestion to take a "course" but I really just want to get the FFT working and move on to processing the FFT results. I'm very tempted at this point to just build hardware active filters instead of FFT, but FFT seems so elegant and versatile.

"... take a several analog readings, than calculate average value and store it into array."
   -> What am I taking averages of, the analog (music) input or the timer value?

In your code example...
   -> Does this code just go anywhere in "void loop()" ?
   -> Is it replacing the "timer" code?

for(i=0; i<N; i++ ) {    //  <---external cycle - "main" 
   -> What is "N" and what do I set it to?

x = temp / AVRG 
   -> What do I do with the x array?

Magician

Quote
-> What am I taking averages of, the analog (music) input or the timer value?

Analog input readings.
Quote
-> Does this code just go anywhere in "void loop()" ?
   -> Is it replacing the "timer" code?

Snippet of code doesn't go anywhere, it stays where is it, it's the same color_music code with injected 4 additional lines. N and x[] are defined in color_music sketch.

Go Up