Obsah:

QuickFFT: Vysokorýchlostný FFT pre Arduino: 3 kroky
QuickFFT: Vysokorýchlostný FFT pre Arduino: 3 kroky

Video: QuickFFT: Vysokorýchlostný FFT pre Arduino: 3 kroky

Video: QuickFFT: Vysokorýchlostný FFT pre Arduino: 3 kroky
Video: FFT su Arduino 2024, Jún
Anonim
QuickFFT: Vysokorýchlostný FFT pre Arduino
QuickFFT: Vysokorýchlostný FFT pre Arduino

Typické Arduino má obmedzenú RAM a výpočtový výkon a FFT je výpočtovo náročný proces. V prípade mnohých aplikácií v reálnom čase je jedinou požiadavkou získanie frekvencie s maximálnou amplitúdou alebo požadované na detekciu frekvenčných špičiek.

V jednom zo svojich pokynov som pripravil kód pre FFT, ktorý nájdete tu: EasyFFT

Tento kód bol schopný vykonať FFT až 128 vzoriek na Arduino nano. Vyššie číslo vzorky nie je možné z dôvodu obmedzenej pamäte Arduina. Funkciu som trochu upravil, aby som zvýšil rýchlosť a znížil spotrebu pamäte. Táto úprava umožňuje Arduinu vykonávať FFT päťkrát rýchlejšie a spotrebuje takmer polovicu pamäte. Tento návod sa nevzťahuje na FFT, odkazy naň nájdete na EasyFFT.

Krok 1: Práca

Pracovné
Pracovné
Pracovné
Pracovné
Pracovné
Pracovné
Pracovné
Pracovné

Typická funkcia FFT je upravená tak, aby zlepšovala rýchlosť s menšou presnosťou. Ako je znázornené na obrázku, testovací signál je potrebné vynásobiť sínusovými alebo kosínusovými priebehmi. Tieto hodnoty môžu byť od 0 do 1, takže plávajúce násobenie je nevyhnutné. v Arduine je plávajúce násobenie pomalé v porovnaní s celočíselnými operáciami.

V tejto funkcii je sínusová/kosínusová vlna nahradená štvorcovou vlnou. Pretože musíme vynásobiť testovací signál štvorcovou vlnou, ktorá môže mať hodnotu 0, 1 alebo -1. Vďaka tomu môžeme nahradiť plávajúce násobenie jednoduchým celočíselným sčítaním alebo odčítaním. Pri Arduine je sčítanie alebo odčítanie celých čísel asi 5 -krát rýchlejšie. Riešenie je tak asi 5 -krát rýchlejšie.

Vďaka tejto úprave je teraz možné hodnoty frekvenčného bin uložiť ako celé číslo (čo bolo predtým float) a získame ďalšiu výhodu nižšej spotreby pamäte. V Arduino Nano int spotrebuje 2 bajty pamäte, zatiaľ čo float spotrebuje 4 bajty pamäte. Vďaka tejto výhode v novom kóde sme schopní vykonať FFT pre takmer 256 vzoriek (predtým 128 vzoriek).

V normálnom FFT sme potrebovali uložiť sínusovú hodnotu, aby bolo riešenie rýchlejšie. V novej funkcii, pretože už nepotrebujeme hodnoty sínus/kosínus, ju môžeme odstrániť a ušetriť pamäť.

Implementácia:

Implementácia tejto funkcie je priamočiara. Túto funkciu môžeme jednoducho skopírovať do súboru kódu. Túto funkciu je možné vykonať pomocou nižšie uvedeného príkazu:

float f = Q_FFT (dáta, 256, 100); Vo funkcii Q_FFT,

údaje: tento výraz je pole so hodnotami signálu, odporúčaná veľkosť vzorky je od 2, 4, 8, 32, 64, 128, 256, 512, … ďalej. ak veľkosť vzorky nepatrí k týmto hodnotám, bude orezaná na najbližšiu dolnú stranu hodnôt. napríklad ak je veľkosť vzorky 75, FFT sa vykoná pre 64 čísel vzoriek. Maximálny počet vzoriek je obmedzený dostupnou RAM v Arduine.

Druhý výraz určuje počet vzoriek v poli a posledný termín je vzorkovacia frekvencia v Hz.

Krok 2: Kód

Táto časť vysvetľuje úpravu vykonanú v kóde EasyFFT, ktorú je potrebné mať na pamäti pri vykonávaní úpravy v kóde, 1. Ako už bolo vysvetlené, tu sa na FFT používajú celé čísla. Int in Arduino je 16 -bitové číslo a môže obsahovať hodnoty od -32768 do 32768. vždy, keď hodnota tohto int presiahne tento rozsah, spôsobuje to problém. na odstránenie tohto problému po výpočte úrovne. ak niektorá z hodnôt presiahne 15 000, kompletné polia sa vydelia 100. tým sa zabráni pretečeniu súboru.

2. Výpočet amplitúdy: Na výpočet amplitúdy je potrebné, aby bola skutočná a imaginárna časť na druhú a aby bola odmocnina súčtu. kvadratúry a odmocnina funkcie zaberie čas. aby bol proces rýchlejší, tento kód jednoducho urobí niektoré veľkosti skutočných a imaginárnych častí. To je určite menej presné a v niektorých prípadoch to môže viesť k nesprávnemu záveru. Môžete sa rozhodnúť vrátiť sa k normálnej metóde na výpočet veľkosti, ale bude to trvať dlhšie a musíte tiež urobiť nejaké opatrenia na uloženie týchto čísel.

3. Tento kód nemá modul na detekciu viacnásobných špičiek. Jednoducho vyberie hodnotu s maximálnou amplitúdou (bez prvého čísla, ktoré je DC offset). Ak potrebujete viac špičiek, môžete sa obrátiť na kód EasyFFT a vykonať tu požadovanú úpravu. V takom prípade musí byť niektoré pole/premenná tiež deklarované ako globálna premenná.

4. Funkcia obsahuje nasledujúci riadok:

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

ak deklarujete vyššie uvedené premenné ako globálnu premennú (prilepíte ju na začiatok kódu), pri každom spustení sa ušetrí niekde 1 milisekundový čas.

5. Na rozdiel od funkcie EasyFFT, kde bolo prvých 5 píkov uložených vo vopred definovanom poli. Táto funkcia vráti pohyblivú hodnotu. táto hodnota predstavuje frekvenciu s maximálnou amplitúdou v Hz. Reprezentácia kódu bude teda vyzerať takto.

float f = Q_FFT (dáta, 256, 100);

6. Detekcia píku: Akonáhle je nájdená frekvencia s maximálnou amplitúdou, táto funkcia používa na výpočet presných výsledkov amplitúdu frekvencie tesne pred a za ňou. Amplitúda použitá v tomto výpočte je tiež súčtom modulu (nie druhou odmocninou súčtu druhých mocnín)

ak Fn je frekvencia s maximálnou amplitúdou, potom môže byť frekvencia vypočítaná z nižšie uvedeného vzorca.

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

kde An je amplitúda n frekvencie a Fn-1 je hodnota frekvencie.

Krok 3: Výsledky:

Výsledky
Výsledky
Výsledky
Výsledky

Čas riešenia je zobrazený na obrázku vyššie v porovnaní s EasyFFT. Rýchlosť je uvedená pri porovnaní.

Pre vzorové údaje sú uvedené 3 sínusové vlny s rôznymi frekvenciami. Výsledok z QuickFFT je porovnaný s výstupom Scilab. Ako vidíme na obrázku, 3 vrcholy s maximálnou amplitúdou sa zhodujú s výstupom Scilab. Výstup však obsahuje veľa hluku, ktorý môže byť pre niektoré aplikácie zavádzajúci. Pred aplikáciou do vašej aplikácie sa preto odporúča poriadne skontrolovať kód.

Dúfam, že ste našli tento kód užitočný pre váš projekt. V prípade akýchkoľvek otázok alebo návrhov prosím napíšte komentár.

Odporúča: