kosme / arduinoFFT

Fast Fourier Transform for Arduino
GNU General Public License v3.0
551 stars 157 forks source link

MEMS + ESP32 + FFT #34

Closed prisikarm closed 5 years ago

prisikarm commented 5 years ago

Hello, I am trying to use SPH0645 MEMS microphone with ESP32, but what I get on the output is just the wrong number.

Here is the code that I am using:

#include <WiFi.h>
#include "driver/i2s.h"
#include <arduinoFFT.h>
arduinoFFT FFT = arduinoFFT(); /* Create FFT object */

const int BLOCK_SIZE = 1024;
const double samplingFrequency = 10000;
double vReal[BLOCK_SIZE];
double vImag[BLOCK_SIZE];
int32_t samples[BLOCK_SIZE];

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_32BIT,
channel_format: I2S_CHANNEL_FMT_ONLY_LEFT,
communication_format: (i2s_comm_format_t)(I2S_COMM_FORMAT_I2S | I2S_COMM_FORMAT_I2S_LSB),
intr_alloc_flags: ESP_INTR_FLAG_LEVEL1,
  dma_buf_count: 8,
dma_buf_len : BLOCK_SIZE
};

i2s_pin_config_t pin_config = {
  .bck_io_num = 5, //this is BCK pin
  .ws_io_num = 18, // this is LRCK pin
  .data_out_num = I2S_PIN_NO_CHANGE, // this is DATA output pin
  .data_in_num = 4   //DATA IN
};
const int i2s_num = 0;
int retStat = 0;
int32_t sampleIn = 0;

void setup()
{
  Serial.begin(115200);
  WiFi.mode(WIFI_OFF);
  //Set up pin 19 for data IN from the Mic to the esp32
  pinMode(4, INPUT);
  //Set up pin 21 and 25 as the BCK and LRCK pins
  pinMode(18, OUTPUT);
  pinMode(5, OUTPUT);
  //Init the i2s device
  i2s_driver_install((i2s_port_t)i2s_num, &i2s_config, 0, NULL);
  i2s_set_pin((i2s_port_t)i2s_num, &pin_config);
  i2s_start((i2s_port_t)i2s_num);
  //This pulls in a bunch of samples and does nothing, its just used to settle the mics output
  for (retStat = 0; retStat < BLOCK_SIZE * 2; retStat++)
  {
    i2s_pop_sample((i2s_port_t)i2s_num, (char*)&sampleIn, portMAX_DELAY);
    delay(1);
  }
}

void loop()
{
  sampleIn = 0;
  for (uint16_t i = 0; i < BLOCK_SIZE; i++)
  {
    //this reads 32bits as 4 chars into a 32bit INT variable
    i2s_pop_sample((i2s_port_t)i2s_num, (char*)&sampleIn, portMAX_DELAY);
    //this pushes out all the unwanted bits as we only need right channel data.
    sampleIn >>= 14;
    vReal[i] = sampleIn;
    vImag[i] = 0.0; //Imaginary part must be zeroed in case of looping to avoid wrong calculations and overflows
  }
  FFT.Windowing(vReal, BLOCK_SIZE, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
  FFT.Compute(vReal, vImag, BLOCK_SIZE, FFT_FORWARD);
  FFT.ComplexToMagnitude(vReal, vImag, BLOCK_SIZE);
  double x;
  double v;
  FFT.MajorPeak(vReal, BLOCK_SIZE, samplingFrequency, &x, &v);
  Serial.print(x, 6);
  Serial.print(", ");
  Serial.println(v, 6);
  delay(2000);
}
kosme commented 5 years ago

You are sampling the audio at 44100 hz but for the FFT calculation you are using the number 10000. Change it to 44100.