INHOUDSOPGAWE:

EasyFFT: Fast Fourier Transform (FFT) vir Arduino: 6 stappe
EasyFFT: Fast Fourier Transform (FFT) vir Arduino: 6 stappe

Video: EasyFFT: Fast Fourier Transform (FFT) vir Arduino: 6 stappe

Video: EasyFFT: Fast Fourier Transform (FFT) vir Arduino: 6 stappe
Video: Curso Básico em C# - Arrays (vetores) - Aula 7 2024, November
Anonim
Image
Image

Meting van frekwensie vanaf die vasgelegde sein kan 'n moeilike taak wees, veral op Arduino, aangesien dit 'n laer rekenkrag het. Daar is metodes beskikbaar om nulkruising vas te lê waar die frekwensie vasgelê word deur te kontroleer hoeveel keer die sein nullyne oorskry binne die gegewe tyd. So 'n metode werk moontlik nie as die sein 'n kombinasie van verskillende frekwensies is nie.

Dit is op die een of ander manier moeilik om te kodeer as u nie van so 'n agtergrond af kom nie. Maar as 'n tinkerer, kan hierdie kode baie nuttig wees vir verskillende projekte wat verband hou met musiek, seinanalise. Die motief van hierdie projek was om 'n kode op te stel wat maklik op Arduino geïmplementeer kan word sonder om op die agtergrond daarvan te kom.

Hierdie projek verduidelik nie die werking van FFT nie, maar verduidelik die toepassing van die FFT -funksie. Dieselfde proses word ook in die aangehegte video verduidelik.

As u slegs geïnteresseerd is in die toepassing van kode en nie in 'n verduideliking daarvan nie. U kan direk na stap 3 gaan.

Stap 1: Inleiding tot frekwensie -transformasie

Inleiding tot Frekwensie Transformasie
Inleiding tot Frekwensie Transformasie
Inleiding tot Frekwensie Transformasie
Inleiding tot Frekwensie Transformasie

Enige sein kan bestaan uit 'n kombinasie van verskillende sinusvormige golwe. Elke tydgebaseerde sein kan dus ook as 'n kombinasie van die verskillende sinusse van verskillende amplituden getoon word.

