Kazalo:

QuickFFT: Hitri FFT za Arduino: 3 koraki
QuickFFT: Hitri FFT za Arduino: 3 koraki

Video: QuickFFT: Hitri FFT za Arduino: 3 koraki

Video: QuickFFT: Hitri FFT za Arduino: 3 koraki
Video: How does an EMI Receiver work? 2024, November
Anonim
QuickFFT: Hitri FFT za Arduino
QuickFFT: Hitri FFT za Arduino

Tipičen Arduino ima omejen RAM in procesorsko moč, FFT pa je računalniško zahteven proces. Za številne aplikacije v realnem času je edina zahteva, da dobite frekvenco z največjo amplitudo ali zahtevate odkrivanje frekvenčnih vrhov.

V enem od mojih navodil sem pripravil kodo za FFT, ki jo najdete tukaj: EasyFFT

Ta koda je lahko izvedla FFT do 128 vzorcev na Arduino nano. Večje število vzorcev od tega ni mogoče zaradi omejenega pomnilnika Arduina. Funkcijo sem nekoliko spremenil, da bi izboljšal hitrost in zmanjšal porabo pomnilnika. Ta sprememba omogoča Arduinu petkrat hitrejše izvajanje FFT in porabi skoraj polovico pomnilnika. Ta navodila ne zajemajo dela FFT, reference zanj so na voljo na EasyFFT.

1. korak: Delo

Delo
Delo
Delo
Delo
Delo
Delo
Delo
Delo

Tipična funkcija FFT je spremenjena za izboljšanje hitrosti z manjšo natančnostjo. Kot je prikazano na sliki, je treba testni signal pomnožiti s sinusno ali kosinusno valovno obliko. Te vrednosti so lahko med 0 in 1, zato je plavajoče množenje nujno. v Arduinu je plavajoče množenje počasno v primerjavi s celoštevilčnimi operacijami.

Pri tej funkciji se sinusni/kosinusni val nadomesti s kvadratnim. Ker moramo testni signal pomnožiti s kvadratnim valom, ki ima lahko vrednost 0, 1 ali -1. Zaradi tega lahko plavajoče množenje zamenjamo na preprosto celoštevilčno seštevanje ali odštevanje. Za Arduino je celovito seštevanje ali odštevanje približno 5 -krat hitrejše. Tako je rešitev približno 5 -krat hitrejša.

Zaradi te spremembe lahko zdaj vrednosti frekvenčnega bina shranimo kot celo število (ki je bilo prej plavajoče) in dobimo še eno prednost manjše porabe pomnilnika. V Arduino Nano int porabi 2 bajta pomnilnika, float pa 4 bajte pomnilnika. Zaradi te prednosti v novi kodi lahko izvedemo FFT za skoraj 256 vzorcev (prej 128 vzorcev).

V normalnem FFT smo morali za hitrejšo rešitev shraniti sinusno vrednost. V novi funkciji, ker ne potrebujemo več sinusnih/kosinusnih vrednosti, jo lahko odpravimo in prihranimo nekaj pomnilnika.

Izvajanje:

Izvajanje te funkcije je naravnost. Funkcijo lahko preprosto kopiramo po kodi. To funkcijo lahko izvedete z naslednjim ukazom:

float f = Q_FFT (podatki, 256, 100); V funkciji Q_FFT,

podatki: ta izraz je matrika z vrednostmi signala, priporočena velikost vzorca je 2, 4, 8, 32, 64, 128, 256, 512, … in več. če velikost vzorca ne pripada tem vrednostim, bo izrezan na najbližjo spodnjo stran vrednosti. na primer, če je velikost vzorca 75, se za 64 številk vzorcev izvede FFT. Največje število vzorcev je omejeno z razpoložljivim RAM -om na Arduinu.

Drugi izraz določa število vzorcev v nizu, zadnji izraz pa je frekvenca vzorčenja v Hz.

2. korak: Koda

Ta razdelek pojasnjuje spremembe, narejene v kodi EasyFFT, ki jih je treba upoštevati pri spreminjanju kode, 1. Kot je bilo že pojasnjeno, se tukaj za štetje FFT uporabljajo cela števila. Int in Arduino je 16 -bitno število in lahko vsebuje vrednosti od -32768 do 32768. kadar vrednost tega int preseže to območje, povzroči težavo. odpraviti to težavo po vsakem izračunu ravni. če katera koli vrednost presega 15000, bodo celotni nizi deljeni s 100. to bo preprečilo prelivanje int.

2. Izračun amplitude: Za izračun amplitude je treba realni in namišljeni del kvadrirati in zahtevati kvadratni koren vsote. kvadrata in kvadratni koren funkcije vzame čas. da bo postopek hitrejši, bo ta koda preprosto naredila nekaj velikosti resničnih in namišljenih delov. To je vsekakor manj natančno in lahko v nekaterih primerih privede do napačnega zaključka. za izračun velikosti se lahko odločite za vrnitev k običajni metodi, vendar bo trajalo več časa, zato morate tudi shraniti te številke.

3. Ta koda nima modula za zaznavanje več vrhov. Preprosto bo izbral vrednost z največjo amplitudo (razen prve številke, ki je odmik DC). Če potrebujete več vrhov, se lahko obrnete na kodo EasyFFT in tukaj naredite potrebno spremembo. V tem primeru je treba tudi določeno polje/spremenljivko razglasiti kot globalno spremenljivko.

4. Funkcija vsebuje naslednjo vrstico:

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

razglasitev zgornjih spremenljivk za globalno spremenljivko (lepljenje na začetku kode) bo prihranilo nekje 1 milisekundo časa pri vsaki izvedbi.

5. Za razliko od funkcije EasyFFT, kjer je bilo prvih 5 vrhov shranjenih v vnaprej določeni matriki. Ta funkcija vrne plavajočo vrednost. ta vrednost predstavlja frekvenco z največjo amplitudo v Hz. Tako bo predstavitev kode videti nekako tako.

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

6. Zaznavanje vrha: Ko je frekvenca z največjo amplitudo najdena, ta funkcija uporabi amplitudo frekvence tik pred njo in za njo za izračun natančnih rezultatov. Amplituda, uporabljena v tem izračunu, je tudi vsota modula (ne kvadratni koren vsote kvadratov)

če je Fn frekvenca z največjo amplitudo, potem lahko frekvenco izračunamo iz spodnje formule.

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

kjer je An amplituda n frekvence in Fn-1 vrednost frekvence.

3. korak: Rezultati:

Rezultati
Rezultati
Rezultati
Rezultati

Čas reševanja je prikazan v zgornji primerjavi slike z EasyFFT. Hitrost je prikazana s primerjavo.

Za vzorčne podatke so prikazani 3 sinusni valovi z različnimi frekvencami. Rezultat QuickFFT primerjamo z izhodom Scilab. Kot lahko vidimo na sliki, se 3 vrhovi z največjo amplitudo ujemajo z izhodom Scilab. Vendar pa izhod vsebuje veliko hrupa, kar je za nekatere aplikacije lahko zavajajoče. Zato je priporočljivo, da pred prijavo na vlogo ustrezno preverite kodo.

Upam, da vam je bila ta koda uporabna za vaš projekt. V primeru kakršnih koli vprašanj ali predlogov prosim za komentar.

Priporočena: