Led control, using FFT library

Hi Everyone!

I need help to create a simple code, using FFT library. I found the 32- Band audio spectrum visualizer project on net. I would like to have the similar concept, but i need to output the measured values to 8 leds. I read hours to understand the FFT, but since i’m not a programmer, it is impossible for me. That’s why i ask for help. The goal is for me, to get signals via MAX4466 microphone, divide the 20Hz-20khz (or 18kHz) to 8 (or better for me to 6) channels, and the result values should drive the leds channel by channel. I tried to reduce the mentioned sketch, and spent hours to get some result what i can use. I could see changes in the different “sample” values, but it wasn’t stable enough, and i don’t know why the result turned to negative sometimes. I tried to use the the original variables in the project (somehow) to get some result, what i can use to control the leds, but no success.

Please let me note, that sadly i’m so far from programming, i can follow logical thinking to get my projects work,
but with this one, i’m really stucked, any kind of help would be greatful, thank you!

The modded sketch attached…

Best Regards:
Keypriceb

Reduced_FFT_sketch.ino (3.33 KB)

Take the original code that does 32 bands and group them in groups of four. Average each group and use that average to light your LEDs.

As you have found the FFT is confusing for some one who doesn’t know the theory so messing about with the parameters without understanding what they are doing and what consequence they have is a bit of a fruitless exercise.

Thank you Mike, for the reply!

Yes, i agree with you, it is quite impossible for me to do this. But since i received 2 pieces of defected MSGEQ7 chip (i planned this to use it for the project) from china, i had no other options. If i order another, it would arrive 2 month later, and i need this stuff earlier. I will take your advice, and try to figure out where, and how i can group the bands.

Have a good day!

Hii , here i tried to help you in this.

FFT CODE;
Arduino\libraries\arduinoFTT (this library's folder) Arduino\libraries\arduinoFTT\arduinoFTT.cpp (the library implementation file, uses 32 bits floats vectors) Arduino\libraries\arduinoFTT\arduinoFTT.h (the library header file, uses 32 bits floats vectors) Arduino\libraries\arduinoFTT\keywords.txt (the syntax coloring file) Arduino\libraries\arduinoFTT\examples

I wish this will help you
for best LED lights we have lot of store in online.

Thank you Sanajain, i'm continuously reading the example codes of the FFT, and trying to understand the functions. :slight_smile:

It does not make sense to sample just 8 or 16 points of the input audio.

If you are using an AVR-based Arduino, the OpenMusicLabs FFT is faster and smaller than Arduino FFT, and the FHT is smaller yet.

To group the bands, use the LOG_OUT option to get intensities (volume). Then you can add together any bands you like.

E.g. band[0]= sum (fht_log_out[0] to fht_log_out[15]), band[1]=sum(fht_log_out[16] to fht_log_out[31]) etc.

FHT example sketch. This code assumes that the audio input is on A0 and is biased to Vcc/2 for zero input.

/*
example sketch for testing the fht library.
it takes in data on ADC0 (Analog0) and processes them
with the FHT. The intensities are sent out over serial
port.  
*/

#define LOG_OUT 1 // use the log output function
#define FHT_N 256 // set to 256 point transform

#include <FHT.h> // include the library

void setup() {
  Serial.begin(115200); // use the serial port
  TIMSK0 = 0; // turn off timer0 for lower jitter
  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 < FHT_N ; i++) { // 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 -= 512; // form into a signed int
      k <<= 6; // scale up into a 16 bit signed int
      fht_input[i] = k; // put real data into bins
    }
    fht_window(); // window the data for better frequency response
    fht_reorder(); // reorder the data before doing the fht
    fht_run(); // process the data in the fht
    fht_mag_log(); // take the output of the fht
    sei();
    for (int i=0; i< FHT_N/2; i++) {
    Serial.println(fht_log_out[i],1); // print the intensities
  }
}
}

Tank you Jremington for the reply!!!

You made my day!! ;D
That's what i exactly need! After i read your reply, i've checked the FHT example, and meanwhile i found a project on
internet with it, where a guy done the same what i need now. It's awesome, i will study the FHT, the example is way good noted, even i can understand the steps, and functions. :stuck_out_tongue:

I appreciate your suggestion, thank you so much!!!

