Hello,
I am trying to use ESP32 and SPH0645 microphone in order to analyze the frequency by Fast Fourier Transformation library, but there is the error I receive during compilation:
MEMS_mic:125:26: error: invalid types 'int32_t {aka int}[uint16_t {aka short unsigned int}]' for array subscript
vReal[i] = sampleIn[i] << 8;
^
invalid types 'int32_t {aka int}[uint16_t {aka short unsigned int}]' for array subscript
Here is my code:
#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
// dma_buf_len: 64
};
// Configure whatever pins you have available and make sure you set them up with PiNmode() Before setting up i2s system
i2s_pin_config_t pin_config = {
.bck_io_num = 25, //this is BCK pin
.ws_io_num = 26, // this is LRCK pin
.data_out_num = I2S_PIN_NO_CHANGE, // this is DATA output pin
.data_in_num = 23 //DATA IN
};
const int i2s_num=0;
int retStat = 0;
int32_t sampleIn=0, avgGain=0, peaks[2]={0,0}, avgSampleIn=0;
unsigned short int numOfBlanks=2000, smoothingReads=10;
void setup()
{
Serial.begin(115200);
//Turn off WIFI to save power
WiFi.mode(WIFI_OFF);
//Set up pin 19 for data IN from the Mic to the esp32
pinMode(23, INPUT);
//Set up pin 21 and 25 as the BCK and LRCK pins
pinMode(26, OUTPUT);
pinMode(25, 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);
Serial.print("\r\nBegin Level detect...");
Serial.print("\r\n\tRead 4000 samples to level out...");
//This pulls in a bunch of samples and does nothing, its just used to settle the mics output
for(retStat=0; retStat<numOfBlanks*2; retStat++)
{
i2s_pop_sample((i2s_port_t)i2s_num, (char*)&sampleIn, portMAX_DELAY);
delay(1);
}
//Pull in x number of samples (IN A QUITE ENVIRONMENT) and create the base gain average(the zero point for the mic)
Serial.print("\r\n\tRead 2000 samples to get avg...");
for(retStat=0; retStat<numOfBlanks; retStat++)
{
i2s_pop_sample((i2s_port_t)i2s_num, (char*)&sampleIn, portMAX_DELAY);
sampleIn>>=14;
avgGain -= sampleIn;
delay(1);
}
avgGain = avgGain/numOfBlanks;
Serial.printf("\t\tAVG Gain=\t%i", avgGain);
peaks[0]=avgGain;
peaks[1]=-avgGain;
Serial.printf("\r\n\tSetting MAX gain to\t%i\tMin Gain to\t%i\r\n", peaks[0], peaks[1]);
delay(1000);
}
void loop()
{
sampleIn=0;
avgSampleIn=0;
//read in smoothingReads number of times and use the average
for(retStat=0; retStat<smoothingReads; retStat++)
{
//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;
avgSampleIn+=sampleIn;
}
sampleIn = round((float)avgSampleIn/smoothingReads);
for (uint16_t i = 0; i < BLOCK_SIZE; i++) {
vReal[i] = sampleIn[i] << 8;
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);
}