Obsah:

QuickFFT: Vysokorychlostní FFT pro Arduino: 3 kroky
QuickFFT: Vysokorychlostní FFT pro Arduino: 3 kroky

Video: QuickFFT: Vysokorychlostní FFT pro Arduino: 3 kroky

Video: QuickFFT: Vysokorychlostní FFT pro Arduino: 3 kroky
Video: QuickFFT: High Speed FFT for Arduino 2024, Červen
Anonim
QuickFFT: Vysokorychlostní FFT pro Arduino
QuickFFT: Vysokorychlostní FFT pro Arduino

Typické Arduino má omezenou RAM a výpočetní výkon a FFT je výpočetně náročný proces. U mnoha aplikací v reálném čase je jediným požadavkem získat frekvenci s maximální amplitudou nebo požadovanou pro detekci frekvenčních špiček.

V jednom ze svých instrukcí jsem připravil kód pro FFT, který najdete zde: EasyFFT

Tento kód byl schopen provést FFT až 128 vzorků na Arduino nano. Vyšší číslo vzorku než toto není možné kvůli omezené paměti Arduina. Funkci jsem trochu upravil, abych zvýšil rychlost a snížil spotřebu paměti. Tato úprava umožňuje Arduinu provádět FFT pětkrát rychleji a spotřebovává téměř poloviční paměť. Tento Instructable nezahrnuje práci FFT, odkazy na něj lze nalézt na EasyFFT.

Krok 1: Práce

Pracovní
Pracovní
Pracovní
Pracovní
Pracovní
Pracovní
Pracovní
Pracovní

Typická funkce FFT je upravena tak, aby zlepšovala rychlost s menší přesností. Jak je znázorněno na obrázku, testovací signál musí být vynásoben sinusovými nebo kosinovými křivkami. Tyto hodnoty mohou být mezi 0 až 1, takže plovoucí násobení je nutností. v Arduinu je plovoucí násobení pomalé ve srovnání s celočíselnými operacemi.

V této funkci je sinusová/kosinová vlna nahrazena čtvercovou vlnou. Protože musíme vynásobit testovací signál čtvercovou vlnou, která může mít hodnotu 0, 1 nebo -1. Díky tomu můžeme nahradit plovoucí násobení jednoduše celočíselným sčítáním nebo odčítáním. U Arduina je sčítání nebo odčítání celých čísel přibližně 5krát rychlejší. Díky tomu je řešení přibližně 5krát rychlejší.

Díky této úpravě nyní mohou být hodnoty frekvenčního bin uloženy jako celé číslo (což bylo dříve plovoucí) a získáváme další výhodu nižší spotřeby paměti. V Arduino Nano spotřebuje int 2 bajty paměti, zatímco float spotřebuje 4 bajty paměti. Díky této výhodě v novém kódu jsme schopni provést FFT pro téměř 256 vzorků (dříve 128 vzorků).

V normálním FFT jsme potřebovali uložit hodnotu sinus, aby bylo řešení rychlejší. V nové funkci, protože již nepotřebujeme hodnoty sinus/kosinus, ji můžeme eliminovat a ušetřit paměť.

Implementace:

Implementace této funkce je přímočará. Funkci můžeme jednoduše zkopírovat do souboru kódu. Tuto funkci lze provést pomocí níže uvedeného příkazu:

float f = Q_FFT (data, 256, 100); Ve funkci Q_FFT, data: tento termín je pole mající hodnoty signálu, doporučená velikost vzorku je 2, 4, 8, 32, 64, 128, 256, 512, … dále. pokud velikost vzorku nepatří k těmto hodnotám, bude oříznuta na nejbližší nižší stranu hodnot. například pokud je velikost vzorku 75, provede se FFT pro 64 čísel vzorků. Maximální počet vzorků je omezen dostupnou RAM na Arduinu.

Druhý termín určuje počet vzorků v poli a poslední termín je vzorkovací frekvence v Hz.

Krok 2: Kód

Tato část vysvětluje úpravy provedené v kódu EasyFFT, které je třeba mít na paměti při provádění změn v kódu, 1. Jak již bylo vysvětleno dříve, zde se k FFT používají celá čísla. Int v Arduinu je 16bitové číslo a může obsahovat hodnoty od -32768 do 32768. kdykoli hodnota tohoto int přesáhne tento rozsah, způsobí to problém. k odstranění tohoto problému po výpočtu všech úrovní. pokud některá z hodnot překročí 15 000, bude kompletní pole děleno 100. zabrání se tím přetečení int.

2. Výpočet amplitudy: Pro výpočet amplitudy je třeba umocnit skutečnou a imaginární část a vyžaduje odmocninu součtu. kvadratura a odmocnina funkce je časově náročná. aby byl proces rychlejší, tento kód jednoduše udělá některé velikosti skutečných a imaginárních částí. To je jistě méně přesné a v některých případech to může vést ke špatnému závěru. můžete se rozhodnout vrátit se k normální metodě pro výpočet velikosti, ale zabere to více času a také musíte udělat nějaké uspořádání pro uložení těchto čísel.

3. Tento kód nemá modul pro detekci více píků. Jednoduše zvolí hodnotu s maximální amplitudou (kromě prvního čísla, které je DC offset). Pokud potřebujete více píků, můžete se obrátit na kód EasyFFT a provést zde požadovanou úpravu. V takovém případě musí být některé pole/proměnná také deklarováno jako globální proměnná.

4. Funkce obsahuje následující řádek:

unsigned int Pow2 [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

deklarace výše uvedených proměnných jako globální proměnné (vložení na začátek kódu) ušetří při každém spuštění někde 1 milisekundu času.

5. Na rozdíl od funkce EasyFFT, kde bylo prvních 5 vrcholů uloženo v předdefinovaném poli. Tato funkce vrátí plovoucí hodnotu. tato hodnota představuje frekvenci s maximální amplitudou v Hz. Reprezentace kódu tedy bude vypadat nějak takto.

float f = Q_FFT (data, 256, 100);

6. Detekce špiček: Jakmile je nalezena frekvence s maximální amplitudou, tato funkce používá k výpočtu přesných výsledků amplitudu frekvence těsně před a za ní. Amplituda použitá v tomto výpočtu je také součtem modulu (ne odmocninou součtu čtverců)

pokud Fn je frekvence s maximální amplitudou, pak lze frekvenci vypočítat z níže uvedeného vzorce.

Skutečné F = (A n-1 *Fn-1+An-1 *Fn-1+An-1 *Fn-1) / (An-1+An+An+1)

kde An je amplituda n frekvence a Fn-1 je hodnota frekvence.

Krok 3: Výsledky:

Výsledek
Výsledek
Výsledek
Výsledek

Doba řešení je uvedena ve výše uvedeném porovnání obrázků s EasyFFT. Rychlost je ukázána při srovnání.

Pro ukázková data jsou uvedena 3 sinusová vlnění s různými frekvencemi. Výsledek z QuickFFT je porovnán s výstupem Scilab. Jak vidíme na obrázku, 3 vrcholy s maximální amplitudou odpovídají výstupu Scilab. Výstup se však skládá ze spousty šumu, což může být u některých aplikací zavádějící. Doporučuje se tedy před přihlášením do aplikace řádně zkontrolovat kód.

Doufám, že jste našli tento kód užitečný pro váš projekt. V případě jakýchkoli dotazů nebo návrhů prosím napište komentář.

Doporučuje: