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;
}

 

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

0 REPLIES 0