Съдържание:

QuickFFT: Високоскоростен FFT за Arduino: 3 стъпки
QuickFFT: Високоскоростен FFT за Arduino: 3 стъпки

Видео: QuickFFT: Високоскоростен FFT за Arduino: 3 стъпки

Видео: QuickFFT: Високоскоростен FFT за Arduino: 3 стъпки
Видео: QuickFFT: High Speed FFT for Arduino 2024, Юни
Anonim
QuickFFT: Високоскоростен FFT за Arduino
QuickFFT: Високоскоростен FFT за Arduino

Типичният Arduino има ограничена RAM и изчислителна мощност, а FFT е изчислително интензивен процес. За много приложения в реално време единственото изискване е да се получи честота с максимална амплитуда или да се изисква за откриване на честотни пикове.

В една от моите инструкции подготвих код за FFT, който може да се намери тук: EasyFFT

Този код успя да извърши FFT до 128 проби на Arduino nano. По -голям брой проби от това не е възможно поради ограничената памет на Arduino. Промених функцията малко, за да подобря скоростта и да намаля консумацията на памет. Тази модификация позволява на Arduino да изпълнява FFT пет пъти по -бързо и консумира почти половината памет. Тази инструкция не обхваща работата на FFT, препратките към нея могат да бъдат намерени в EasyFFT.

Стъпка 1: Работа

Работещи
Работещи
Работещи
Работещи
Работещи
Работещи
Работещи
Работещи

Типичната функция FFT е модифицирана, за да се подобри скоростта с по -малка точност. Както е показано на изображението, тестовият сигнал трябва да се умножи по синусоидална или косинусна форма на вълната. Тези стойности могат да бъдат между 0 до 1, така че плаващото умножение е задължително. в Arduino плаващото умножение е бавно в сравнение с целочислените операции.

При тази функция вълната синус/косинус се заменя с квадратна вълна. Тъй като трябва да умножим тестовия сигнал с квадратна вълна, която може да има стойност 0, 1 или -1. Поради това можем да заменим плаващото умножение с просто цялостно събиране или изваждане. За Arduino целочисленото събиране или изваждане е около 5 пъти по -бързо. Това прави решаването около 5 пъти по -бързо.

Поради тази модификация сега стойностите на честотния контейнер могат да се съхраняват като цяло число (което преди беше плаващо) и получаваме друго предимство от по -ниската консумация на памет. В Arduino Nano int консумира 2 байта памет, докато float консумира 4 байта памет. Поради това предимство в новия код, ние сме в състояние да извършим FFT за почти 256 проби (преди това 128 проби).

В Normal FFT трябваше да съхраняваме синусовата стойност, за да направим решението по -бързо. В новата функция, тъй като вече не се изискват стойности на синус/косинус, можем да го премахнем и да спестим малко памет.

Изпълнение:

Изпълнението на тази функция е направо напред. Можем просто да копираме функцията в следния код. Тази функция може да бъде изпълнена с помощта на следната команда:

float f = Q_FFT (данни, 256, 100); Във функция Q_FFT, данни: този термин е масив със стойности на сигнала, препоръчителният размер на извадката е 2, 4, 8, 32, 64, 128, 256, 512, … нататък. ако размерът на извадката не принадлежи на тези стойности, тя ще бъде подрязана до най -близката долна страна на стойностите. например, ако размерът на извадката е 75, FFT ще се извърши за 64 броя проби. Максималният размер на извадката е ограничен от наличната RAM на Arduino.

Вторият термин определя броя на извадките в масив, а последният термин е честотата на дискретизация в Hz.

Стъпка 2: Код

Този раздел обяснява промените, направени в кода на EasyFFT, които трябва да се имат предвид, докато се правят промени в кода, 1. Както беше обяснено по -рано, тук цели числа се използват за FFT. Int в Arduino е 16 -битово число и може да съдържа стойности от -32768 до 32768. когато стойността на този int надвишава този диапазон, това причинява проблема. за премахване на този проблем след изчисляване на ниво. ако някоя от стойностите надвишава 15000, пълните масиви ще бъдат разделени на 100. това ще предотврати препълването на int.

2. Изчисляване на амплитудата: За да се изчисли амплитудата, реалната и въображаемата част трябва да бъдат на квадрат и е необходим квадратният корен от сумата. квадратиране и квадратния корен на функцията отнема време. за да ускори процеса, този код просто ще направи някои от величините на реални и въображаеми части. Това със сигурност е по -малко точно и в някои случаи може да доведе до грешен извод. можете да изберете да се върнете към нормалния метод за изчисляване на величината, но това ще отнеме повече време и също така трябва да направите някакво подреждане, за да съхраните тези числа.

3. Този код няма модул за откриване на множество пикове. Той просто ще избере стойността с максимална амплитуда (с изключение на първото число, което е DC отместване). Ако имате нужда от множество пикове, можете да се обърнете към кода на EasyFFT и да направите необходимата промяна тук. В този случай някои масиви/променливи също трябва да бъдат декларирани като глобална променлива.

4. Функцията съдържа следния ред:

без знак int Pow2 [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

декларирането на горните променливи като глобална променлива (поставянето им в началото на кода) ще спести някъде 1 милисекунда време при всяко изпълнение.

5. За разлика от функцията EasyFFT, където първите 5 пика се съхраняват в предварително дефинирания масив. Тази функция ще върне плаваща стойност. тази стойност представлява честотата с максимална амплитуда в Hz. Така че представянето на кода ще изглежда така.

поплавък f = Q_FFT (данни, 256, 100);

6. Откриване на пик: След като бъде намерена честота с максимална амплитуда, тази функция използва амплитуда на честотата непосредствено преди и след нея, за да изчисли точните резултати. Амплитудата, използвана в това изчисление, също е сумата от модула (а не квадратен корен от сумата от квадрати)

ако Fn е честотата с максимална амплитуда, тогава честотата може да бъде изчислена от формулата по -долу.

Действително F = (A n-1 *Fn-1+An-1 *Fn-1+An-1 *Fn-1) / (An-1+An+An+1)

където An е амплитуда на n честотата и Fn-1 е честотна стойност.

Стъпка 3: Резултати:

Резултати
Резултати
Резултати
Резултати

Времето за решаване е показано в горното сравнение на изображението с EasyFFT. Скоростта му е показана при сравнението.

За примерни данни са показани 3 синусоидални вълни с различни честоти. Резултатът от QuickFFT се сравнява с изхода на Scilab. Както можем да видим на изображението, 3 пика с максимална амплитуда съвпадат с изхода на Scilab. Изходът обаче се състои от много шум, което може да бъде подвеждащо за някои приложения. Затова се препоръчва да проверите правилно кода, преди да кандидатствате за кандидатурата си.

Надявам се, че сте намерили този код за полезен за вашия проект. В случай на запитване или предложение, моля, коментирайте.

Препоръчано: