Cuprins:

QuickFFT: FFT de mare viteză pentru Arduino: 3 pași
QuickFFT: FFT de mare viteză pentru Arduino: 3 pași
Anonim
QuickFFT: FFT de mare viteză pentru Arduino
QuickFFT: FFT de mare viteză pentru Arduino

Arduino tipic are RAM și putere de procesare limitate, iar FFT este un proces intens din punct de vedere al calculului. Pentru multe aplicații în timp real, singura cerință este obținerea frecvenței cu amplitudine maximă sau necesară pentru detectarea vârfurilor de frecvență.

Într-una dintre instrucțiunile mele, am pregătit un cod pentru FFT care poate fi găsit aici: EasyFFT

Acest cod a fost capabil să efectueze FFT de până la 128 de eșantioane pe Arduino nano. Un număr de eșantion mai mare decât acesta nu este posibil datorită memoriei limitate a Arduino. Am modificat puțin funcția pentru a îmbunătăți viteza și a reduce consumul de memorie. Această modificare permite Arduino să efectueze FFT de cinci ori mai rapid și consumă aproape jumătate de memorie. Acest instructabil nu acoperă funcționarea FFT, referințe pentru acesta pot fi găsite la EasyFFT.

Pasul 1: Lucrul

Lucru
Lucru
Lucru
Lucru
Lucru
Lucru
Lucru
Lucru

Funcția tipică FFT este modificată pentru a îmbunătăți viteza cu o precizie mai mică. După cum se arată în imagine, un semnal de test trebuie să fie înmulțit cu forme de undă sinusoidală sau cosinus. Aceste valori pot fi cuprinse între 0 și 1, deci realizarea multiplicării plutitoare este o necesitate. în Arduino, multiplicarea plutitoare este lentă în comparație cu operațiile întregi.

În această funcție, unda sinusoidală / cosinus este înlocuită de o undă pătrată. Deoarece trebuie să înmulțim un semnal de testare cu o undă pătrată care poate avea valoarea 0, 1 sau -1. Datorită acestui fapt, putem înlocui înmulțirea plutitoare cu simpla adunare sau scădere întreagă. Pentru Arduino, adunarea sau scăderea numărului întreg este de aproximativ 5 ori mai rapidă. Acest lucru face ca rezolvarea de aproximativ 5 ori mai rapidă.

Datorită acestei modificări, acum valorile coșului de frecvență pot fi stocate ca un număr întreg (care anterior era plutitor) și obținem un alt avantaj al consumului de memorie mai mic. În Arduino Nano, int consumă 2 octeți de memorie în timp ce float consumă 4 octeți de memorie. Datorită acestui avantaj al noului cod, putem realiza FFT pentru aproape 256 de eșantioane (anterior 128 de eșantioane).

În FFT normal, trebuia să stocăm valoarea sinusoidală pentru a face o soluție mai rapidă. În funcția nouă, întrucât nu mai sunt necesare valori sinusoidale / cosinus, o putem elimina și economisi niște memorie.

Implementare:

Implementarea acestei funcții este simplă. Putem pur și simplu să copiem funcția în codul ens. Această funcție poate fi executată folosind comanda de mai jos:

float f = Q_FFT (date, 256, 100); În funcția Q_FFT, date: acest termen este o matrice cu valori ale semnalului, dimensiunea recomandată a eșantionului este de 2, 4, 8, 32, 64, 128, 256, 512,… în continuare. dacă dimensiunea eșantionului nu aparține acestor valori, aceasta va fi tăiată la cea mai apropiată parte inferioară a valorilor. de exemplu, dacă dimensiunea eșantionului este de 75, se va efectua FFT pentru 64 de numere de eșantioane. Numărul maxim de dimensiuni ale eșantionului este limitat de memoria RAM disponibilă pe Arduino.

Al doilea termen specifică numărul de eșantioane dintr-o matrice, iar ultimul termen este frecvența de eșantionare în Hz.

Pasul 2: Cod

Această secțiune explică modificarea făcută în codul EasyFFT care trebuie să fie luată în considerare în timp ce efectuați modificări în cod, 1. După cum s-a explicat anterior, aici se utilizează numere întregi pentru a face FFT. Int în Arduino este un număr de 16 biți și poate conține valori de la -32768 la 32768. ori de câte ori valoarea acestui int depășește acest interval provoacă problema. pentru a elimina această problemă după calculul nivelului. dacă oricare dintre valori depășește 15000 de tablouri complete vor fi împărțite la 100. acest lucru va împiedica revărsarea int.

2. Calculul amplitudinii: Pentru a calcula amplitudinea, partea reală și imaginară trebuie să fie pătrată și este necesară rădăcina pătrată a sumei. pătratul și rădăcina pătrată a funcției este luarea de timp. pentru a face procesul mai rapid, acest cod va face pur și simplu unele dintre magnitudinile părților reale și imaginare. Acest lucru este cu siguranță mai puțin precis și poate duce la o concluzie greșită în unele cazuri. puteți alege să reveniți la metoda normală pentru calculul mărimii, dar va dura mai mult timp și trebuie, de asemenea, să faceți unele aranjamente pentru a stoca aceste numere.

3. Acest cod nu are un modul pentru detectarea vârfurilor multiple. Va alege pur și simplu valoarea cu amplitudine maximă (cu excepția primului număr care este offset DC). Dacă aveți nevoie de mai multe vârfuri, puteți consulta codul EasyFFT și puteți face modificările necesare aici. În acest caz, unele matrice / variabile trebuie, de asemenea, declarate ca variabile globale.

4. Funcția conține următoarea linie:

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

declararea variabilelor de mai sus ca o variabilă globală (lipirea la începutul codului) va economisi undeva 1 milisecundă de timp la fiecare execuție.

5. Spre deosebire de funcția EasyFFT, unde primele 5 vârfuri au fost stocate în matricea predefinită. Această funcție va returna o valoare float. această valoare reprezintă frecvența cu amplitudine maximă în Hz. Deci, reprezentarea codului va arăta cam așa.

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

6. Detectarea vârfurilor: Odată ce frecvența cu amplitudine maximă este găsită, această funcție utilizează o amplitudine de frecvență chiar înainte și după ea pentru a calcula rezultatele exacte. Amplitudinea utilizată în acest calcul este, de asemenea, suma modulului (nu rădăcina pătrată a sumei pătratelor)

dacă Fn este frecvența cu amplitudine maximă, atunci frecvența poate fi calculată din formula de mai jos.

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

unde An este amplitudinea n frecvenței și Fn-1 este valoarea frecvenței.

Pasul 3: Rezultate:

Rezultate
Rezultate
Rezultate
Rezultate

Timpul de rezolvare este prezentat în comparația de imagine de mai sus cu EasyFFT. Viteza acestuia indicată în comparație.

Pentru datele eșantionului sunt prezentate 3 unde sinusoidale cu frecvențe diferite. Rezultatul de la QuickFFT este comparat cu ieșirea Scilab. După cum putem vedea în imagine, 3 vârfuri cu amplitudine maximă se potrivesc cu ieșirea Scilab. Cu toate acestea, ieșirea constă din mult zgomot, care poate fi înșelător pentru unele aplicații. Așadar, este recomandat să verificați corect codul înainte de a aplica la cererea dvs.

Sper că ați găsit acest cod util pentru proiectul dvs. În cazul oricărei întrebări sau sugestii, vă rugăm să comentați.

Recomandat: