Sisukord:

QuickFFT: kiire FFT Arduino jaoks: 3 sammu
QuickFFT: kiire FFT Arduino jaoks: 3 sammu

Video: QuickFFT: kiire FFT Arduino jaoks: 3 sammu

Video: QuickFFT: kiire FFT Arduino jaoks: 3 sammu
Video: FFT in Data Analysis (Fast Fourier Transform) 2024, November
Anonim
QuickFFT: kiire FFT Arduino jaoks
QuickFFT: kiire FFT Arduino jaoks

Tüüpilisel Arduinol on piiratud RAM ja töötlemisvõimsus ning FFT on arvutusmahukas protsess. Paljude reaalajas kasutatavate rakenduste puhul on ainus nõue saada maksimaalse amplituudiga või sageduse piikide tuvastamiseks vajalik sagedus.

Ühes juhendis koostasin FFT jaoks koodi, mille leiate siit: EasyFFT

See kood suutis Arduino nano abil teostada kuni 128 proovi FFT. Sellest suurem proovide arv pole Arduino piiratud mälu tõttu võimalik. Kiiruse parandamiseks ja mälutarbimise vähendamiseks olen funktsiooni veidi muutnud. See muudatus võimaldab Arduino'l teostada FFT viis korda kiiremini ja kulutab peaaegu pool mälu. See juhend ei hõlma FFT töötamist, viiteid selle kohta leiate veebisaidilt EasyFFT.

Samm: töö

Töötab
Töötab
Töötab
Töötab
Töötab
Töötab
Töötab
Töötab

Tüüpilist FFT -funktsiooni muudetakse kiiruse parandamiseks väiksema täpsusega. Nagu pildil näidatud, tuleb testisignaal korrutada siinus- või koosinuslainekujuga. Need väärtused võivad olla vahemikus 0 kuni 1, seega on ujuva korrutamise tegemine kohustuslik. Arduinos on ujuv korrutamine täisarvude toimingutega võrreldes aeglane.

Selle funktsiooni korral asendatakse siinus/koosinuslaine ruutlainega. Kuna peame testisignaali korrutama ruutlainega, mille väärtus võib olla 0, 1 või -1. Tänu sellele saame ujuva korrutamise asendada lihtsalt täisarvu liitmise või lahutamisega. Arduino täisarvude liitmine või lahutamine on umbes 5 korda kiirem. See muudab lahendamise umbes 5 korda kiiremaks.

Selle muudatuse tõttu saab nüüd sagedusala väärtusi salvestada täisarvuna (mis oli varem ujuv) ja saame veel ühe eelise väiksema mälutarbimise kohta. Arduino Nano puhul tarbib int 2 baiti mälu, float aga 4 baiti mälu. Selle eelise tõttu uues koodis suudame teostada FFT peaaegu 256 proovi jaoks (varem 128 proovi).

Tavalises FFT -s pidime lahenduse kiiremaks muutmiseks salvestama siinusväärtuse. Uue funktsiooni puhul, kuna me ei vaja enam siinus-/koosinusväärtusi, saame selle kõrvaldada ja salvestada mälu.

Rakendamine:

Selle funktsiooni rakendamine on lihtne. Funktsiooni saame lihtsalt koodi koodis kopeerida. Seda funktsiooni saab täita järgmise käsu abil:

float f = Q_FFT (andmed, 256, 100); Funktsioonis Q_FFT

andmed: see termin on signaaliväärtustega massiiv, soovitatav valimi suurus on 2, 4, 8, 32, 64, 128, 256, 512,… ja edasi. kui valimi suurus ei kuulu nende väärtuste hulka, lõigatakse see väärtuste alumisele küljele. Näiteks kui valimi suurus on 75, viiakse FFT läbi 64 proovi jaoks. Proovi suuruse maksimaalset arvu piirab Arduino vaba RAM.