Have a great day!!

Hi all!

Finally i was able to made a test with the FHT. Sad, but i couldn't get any result, with the example codes, even if i gave higher input then VCC/2, the result was a few (? ? ?) and i couldn't find where it went wrong. ::slight_smile: But the FHT based project, that i found related to my project gave results:
https://cassiopeia.hk/spectrumanalyser/

I built it, and seems to working, the channels changing by the frequencies, and their magnitudes, but the noise is pretty big, even if i try to drive the input by tone generator, instead of the MAX4466 microphone. I was read more projects like this, and most of them using voltage divider to the input (see in the project below), using the 3v3 supply on the arduino.
I tried it, the noise reduced a lot, it is still worse then the guy have in the project. And what i don't understand, he just simply plugged the microphone to A0. If i do that, the noise is almost equal with the frequency magnitudes. :frowning:

If someone know what i made wrong, please let me know.

In this project - https://create.arduino.cc/projecthub/janux/fht-audio-spectrum-visualizer-83bba0

  • the guy says, we have to set around 2.7 volts on AREF. At the same setup, i measure 5 volts, no matter what. I read, that AREF pin has an internal reference voltage(protected with a 32k resistor), and it should turn off, while we supply it from outside. On my NANO, it don't want to, even if i tried to use to turn off via code in void(setup).

Any tip regarding to the correct wiring up would be great, thank you. :o

the guy says, we have to set around 2.7 volts on AREF. At the same setup, i measure 5 volts, no matter what.

Unless you set up Aref to be an external input then that is what you will see. There is a line with a comment in the setup function that sets this.
Unless this line is run Aref will pump out 5V and so that circuit will not have the desired effect, which is to maximise the readings you get from a given signal.

https://www.arduino.cc/reference/en/language/functions/analog-io/analogreference/

Thank you Mike, i changed it in (setup) , and it seems, that the measuring quite better, i was able to set the noise/magnitude levels, and on the OSD screen everything act, like it should now.
But when i plug the microphone modul instead of line-in, everything goes wrong, 1 of the bands amplitude goes to maximum (around 5000Hz), and the other bands act like they not changing due to the sounds the mic should receive. I am started to test the microphone, it is also ordered from china, i wouldn't be surprised, if it is defected also, so i try to figure it out. I found a simple frequency measuring sketch that someone created to check a same type of mic, uploaded it, and no results, so i try other way. Thanks for your reply!

I assume that it is not a simple MAX4466 op-amp but one on a board. So it could be in any sort of circuit.
The ones I have seen from a quick search incorporate some sort of filter which will mess up the frequency response. Also the output voltage is likely to be different from a line output and the output impedance is going to be a lot higher. So it is this that is likely to be the difference.

Do you have any test equipment where you could look at the waveform you get from those two audio sources, both with the output connected to your circuit and not connected. That would tell you in an instant what was wrong and then you might take steps to correct your microphone input circuit.

Meanwhile, it turned out, that the microphone is working, instead of 5volt, i connected it to 3.3volt pin on the arduino (i was read, that it is preferred due to minimal supply noise) and the readings became much more better, but still too noisy.

Yes, i have a 2 channel oscilloscope, soon i will set up the way you mentioned, and will get back with the results. (thanks again :blush:)

After a few days i was able to test the mic via oscilloscope. The readings seems more than good. At the biggest peak, the mic provide around 900mV signal, and only 50mV is the noise while everything quiet. Regarding to the OLED screen display, the original code was almost usable in my case, i only had to change the noise level dividing(from 4 to 1), to scale the screen for lower input levels, like talking...

int h = max((fht_oct_out [ x ] - noise_level / 1), 0); // scale the height

Now it's acting fine. But the leds would be the goal for me, so i started to interpret the commands ("min" and "pow"),
to set the led scaling correctly.

int green_level = min( pow(fht_oct_out[4]+fht_oct_out[5] - 2 * noise_level,2)/100, 255); // limit at 255

So regarding to the "hardware" , it seems everything is ok, only the 3,3V supply was the point to the better readings, now i have to understand the two reference command, to set them correctly. Later on i have to be able to change it via potentiometer, depend on "speech or music listening" , so the task is clear, now i have to learn. :stuck_out_tongue: