cancel
Showing results for 
Search instead for 
Did you mean: 

FFT on Array outputting incorrect value.

mattsparksy
Visitor

Hi there, I'm attempting to run an FFT on a sine wave input with frequencies from 0.1-1Hz however i seem to be getting incorrect frequencies from my FFT. Any help would be appreciated. 

 

#include "main.h"

/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
#include <stdio.h>
#include <string.h>
#include "arm_math.h"
/* USER CODE END Includes */

/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN PTD */

/* USER CODE END PTD */

/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
#define SAMPLE_RATE 200 // Adjust the sample rate (samples per second)
#define DURATION 12     // Duration in seconds
#define TOTAL_SAMPLES (SAMPLE_RATE * DURATION)
#define FFT_SIZE 1024   // Define FFT size (must be a power of 2)

/* USER CODE END PD */

/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */

/* USER CODE END PM */

/* Private variables ---------------------------------------------------------*/
ADC_HandleTypeDef hadc1;

UART_HandleTypeDef huart2;

/* USER CODE BEGIN PV */
uint16_t lux =0;
char msg[20];

uint32_t lux_values[TOTAL_SAMPLES];
float32_t fft_input[FFT_SIZE * 2];
float32_t fft_output[FFT_SIZE];
/* USER CODE END PV */

/* Private function prototypes -----------------------------------------------*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_ADC1_Init(void);
static void MX_USART2_UART_Init(void);
/* USER CODE BEGIN PFP */
void PerformFFT(void);

/* USER CODE END PFP */

/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */

/**
  * @brief  The application entry point.
  * @retval int
  */
int main(void)
{
  /* USER CODE BEGIN 1 */

  /* USER CODE END 1 */

  /* MCU Configuration--------------------------------------------------------*/

  /* Reset of all peripherals, Initializes the Flash interface and the Systick. */
  HAL_Init();

  /* USER CODE BEGIN Init */

  /* USER CODE END Init */

  /* Configure the system clock */
  SystemClock_Config();

  /* USER CODE BEGIN SysInit */

  /* USER CODE END SysInit */

  /* Initialize all configured peripherals */
  MX_GPIO_Init();
  MX_ADC1_Init();
  MX_USART2_UART_Init();
  /* USER CODE BEGIN 2 */
  char buffer[64];
  uint32_t start_time = HAL_GetTick();
  uint32_t index = 0;
  /* USER CODE END 2 */

  /* Infinite loop */
  /* USER CODE BEGIN WHILE */
  while ((HAL_GetTick() - start_time) < (DURATION * 1000) && index < TOTAL_SAMPLES) {
      HAL_ADC_Start(&hadc1);
      HAL_ADC_PollForConversion(&hadc1, HAL_MAX_DELAY);
      lux_values[index] = HAL_ADC_GetValue(&hadc1);

      snprintf(buffer, sizeof(buffer), "Light Intensity: %lu\r\n", lux_values[index]);
      HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);

      index++;
      HAL_Delay(1000 / SAMPLE_RATE);
  }

  snprintf(buffer, sizeof(buffer), "Data collection done. Performing FFT...\r\n");
  HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);

  PerformFFT();

  while (1) {}
}
    /* USER CODE END WHILE */

    /* USER CODE BEGIN 3 */
void PerformFFT(void)
{
    arm_rfft_fast_instance_f32 fft_instance;
    arm_rfft_fast_init_f32(&fft_instance, FFT_SIZE);

    for (uint32_t i = 0; i < FFT_SIZE; i++) {
        fft_input[i] = (i < TOTAL_SAMPLES) ? (float32_t)lux_values[i] : 0.0f;
    }

    arm_rfft_fast_f32(&fft_instance, fft_input, fft_output, 0);

    float32_t magnitudes[FFT_SIZE / 2];
    for (uint32_t i = 0; i < FFT_SIZE / 2; i++) {
        float32_t real = fft_output[2 * i];
        float32_t imag = fft_output[2 * i + 1];
        magnitudes[i] = sqrtf(real * real + imag * imag);
    }

    float32_t max_value = 0;
    uint32_t max_index = 1; // Start from 1 to avoid DC component
    for (uint32_t i = 1; i < (FFT_SIZE / 2); i++) {
        if (magnitudes[i] > max_value) {
            max_value = magnitudes[i];
            max_index = i;
        }
    }

    float32_t bin_resolution = (float32_t)SAMPLE_RATE / (float32_t)FFT_SIZE;
    float32_t dominant_frequency = max_index * bin_resolution;

    char buffer[64];
    snprintf(buffer, sizeof(buffer), "Dominant Frequency: %.2f Hz\r\n", dominant_frequency);
    HAL_UART_Transmit(&huart2, (uint8_t*)buffer, strlen(buffer), HAL_MAX_DELAY);
}

 

0 REPLIES 0