Using FFT Library to Interface with Headphone Jack Input

I’m working on a project that requires me to take an input (3.5mm headphone jack) and split it into 7 frequency bands. I then want those 7 frequency bands to give me a number (0-255 for example) to be able to control various lighting and moving effects that my project requires. The project will be run off of an Arduino Mega 2560.

I can handle how to work with the numbers once I get 7 variables outputting from 0-255 for example but I need to get to that point. So far I’ve taken several hours trying to work with various examples of FFT code to create a VU however I can’t figure out how to get the readout from FFT into the form I want.

This is the example code I found that I’ve been toying with in attempts to be able to do what I want:

#define LOG_OUT 1 // use the log output function
#define FFT_N 256 // set to 256 point fft

#include <FFT.h>

void setup() {
  Serial.begin(115200); // use the serial port
  TIMSK0 = 0; // turn off timer0 for lower jitter - delay() and millis() killed
  ADCSRA = 0xe5; // set the adc to free running mode
  ADMUX = 0x40; // use adc0
  DIDR0 = 0x01; // turn off the digital input for adc0

void loop() {
  while(1) { // reduces jitter
    cli();  // UDRE interrupt slows this way down on arduino1.0
    for (int i = 0 ; i < 512 ; i += 2) { // save 256 samples
      while(!(ADCSRA & 0x10)); // wait for adc to be ready
      ADCSRA = 0xf5; // restart adc
      byte m = ADCL; // fetch adc data
      byte j = ADCH;
      int k = (j << 8) | m; // form into an int
      k -= 0x0200; // form into a signed int
      k <<= 6; // form into a 16b signed int
      fft_input[i] = k; // put real data into even bins
      fft_input[i+1] = 0; // set odd bins to 0
    // window data, then reorder, then run, then take output
    fft_window(); // window the data for better frequency response
    fft_reorder(); // reorder the data before doing the fft
    fft_run(); // process the data in the fft
    fft_mag_log(); // take the output of the fft
    sei(); // turn interrupts back on
    Serial.write(255); // send a start byte
    Serial.write(fft_log_out, 16); // send out the data

I know this code by how it is written shows 16 bars and I also need help in changing that down to the appropriate 7.
The code also has known issues with the Serial.write functions but I just copied the original code here because I’m having issues getting down to the 7 variables so I can print my numbers.


I feel like the code is missing some important bits. Like how FFT_N is incorporated into everything else, or where fft_log_out comes from.

You want to define your FFT information into 7 Buckets. Divide your output from your FFT evenly between the buckets, or center them around important frequencies, etc, and then just either average or sum up your values, and interpret that as your output. With 256 entries, it won't divide evenly, but you should be able to divide it up evenly within +/- 1 entry.

The code comes from the same place I got the particular library I'm currently trying to work with from:

The code does successfully compile and download but this code on its own doesn't give me any better understanding of how the library works to even begin to figure out how to access each individual bin.

I believe my biggest issue is how can I access the number stored for each bin so that I can then average them down into 7 bins.

I should also be able to bring the 256 to 16 so I'm not working with as many bins and can speed up processing.