Jump to content

    
Sign in to follow this  
roma-cezar

STM32 FFT (БПФ)

Recommended Posts

Всем добрый день!

Недавно начал знакомство с библиотекой fft для DSP ядра arm_cfft_radix4_f32 STM32F3 и его АЦП соответственно.

Поглядел пример, решил запустить свою программку которая берет сигнал с АЦП и выдает график спектра сигнала.

Сперва просто попробовал выдавать осциллограмму, с чем успешно справился, все правильно измеряет.

 

Параметры для получения спектра следующие.

 

На вход ацп подаю сигнал от 0 до 1000 Гц с цифрового генератора.

Сигнал смещен в положительную сторону, изменяется от 0 до 3 вольта. Амплитуда сигнала постоянная. Вход АЦП пока напрямую подключен к выходу генератора витой парой.

 

Частота выборки АЦП задается по таймеру - 2048 Гц далее через DMA все кладу в буфер. Получаю 2048 отсчетов на канал. Sample rate на канал АЦП - 7,5 циклов.

Количество отсчетов БПФ - 1024 дискретность 1 герц

 

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

 

IQW9b-uC9qQ.jpg

(С матаном и теорией по БПФ не дружу особо только поверхностно, заранее прошу прощения за что-то глупое.)

В чем моя ошибка?

Edited by Роман

Share this post


Link to post
Share on other sites
..при оцифровке сигнал теряет амплитуду пропорционально графику sin(x)/x , чем ближе к fсэмпл тем меньше.

С какого перепугу? Амплитуду теряют образы из высших зон Найквиста. При частоте сигнала, меньшей половины частоты дискретизации, амплитуда меняться не должна. Искать глюк в программе

Share this post


Link to post
Share on other sites
..при оцифровке сигнал теряет амплитуду пропорционально графику sin(x)/x , чем ближе к fсэмпл тем меньше.

 

Только не при оцифровке, а при обратном процессе, а так все верно:)))

 

С какого перепугу? Амплитуду теряют образы из высших зон при несоблюдении теоремы Котельникова. При частоте сигнала, меньшей половины частоты дискретизации, амплитуда меняться не должна. Искать глюк в программе

 

Вот и мне интересно, с какого это перепугу теряется амплитуда образов из высших зон при несоблюдении теоремы Котельникова??? Мы все еще про АЦП говорим? Или Вы так образно назвали ослабление сигнала на пару дБ в пределах полосы пропускания АЦП, которая, к слову, обычно в разы больше максимальной частоты дискретизации?

 

И вопрос для ТС: что из себя представляет Ваш "цифровой генератор"? Можете показать осциллограммы, соответствующие трем Вашим рисункам со спектром?

 

Share this post


Link to post
Share on other sites
И вопрос для ТС: что из себя представляет Ваш "цифровой генератор"? Можете показать осциллограммы, соответствующие трем Вашим рисункам со спектром?

 

 

Генератор такой, только модель немного другая

2aedd6a1960f3e674b9ecfc38a408f42.jpg

 

Сейчас показать осциллограммы не могу. В ПН могу снять повторно, перепроверить. Но вчера, когда тестировал, снимал синус и выводил его на комп, амплитуда оставалась такой же, как задано на генераторе сигналов во всей полосе 0 - 1 кГц (АЦП вроде как боле 5 MSPS хватит за глаза для такой частоты). Падение амплитуды от частоты происходит после БПФ.

 

еще я при получении данных с ацп сразу их нормализовывал и приводил к вольтам в тип float, после передавал в БПФ функцию. Но на выходе получаю какие то попугаи.

Edited by Роман

Share this post


Link to post
Share on other sites

FFT "не в ту сторону" ?

Подайте постоянный код вместо АЦП - должна появиться постоянная составляющая на нулевой частоте

Edited by Genadi Zawidowski

Share this post


Link to post
Share on other sites
FFT "не в ту сторону" ?

Подайте постоянный код вместо АЦП - должна появиться постоянная составляющая на нулевой частоте

Пост сост-ая есть слева, но плохо отрисовывается, она 720 единиц (попугаев).

Сегодня переделал немного, отображаю спектр с зеркальной частью от 0 до 512 Гц. Частоты 100, 300, 400 Гц. На 500 гц сходится в один спектр в зеркальной части

получаю такую картину

8P7a-SCOR18.jpg

 

Далее с графиком синус. сигнала, оцифрованный АЦП его гармоники.

10 Гц, 100 и 300 Гц. Амплитуда синусоиды постоянная, при переводе в вольты все точно получается.

post-66719-1534742969_thumb.jpg

post-66719-1534742985_thumb.jpg

post-66719-1534743012_thumb.jpg

 

Суммирование частот 10 и 200 гц

post-66719-1534745880_thumb.jpg

Edited by Роман

Share this post


Link to post
Share on other sites

Значит, проблема в рисовании спектра. Палки должны быть одинаковые.

Я бы предположил, что амплитуда сигнала теряется из-за фильтра на входе АЦП, но, похоже, нет.

Share this post


Link to post
Share on other sites
Значит, проблема в рисовании спектра. Палки должны быть одинаковые.

Я бы предположил, что амплитуда сигнала теряется из-за фильтра на входе АЦП, но, похоже, нет.

Да должно быть. Но нет((((

Вот кусок кода где получаю выход fftOutput

#define ADC_BUFF_SIZE 				2048

#define FFT_IN_BUFF_SIZE  			2048 
#define FFT_OUT_BUFF_SIZE 			1024

#define UTX_BUFF_SIZE				(4096)+2

uint16_t ADC_BUFF[ADC_BUFF_SIZE];
float32_t fftOutput[FFT_OUT_BUFF_SIZE] = {0};	
float32_t fftInput[FFT_IN_BUFF_SIZE] = {0}; 

uint32_t fftSize = 1024; 
uint32_t ifftFlag = 0; 
uint32_t doBitReverse = 1;
arm_cfft_radix4_instance_f32 S; 

for(uint16_t i=0; i<(ADC_BUFF_SIZE/2); i++)
{
fftInput[i] = ((float32_t)(ADC_BUFF[(i*2)]));
}
arm_cfft_radix4_init_f32(&S, fftSize, ifftFlag, doBitReverse); 
arm_cfft_radix4_f32(&S, fftInput); 
arm_cmplx_mag_f32(fftInput, fftOutput,  fftSize); 

 

Уже при отладке вижу в fftOutput что основная гармоника и ее зеркальное отображение имеют разные значения.

Edited by Роман

Share this post


Link to post
Share on other sites

На входные данные еще нужно окно наложить, их много разных есть. Края массива приглушить, там же обрывается синус. Может, в этом дело? Хотя, симметрия с зеркальным спектром должна сохраняться.

 

А откуда берутся float32_t данные от АЦП? Их же преобразовать надо, а не к типу привести.

Share this post


Link to post
Share on other sites
На входные данные еще нужно окно наложить, их много разных есть. Края массива приглушить, там же обрывается синус. Может, в этом дело? Хотя, симметрия с зеркальным спектром должна сохраняться.

 

А откуда берутся float32_t данные от АЦП? Их же преобразовать надо, а не к типу привести.

Нашел ошибку, не вписал часть равную 0 в массив fftInput

for(uint16_t i=0; i<(ADC_BUFF_SIZE/2); i++)

{

fftInput[i*2] = ((float32_t)(ADC_BUFF[(i*2)+ curr_adc_ch ])) / (float32_t)4096.0;

fftInput[(i*2)+1] = 0.0;

}

постоянная составляющая - 0 гармоника показывает величину смещения сигнала 1,5 вольт примерно.

Магнитуда синуса i-ой гармоники почему то показывает 0,8 в вместо 1,6 вольт - в 2 раза меньше. так и должно быть?

Edited by Роман

Share this post


Link to post
Share on other sites

Теперь у меня слудующий вопрос. Запустил FFT с частотой дискр. АЦП 2048 Гц. Получаю 1024 выборки сигнала. Частотный диапазон сигнала на входе 500 - 1000 Гц. Получаю ряд амплитуд с частотами с шагом 2 Гц (511 точек) При отрисовке вижу, что если на вход ацп подать четное значение частоты, то амплитуда отрисовывается нормально, а если ytчетное, то амплитуда занижена на треть.

Edited by Роман

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Sign in to follow this