Teine termin määrab proovide arvu massiivis ja viimane mõiste on diskreetimissagedus Hz.

2. samm: kood

Selles jaotises selgitatakse EasyFFT -koodis tehtud muudatusi, mida tuleb koodi muutmise ajal meeles pidada, 1. Nagu eelnevalt selgitatud, kasutatakse siin FFT tegemiseks täisarvu. Int in Arduino on 16 -bitine arv ja võib sisaldada väärtusi vahemikus -32768 kuni 32768. kui selle int väärtus ületab seda vahemikku, põhjustab see probleemi. selle probleemi kõrvaldamiseks pärast kunagi taseme arvutamist. kui mõni väärtustest ületab 15000, jagatakse täismassiivid 100 -ga. see hoiab ära int -i ületäitumise.

2. Amplituudi arvutamine: amplituudi arvutamiseks tuleb tegelik ja kujuteldav osa ruudutada ning nõuda summa ruutjuurt. ruutimine ja funktsiooni ruutjuur võtab aega. protsessi kiirendamiseks teeb see kood lihtsalt reaalsete ja kujuteldavate osade suuruse. See on kindlasti vähem täpne ja võib mõnel juhul teha vale järelduse. võite naasta suurusjärgu arvutamiseks tavalise meetodi juurde, kuid see võtab rohkem aega ja peate ka nende numbrite salvestamiseks midagi ette võtma.

3. Sellel koodil puudub moodul mitme piigi tuvastamiseks. See valib lihtsalt maksimaalse amplituudiga väärtuse (välja arvatud esimene arv, mis on alalisvoolu nihe). Kui vajate mitut piiki, saate siin viidata EasyFFT -koodile ja teha vajalikke muudatusi. Sellisel juhul tuleb mõni massiiv/muutuja deklareerida ka globaalse muutujana.

4. Funktsioon sisaldab järgmist rida:

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

ülaltoodud muutujate globaalse muutujana deklareerimine (selle kleepimine koodi algusesse) säästab igal täitmisel kuskil 1 millisekundit.

5. Erinevalt funktsioonist EasyFFT, kus 5 parimat piiki salvestati eelnevalt määratletud massiivi. See funktsioon tagastab ujuva väärtuse. see väärtus tähistab sagedust maksimaalse amplituudiga Hz. Seega näeb koodi esitus välja umbes selline.

ujuk f = Q_FFT (andmed, 256, 100);

6. Peak Detection: kui on leitud maksimaalse amplituudiga sagedus, kasutab see funktsioon täpsete tulemuste arvutamiseks sageduse amplituudi vahetult enne ja pärast seda. Selles arvutuses kasutatud amplituud on samuti mooduli summa (mitte ruutude summa ruutjuur)

kui Fn on maksimaalse amplituudiga sagedus, saab sageduse arvutada allpool toodud valemi järgi.

Tegelik F = (A n-1 *Fn-1+An-1 *Fn-1+An-1 *Fn-1) / (An-1+An+An+1)

kus An on sageduse amplituud n ja Fn-1 on sageduse väärtus.

3. samm: Tulemused:

Tulemused
Tulemused
Tulemused
Tulemused

Lahendusaeg on näidatud ülaltoodud piltide võrdluses EasyFFT -ga. Selle kiirust näidati võrdlusega.

Näidisandmete jaoks on näidatud 3 erineva sagedusega sinusoidaalset lainet. QuickFFT -i tulemust võrreldakse Scilabi väljundiga. Nagu pildilt näeme, sobivad 3 maksimaalse amplituudiga piiki Scilabi väljundiga. Väljund sisaldab aga palju müra, mis võib mõne rakenduse puhul olla eksitav. Seetõttu on soovitatav enne rakendusele kandideerimist koodi korralikult kontrollida.

Loodan, et leidsite selle koodi oma projekti jaoks kasulikuks. Küsimuste või soovituste korral palun kommenteerige.

Soovitan: