Я пробовал использовать библиотеку CMSIS DSP для реализации БПФ на STM32F407. Я основывал свой проект на Тилен Майерле библиотека. Я отбираю данные с помощью встроенного АЦП и заполняю входной буфер функцией 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 Гц. Но меня это не сильно смущает.
Такая же картина наблюдается и для других частотных диапазонов и частот дискретизации.
Теперь я вижу, что единственное прямое решение - это математически привести мои результаты в соответствие с реальными измеренными значениями. Но это не изящное решение. Очень вероятно, что я пренебрегаю некоторыми важными особенностями анализа DSP FFT и не понимаю математический алгоритм. Другие реализации БПФ мне не так понятны. И действительно ли имеет смысл использовать другие библиотеки, например kissFFT и так далее? Кто имеет опыт работы с другими библиотеками и будет рад поделиться им со мной? Любой совет приветствуется.
2.0*0.7071067812/(float)(FFT->FFT_Size);
Здесь вы смешиваетеfloat
иdouble
. Какова точностьdouble
в вашей системе и что происходит, когда вы усекаете его доfloat
? - person Lundin   schedule 10.10.20192.0
, на константы с плавающей запятой2.0f
. Если вы вызываете стандартные библиотеки C, убедитесь, что вы вызываете функции с плавающей запятой, а не двойные. - person Lundin   schedule 10.10.2019