HELP! FFT and I2S

I need help with FFT and i2s. I'm making an application where I need to find frequencies between 50Hz and 300Hz. I made this code for FFT and it is not working, could someone help me? :frowning:

I'm using an INMP441 microphone and ESP32

#include <driver/i2s.h>
#define I2S_WS 15
#define I2S_SD 13
#define I2S_SCK 2
#define I2S_PORT I2S_NUM_0

#include "arduinoFFT.h"
 
#define SAMPLES 512                 //Must be a power of 2
#define SAMPLING_FREQUENCY 2000    //Hz, must be less than 10000 due to ADC   //Frequencia mais alta esperada dobrada

arduinoFFT FFT = arduinoFFT();
 
unsigned int sampling_period_us;
unsigned long microseconds;
 
double vReal[SAMPLES];
double vImag[SAMPLES];

void setup() {
  Serial.begin(115200);
  sampling_period_us = round(1000000*(1.0/SAMPLING_FREQUENCY));
  i2s_install();
  i2s_setpin();
  i2s_start(I2S_PORT);
}

void loop() {
  int32_t samples = 512;
  int bytes = i2s_pop_sample(I2S_PORT, (char*)&samples, portMAX_DELAY);
   /*SAMPLING*/
    for(int i=0; i<SAMPLES; i++)
    {
        microseconds = micros();    //Overflows after around 70 minutes!
     
        vReal[i] = bytes;
        vImag[i] = 0;
     
        while(micros() < (microseconds + sampling_period_us)){
        }
    }
 
    /*FFT*/
    FFT.Windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.Compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.ComplexToMagnitude(vReal, vImag, SAMPLES);
    double peak = FFT.MajorPeak(vReal, SAMPLES, SAMPLING_FREQUENCY);
 
    /*PRINT RESULTS*/
    Serial.print("xp - "); Serial.println(peak);  //Print out what frequency is the most dominant.
    delayMicroseconds(sampling_period_us);
  
}

void i2s_install(){
  const i2s_config_t i2s_config = {
    .mode = i2s_mode_t(I2S_MODE_MASTER | I2S_MODE_RX),
    .sample_rate = 44100,
    .bits_per_sample = i2s_bits_per_sample_t(16),
    .channel_format = I2S_CHANNEL_FMT_ONLY_LEFT,
    .communication_format = i2s_comm_format_t(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_MSB),
    .intr_alloc_flags = 0, // default interrupt priority
    .dma_buf_count = 8,
    .dma_buf_len = SAMPLES,
    .use_apll = false
  };

  i2s_driver_install(I2S_PORT, &i2s_config, 0, NULL);
}

void i2s_setpin(){
  const i2s_pin_config_t pin_config = {
    .bck_io_num = I2S_SCK,
    .ws_io_num = I2S_WS,
    .data_out_num = -1,
    .data_in_num = I2S_SD
  };

  i2s_set_pin(I2S_PORT, &pin_config);
}

Hi,

What do you mean?
Does the arduinoFFT library work on the ESP32?
A circuit diagram would also help?
What are you using for your test signal?
Do you have a scope?

Tom.... :smiley: :+1: :coffee: :australia:

What does "not working" mean?

Explain what you expect to happen, and what happens instead.

I need the sound frequency picked up by this microphone to be returned. It just leaves a default value, I think it's a code problem. I did the separate microphone test and it's working..

I need the sound frequency picked up by this microphone to be returned. It just leaves a default value, I think it's a code problem. I did the separate microphone test and it's working

This won't do you any good, if the calculation is not working as expected. Print out the spectrum to see what it looks like.

Please tell us what "sound frequency" you expect, and why.

Show us a sample of the waveform as well.

But you are not using the ADC. You have setup the I2C for

I am not sure if the way you put the I2S samples into the FFT buffer will work. So I would test this by sending the FFT buffer to the serial plotter to see if you are getting a waveform, before worrying about what the FFT produces.

As I mentioned in the first thread you made, do yourself a favour and use ArduinoSound library, it has FFTAnalyzer library with example Arduino - FFTAnalyzerClass

This library needs boards that I don't have and to import to Brazil is very expensive. I found one, but I'm not sure it's compatible..

I made the change, but only 1 value is still coming out...

From that board page it looks like it is trying to pass for Arduino Zero, which should be ok for the library

You can try if you can afford it, in the worst case you end up with SAMD21 board and it is a really good MCU

I don't think you did.
Did you try outputting the buffer as a waveform?
There is no need to have a delay because the data is coming from the I2C, this is setting the sample rate not any delay.

The data was coming out correctly, when I put the FFT it didn't work.

On second thought, I ordered one exactly like that out of curiousity, so will let you know