I'm working on a project on my ESP32s3, trying to correctly evaluate the maximum frequency of an input signal. I've performed my fft basing my code on the FFT dsp example on ESP-IDF. Actually I generate the signal inside my code, sampling it at a very high frequency. The signal i generate has his peak frequency at 5Hz, but the code I wrote gives back values way higher than this peak frequency. It might be important to mention that the Default fft size that i'm using is 4096.
This is the code that i use to generate the signal
double composite_signal(double t, SignalComponent *component) {
double signal = 0;
// Summing sine components
for (int i = 0; i < component->num_sin_components; i++) {
signal += component->sin_amplitudes[i] * sin(2 * M_PI * component->sin_frequencies[i] * t);
}
return signal;
}
SignalComponent component = {
2, // Number of sine components
{3,5}, // Sine frequencies in HZ
{2,4} // Sine amplitudes
};
//AND IN THE MAIN
for (int i = 0; i < NUM_SAMPLES; i++) {
double t = (double)i / SAMPLING_RATE;
wave[i] = composite_signal(t, &component);
//ESP_LOGI(TAG, "FFT for %f ", wave[i]);
}
Those are the rates i'm using
#define SAMPLING_RATE 1000 // Hz
#define DURATION 3 // seconds
#define NUM_SAMPLES (SAMPLING_RATE * DURATION)
#define TH 3 //threshold for magnitude, max frequency of the fft
Then I process the FFT as it is done in the dsp ESP IDF example
dsps_wind_hann_f32(wind, NUM_SAMPLES);
// Generate input signal for x1 A=1 , F=0.1
// dsps_tone_gen_f32(x1, N, 1.0, 0.1, 0);
// for(int i=0; i<N;i++){
// ESP_LOGI(TAG, "Signal at index %i is %f", i, x1[i]);
// }
// Generate input signal for x2 A=0.1,F=0.2
//dsps_tone_gen_f32(x2, N, 0.1, 0.2, 0);
// Convert two input vectors to one complex vector
for (int i = 0 ; i < NUM_SAMPLES ; i++) {
y_cf[i * 2] = wave[i] * wind[i];
y_cf[i * 2 + 1] = 0; // I don't have a second vector as in the example
}
// FFT
unsigned int start_b = dsp_get_cpu_cycle_count();
dsps_fft2r_fc32(y_cf, NUM_SAMPLES);
unsigned int end_b = dsp_get_cpu_cycle_count();
// Bit reverse
dsps_bit_rev_fc32(y_cf, NUM_SAMPLES);
// Convert one complex vector to two complex vectors
dsps_cplx2reC_fc32(y_cf, NUM_SAMPLES);
//RETRIEVE THE MAX FREQ OF THE SIGNAL
int maxI = 0;
double maxM = 0;
for (int i = 0; i < NUM_SAMPLES; i++)
{
if(y_cf[i]>TH && y_cf[i]>maxM){
maxI = i;
maxM = y_cf[i];
}
}
ESP_LOGI(TAG, "THE MAX Index is %i", maxI);
float maxF = maxI;
maxF *= SAMPLING_RATE / (float) NUM_SAMPLES; //max frequency retrival
Then the example code does some adjustment in order to display the signals correctly. Obviously here I'm expecting that the max frequency should be something around 5Hz. But in the output I'm getting: I (22594) main: THE MAX Index is 1838 I (22944) main: The maximum frequency of the signal is 612.666687, and the relative magnitude value is 564.219421.
I've been following various guides and I think that is the proper way to get the max frequency. Can somebody tell me what I'm doing wrong ?
I eventually found out that the FFT needs in input an array of a dimension that has to be expressible as a power of 2.