Измерению уровня библиотеки CMSIS DSP FFT не хватает точности - PullRequest
0 голосов
/ 10 октября 2019

Я пытался использовать библиотеку CMSIS DSP для реализации FFT на STM32F407. Я основал свой проект на библиотеке Tilen MaJerle . Я собираю данные с помощью встроенного АЦП и заполняю входной буфер функцией TM_FFT_AddToBuffer (TM_FFT_F32_t * FFT, float32_t sampleValue). Далее я обрабатываю данные с помощью функции TM_FFT_Process_F32 (TM_FFT_F32_t * FFT).

uint8_t TM_FFT_AddToBuffer(TM_FFT_F32_t* FFT, float32_t sampleValue) {
/* Check if memory available */
if (FFT->Count < FFT->FFT_Size) {
    /* Add to buffer, real part */
    FFT->Input[2 * FFT->Count] = sampleValue;
    /* Imaginary part set to 0 */
    FFT->Input[2 * FFT->Count + 1] = 0;

    /* Increase count */
    FFT->Count++;
}

/* Check if buffer full */
if (FFT->Count >= FFT->FFT_Size) {
    /* Buffer full, samples ready to be calculated */
    return 1;
}

/* Buffer not full yet */
return 0;
}

и

void TM_FFT_Process_F32(TM_FFT_F32_t* FFT) {
uint16_t iCntr = 0;
float coeff = 2.0*0.7071067812/(float)(FFT->FFT_Size);

/* Process FFT input data */
arm_cfft_f32(FFT->S, FFT->Input, 0, 1);

/* Process the data through the Complex Magniture Module for calculating the magnitude at each bin */
arm_cmplx_mag_f32(FFT->Input, FFT->Output, FFT->FFT_Size);  

for (iCntr = 1; iCntr < (FFT->FFT_Size); iCntr++) 
    FFT->Output[iCntr] *= coeff; //high-order harmonics values - magnitude

FFT->Output[0] /= (float)FFT->FFT_Size; //dc component value 

/* Reset count */   
FFT->Count = 0;
}

Я добавил несколько простых преобразований в функции TM_FFT_Process_F32 (...), направленных на регулировку уровня гармоник,Конечно, когда я исключаю их и использую оригинальный код Tilen, я получаю тот же результат.

Как видите, я попробовал функции arm_cfft_f32 (…) и arm_cmplx_mag_f32 (…). Я также попробовал функцию arm_rfft_fast_f32 (…) для своих целей и получил тот же результат.

Моя проблема в точности вычисления величины. Моя задача состоит в том, чтобы получить точные расчеты уровня заданных гармоник. Я измеряю чистый синусоидальный сигнал переменного тока со смещением постоянного тока на входе АЦП с помощью вольтметра. Затем я измеряю частоту сигнала с помощью FFT lib и получаю снижение уровня сигнала с увеличением частоты. Я принимаю во внимание ограничения, касающиеся максимальной измеренной частоты для данной частоты дискретизации, и этот факт, я не могу использовать более 4096 выборок с CMSIS DSP FFT. Мне также нужен небольшой шаг частоты, например, 1 Гц для диапазона от 100 до 1000 Гц.

На данной фотографии я показываю вам результаты. Кстати, частота измеряется с некоторой ошибкой. 100 Гц определяется как 101 Гц, 800 Гц - как 808 Гц. Но это меня не сильно смущает.

Синяя линия измеряется вольтметром переменного тока. Красная линия - мои измерения с библиотекой FFT. Частота дискретизации 4096 Гц, количество выборок - 4096

Та же картина достигается для других частотных диапазонов и частот дискретизации.

Теперь я вижу, что единственное лобовое решение - математическинастроить мои результаты на реальные измеренные значения. Но это не элегантное решение. Вполне вероятно, что я пренебрегаю некоторыми важными функциями анализа БПФ DSP и не понимаю математического алгоритма. Другие реализации БПФ мне не так понятны. И действительно ли имеет смысл использовать другие библиотеки, например, kissFFT и так далее? Кто доказал свой опыт работы с другими библиотеками и хотел бы поделиться им со мной? Любой совет высоко ценится.

...