Ek het probeer om die werking van DFT (diskrete Fourier-transform) in een van die vorige instruksies (https://www.instructables.com/id/Arduino-Frequency…) te verduidelik. Hierdie metodes is baie stadig vir enige intydse toepassing. wat dit amper nutteloos maak.

In die prent word 'n sein getoon wat 'n kombinasie is van twee frekwensies f2 en f5. Hierdie sein word vermenigvuldig met toets sinusgolwe van waardes f1 tot f5.

Dit kan wiskundig aangetoon word dat die som van vermenigvuldiging van twee harmoniese datastelle met verskillende frekwensies tot nul neig ('n groter aantal data kan lei tot 'n beslaglegging). In ons geval, as hierdie twee vermenigvuldigingsfrekwensies dieselfde (of baie naby) frekwensie het, is die som van vermenigvuldiging die nulnommer.

Dus, as ons sein vermenigvuldig word met f1, sal die som van vermenigvuldiging nul wees (naby nul vir werklike toepassing). soortgelyk is die geval vir f3, f4. Vir die waarde sal die f2- en f5 -uitset egter nie nul wees nie, maar aansienlik hoër as die res van die waardes.

Hier word 'n sein met 5 frekwensies getoets, dus die sein moet met vyf frekwensies vermenigvuldig word. So 'n intense berekening verg langer tyd. Wiskundig word getoon dat dit vir N aantal monsters N*N komplekse vermenigvuldiging verg.

Stap 2: Fast Fourier -transformasie

Om die berekening van DFT vinniger te maak, is FFT -algoritme ontwikkel deur James Cooley en John Tukey. Hierdie algoritme word ook beskou as een van die belangrikste algoritmes van die 20ste eeu. Dit verdeel 'n sein in 'n vreemde en gelyke volgorde wat 'n aantal vereiste berekeninge verlaag. Deur dit te gebruik, kan die totale vereiste komplekse vermenigvuldiging tot NlogN verminder word. wat 'n aansienlike verbetering is.

U kan die verwysings hieronder verwys waarna ek verwys het tydens die skryf van die kode vir 'n gedetailleerde begrip van die wiskunde agter FFT:

1.

2.

3.

4.

Stap 3: Verklaring van die kode

1. Fast sinus en Cosinus:

Berekening FFT neem die waarde van verskillende sinus en cosinus verskeie kere. Die ingeboude funksie van Arduino is nie vinnig genoeg nie, en dit neem baie tyd om die vereiste waarde te verskaf. Dit maak die kode aansienlik stadiger (tyd verdubbel vir 64 monsters). Om hierdie kwessie teë te werk, word die sinuswaarde van 0 tot 90 grade gestoor as 'n veelvoud van 255. As u dit doen, word die noodsaaklikheid van die gebruik van stoorgetalle as float uitgeskakel. Die sinusdata moet bo -aan die kode plak om dit as 'n globale veranderlike te verklaar.

Afgesien van sine_data, word 'n skikking genaamd f_peaks verklaar as 'n globale veranderlike. Na elke uitvoer van FFT -funksie word hierdie skikking opgedateer. Waar f_peaks [0] die mees dominante frekwensie en verdere waardes in dalende volgorde is.

byte sine_data [91] = {0, 4, 9, 13, 18, 22, 27, 31, 35, 40, 44, 49, 53, 57, 62, 66, 70, 75, 79, 83, 87, 91, 96, 100, 104, 108, 112, 116, 120, 124, 127, 131, 135, 139, 143, 146, 150, 153, 157, 160, 164, 167, 171, 174, 177, 180, 183, 186, 189, 192, 195, 198, 201, 204, 206, 209, 211, 214, 216, 219, 221, 223, 225, 227, 229, 231, 233, 235, 236, 238, 240, 241, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255, 255}; float f_peaks [5];

Aangesien ons die sinuswaarde vir 0 tot 90 grade gestoor het, kan enige sinus- of cosinuswaarde bereken word. Onder funksioneer die eerste ronde van die getal tot nul desimale punt en gee die waarde terug van gestoorde data. hierdie metode benodig slegs een drywende afdeling. Dit kan verder verminder word deur sinuswaardes direk te stoor (nie 255 veelvoudig nie). maar dit vreet Arduino baie geheue op.

Deur die bogenoemde prosedure te gebruik, verminder die akkuraatheid, maar verbeter die snelheid. Vir 64 punte gee dit die voordeel van 8ms en vir 128 punte 'n voordeel van 20ms.

Stap 4: Verklaring van kode: FFT -funksie

FFT kan slegs uitgevoer word vir die steekproefgrootte van 2, 4, 8, 16, 32, 64 ensovoorts. as die waarde nie 2^n is nie, neem dit die onderste kant van die waarde. As ons byvoorbeeld die steekproefgrootte van 70 kies, sal dit slegs die eerste 64 monsters oorweeg en rus uitlaat.

Dit word altyd aanbeveel om 'n steekproefgrootte van 2^n te hê. wat kan wees:

2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, …

Twee vlotte out_r en out_im benodig baie geheue. As gevolg van 'n gebrek aan beskikbare geheue, werk Arduino nano nie vir monsters hoër as 128 (en in sommige gevalle 128) nie.

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

int a, c1, f, o, x; a = N; for (int i = 0; i <12; i ++) // bereken die vlakke {if (data <= a) {o = i;}} int in_ps [data [o] = {}; // invoer vir opeenvolging float out_r [data [o] = {}; // werklike deel van transform float out_im [data [o] = {}; // verbeeldingryke deel van transformasie

Verdere vloei is soos volg:

1. Kode genereer 'n bietjie omgekeerde volgorde vir die gegewe steekproefgrootte (besonderhede oor bitsomkeer op verwysings: stap 2)

2. Invoerdata bestel volgens gegenereerde bestelling, 3. FFT uitgevoer

4. Die amplitude van die komplekse getal bereken, 5. Pieke word in dalende volgorde opgespoor en georden

6. Die resultate kan verkry word vanaf f_peaks.

[om toegang tot ander data (behalwe piekfrekwensie) te verkry, moet die kode gewysig word, sodat die plaaslike veranderlike na 'n voorafbepaalde globale veranderlike gekopieer kan word]

Stap 5: Toets die kode

Toets die kode
Toets die kode
Toets die kode
Toets die kode

'N Voorbeelddriehoekgolf word as invoer gegee. vir hierdie golf is die bemonsteringsfrekwensie 10 Hz en die frekwensie van die golf self is 1,25 Hz.

Soos uit die rou uitset kan blyk, pas die waarde by die FFT bereken deur Scilab. hierdie waardes is egter nie presies dieselfde as ons lae akkuraatheid nie, maar vinniger sinusgolf.

In die uitsetfrekwensie is die skikkingfrekwensie 1,25 en 3,75. dit is nie nodig om elke keer die presiese waarde te kry nie. tipies word hierdie getalle frekwensiebakke genoem. die uitsetwaarde kan dus oral binne die gespesifiseerde asblikke wees.

Spoed:

vir Arduino nano neem dit:

16 punte: 4ms32 punte: 10ms 64 punte: 26ms 128 punte: 53ms

Stap 6: Gevolgtrekking

Hierdie FFT-kode kan in real-time toepassings gebruik word. Aangesien dit ongeveer 30 ms neem om die berekening te voltooi. Die resolusie daarvan word egter beperk deur 'n aantal monsters. Die aantal monsters word beperk deur die Arduino -geheue. Deur die gebruik van Arduino Mega of ander hoëprestasiebord kan die akkuraatheid verbeter word.

kommentaar lewer as u navrae, voorstelle of regstellings het.

Opdatering (2/5/21)

Updates: // ----------------------------- FFT-funksie --------------- ------------------------------- // float FFT (int in , int N, float Frequency)

Die datatipe van N verander na heelgetal (bestaande greep) om> 255 steekproefgrootte te ondersteun. As die steekproefgrootte <= 128 is, moet die greepdatatipe gebruik word.

Aanbeveel: