cancel
Showing results for 
Search instead for 
Did you mean: 

Help with Cmsis_DSP fft and wrong frequencies detected

RafaelJureg
Associate

I don't know if libopencm3 code is allowed to post here but really isn't that different at all...
I am getting wrong frequencies trying to measure a sine wave of 1.5v amplitude through adc of stm32f411, when  82hz I am getting 7.81, 110hz = 23.44... but when I simulate an 82hz sine wave with the code below, I am getting satisfactory results:

 

for (int i = 0; i < BUFFER_SIZE; i++) { adc_buffer[i] = (uint16_t)(2048 + 2047 * sinf(2 * PI * 82.41 * i / SAMPLE_RATE)); }

 


, I am really FFT noob and probably doing something very ***, anyway here is some important parts of my code:

 

#include "arm_math.h" #include "arm_const_structs.h" #include <stdint.h> #include <stdlib.h> #include <math.h> #include <stdio.h> #define SAMPLE_RATE 8000 #define BUFFER_SIZE 1024 uint16_t adc_buffer[BUFFER_SIZE]; float fft_input[BUFFER_SIZE * 2]; // Interleaved real and imaginary parts float fft_output[BUFFER_SIZE]; void compute_fft(float *input, float *output, int buffer_size) { arm_cfft_instance_f32 fft_instance; if (arm_cfft_init_f32(&fft_instance, buffer_size) != ARM_MATH_SUCCESS) { return; } arm_cfft_f32(&fft_instance, input, 0, 1); arm_cmplx_mag_f32(input, output, buffer_size); } float find_fundamental_frequency(float *fft_output, int buffer_size) { float max_value = 0.0f; int max_index = 0; for (int i = 1; i < buffer_size / 2; i++) { if (fft_output[i] > max_value) { max_value = fft_output[i]; max_index = i; } } return (float)max_index * SAMPLE_RATE / buffer_size; } void capture_adc_data(uint16_t *buffer, int size) { for (int i = 0; i < size; i++) { adc_start_conversion_regular(ADC1); while (!adc_eoc(ADC1)); buffer[i] = adc_read_regular(ADC1); } } int main(void) { rcc_clock_setup_pll(&rcc_hse_25mhz_3v3[RCC_CLOCK_3V3_84MHZ]); adc_setup(); usart_setup(); char output_buffer[50]; while (1) { capture_adc_data(adc_buffer, BUFFER_SIZE); for (int i = 0; i < BUFFER_SIZE; i++) { float sample = (float)adc_buffer[i] / 4096.0f - 0.5f; fft_input[2 * i] = (float)adc_buffer[i] / 4096.0f - 0.5f; fft_input[2 * i + 1] = 0.0f; } compute_fft(fft_input, fft_output, BUFFER_SIZE); float fundamental_frequency = find_fundamental_frequency(fft_output, BUFFER_SIZE); snprintf(output_buffer, sizeof(output_buffer), "Freq: %.2f Hz\r\n", fundamental_frequency); usart_send_string(output_buffer); } return 0; }
View more

 

 my raw adc values seem to be right what can could be happening?

0 REPLIES 0