Kazalo:
- 1. korak: Uvod v frekvenčno transformacijo
- 2. korak: Hitra Fourierjeva transformacija
- 3. korak: Razlaga kode
- 4. korak: Pojasnilo kode: funkcija FFT
- 5. korak: Preizkusite kodo
- 6. korak: Zaključek
Video: EasyFFT: Hitra Fourierjeva transformacija (FFT) za Arduino: 6 korakov
2024 Avtor: John Day | [email protected]. Nazadnje spremenjeno: 2024-01-30 12:03
Merjenje frekvence iz zajetega signala je lahko težka naloga, zlasti na Arduinu, saj ima manjšo računsko moč. Na voljo so načini za zajemanje ničelnega prehoda, pri katerem se frekvenca zajame s preverjanjem, kolikokrat signal prečka ničelne črte v danem času. Ta metoda morda ne bo delovala, če je signal kombinacija različnih frekvenc.
To je nekako težko kodirati, če niste iz takega ozadja. Toda kot odpravljalka kode je lahko zelo koristna za različne projekte, povezane z glasbo, analizo signalov. Motiv tega projekta je bil pripraviti kodo, ki je enostavna za izvedbo na Arduinu, ne da bi pri tem prišla v ozadje.
Ta projekt ne razlaga delovanja FFT, ampak razlaga uporabo funkcije FFT. Enak postopek je razložen tudi v priloženem videoposnetku.
Če vas zanima samo uporaba kode in ne razlaga le -te. Lahko preskočite neposredno na korak 3.
1. korak: Uvod v frekvenčno transformacijo
Vsak signal je lahko sestavljen iz kombinacije različnih sinusnih valov. Tako se lahko vsak časovno odvisen signal prikaže tudi kot kombinacija različnih sinusov različnih amplitud.
Poskušal sem razložiti delovanje DFT (diskretna Fourierjeva pretvorba) v enem od prejšnjih navodil (https://www.instructables.com/id/Arduino-Frequency…). Te metode so zelo počasne za vsako aplikacijo v realnem času. zaradi česar je skoraj neuporaben.
Na sliki je prikazan signal, ki je kombinacija dveh frekvenc f2 in f5. Ta signal se pomnoži s preskusnimi sinusnimi valovi vrednosti od f1 do f5.
Matematično je mogoče prikazati, da -povzetek množenja dveh harmoničnih nizov podatkov z različno frekvenco teži k nič (večje število podatkov lahko privede do testa). V našem primeru, če imata ti dve frekvenci množenja enako (ali zelo blizu) frekvenco, je vsota množenja različno od nič.
Torej, če naš signal pomnožimo s f1, bo seštevek množenja nič (blizu nič za resnično uporabo). podobno velja za f3, f4. Vendar za vrednost izhod f2 in f5 ne bo nič, ampak bistveno višji od preostalih vrednosti.
Tu se signal preskusi s 5 frekvencami, zato ga je treba pomnožiti s petimi frekvencami. Tako intenziven izračun traja dlje. Matematično je prikazano, da je za N število vzorcev potrebno kompleksno množenje N*N.
2. korak: Hitra Fourierjeva transformacija
Za hitrejši izračun DFT sta algoritem FFT razvila James Cooley in John Tukey. Ta algoritem velja tudi za enega najpomembnejših algoritmov 20. stoletja. Signal razdeli na lih in sodo zaporeden del, zaradi česar je število zahtevanih izračunov manjše. Z njegovo uporabo se lahko skupno zahtevano kompleksno množenje zmanjša na NlogN. kar je pomemben napredek.
Za podrobnejše razumevanje matematike, ki stoji za FFT, se lahko sklicujete na spodnje reference, ki sem jih omenil pri pisanju kode:
1.
2.
3.
4.
3. korak: Razlaga kode
1. Hitri sinus in kosinus:
Izračun FFT večkrat vzame vrednost različnih sinusov in kosinusov. Vgrajena funkcija Arduina ni dovolj hitra in potrebuje kar nekaj časa, da zagotovi zahtevano vrednost. Zaradi tega se koda bistveno upočasni (podvoji čas za 64 vzorcev). Če želite odpraviti to težavo, je vrednost sinusov za 0 do 90 stopinj shranjena kot večkratnik 255. S tem boste odpravili potrebo po shranjevanju številk kot float in jih lahko shranimo kot bajt, ki zavzame 1/4 prostora na Arduinu. Sine_data je treba prilepiti na vrh kode, da jo razglasi za globalno spremenljivko.
Poleg sine_data je polje, imenovano f_peaks , deklarirano kot globalna spremenljivka. Po vsakem zagonu funkcije FFT se ta niz posodobi. Kjer je f_peaks [0] najbolj prevladujoča frekvenca in nadaljnje vrednosti v padajočem vrstnem redu.
bajt 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];
Ker imamo shranjeno vrednost sinusa za 0 do 90 stopinj, lahko izračunamo katero koli vrednost sinusa ali kosinusa. Spodaj deluje prvi krog števila na decimalno vejico nič in vrnjena vrednost iz shranjenih podatkov. ta metoda potrebuje le eno plavajočo delitev. To lahko dodatno zmanjšamo z neposrednim shranjevanjem vrednosti sinusov (ne 255 večkratnikov). vendar to na Arduinu poje veliko spomina.
Z uporabo zgornjega postopka se zmanjša natančnost, vendar izboljša hitrost. Za 64 točk daje prednost 8 ms, za 128 točk pa prednost 20 ms.
4. korak: Pojasnilo kode: funkcija FFT
FFT je mogoče izvesti samo za velikost vzorca 2, 4, 8, 16, 32, 64 itd. če vrednost ni 2^n, potem vzame spodnjo stran vrednosti. Na primer, če izberemo velikost vzorca 70, bo upošteval le prvih 64 vzorcev in izpustil ostalo.
Vedno je priporočljivo imeti vzorec 2^n. kar je lahko:
2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, …
Dva plavajoča out_r in out_im bosta zajela veliko pomnilnika. ker Arduino nano ne bo deloval za vzorce, večje od 128 (in v nekaterih primerih 128) zaradi pomanjkanja razpoložljivega pomnilnika.
podpisani int podatki [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 ++) // izračun ravni {if (data <= a) {o = i;}} int in_ps [data [o] = {}; // vnos za zaporedje float out_r [data [o] = {}; // dejanski del transformacije float out_im [data [o] = {}; // imaginarni del preoblikovanja
Nadaljnji tok je naslednji:
1. Koda ustvari malo obrnjen vrstni red za dano velikost vzorca (podrobnosti o obrnitvi bitov na referencah: korak 2)
2. Vhodni podatki, razvrščeni po generiranem naročilu, 3. Izveden FFT
4. Izračunana amplituda kompleksnega števila, 5. Vrhovi se zaznajo in razvrstijo po padajočem vrstnem redu
6. Do rezultatov lahko dostopate iz f_peaks.
[za dostop do drugih podatkov (razen najvišje frekvence) je treba kodo spremeniti, tako da je mogoče lokalno spremenljivko kopirati v neko vnaprej določeno globalno spremenljivko]
5. korak: Preizkusite kodo
Vhodni vzorec je trikotni val. frekvenca vzorčenja tega vala je 10 Hz, frekvenca samega vala pa 1,25 Hz.
Kot je razvidno iz surove proizvodnje, se vrednost ujema s FFT, ki ga izračuna Scilab. vendar te vrednosti niso povsem enake kot pri nas z nizko natančnostjo, ampak hitrejši sinusni val.
V izhodni frekvenčni matriki sta frekvenci 1,25 in 3,75. ni treba vsakič dobiti natančne vrednosti. Običajno se te številke imenujejo frekvenčni sprejemniki. zato je lahko izhodna vrednost kjer koli v določenih posodah.
Hitrost:
za Arduino nano je potrebno:
16 točk: 4 ms32 točk: 10 ms 64 točk: 26 ms 128 točk: 53 ms
6. korak: Zaključek
To kodo FFT je mogoče uporabiti v aplikacijah v realnem času. Ker za dokončanje izračuna traja približno 30 ms. Vendar je njegova ločljivost omejena s številnimi vzorci. Število vzorcev je omejeno s pomnilnikom Arduino. Z uporabo Arduino Mega ali katere koli druge zmogljivosti plošče lahko izboljšate natančnost.
če imate kakršna koli vprašanja, predloge ali popravke, komentirajte.
Posodobitev (2/5/21)
Posodobitve: // ----------------------------- Funkcija FFT --------------- ------------------------------- // float FFT (int in , int N, float Frequency)
Podatkovni tip N se je spremenil v Integer (obstoječi bajt), da podpira> 255 velikosti vzorca. Če je velikost vzorca <= 128, je treba uporabiti podatkovni tip bajtov.
Priporočena:
Otto DIY Robot Walking - Hitra in enostavna vadnica: 7 korakov
Otto DIY Robot Walking - Hitra in enostavna vadnica: V tej vadnici se bomo naučili, kako zlahka programirati Otto DIY robota za hojo. Oglejte si predstavitveni video
DHT12 (senzor poceni vlažnosti in temperature i2c), hitra enostavna uporaba: 14 korakov
DHT12 (i2c poceni senzor vlažnosti in temperature), hitra enostavna uporaba: posodobitve in drugo najdete na moji spletni strani https://www.mischianti.org/2019/01/01/dht12-library-en/.Všeč mi je senzor, ki se lahko uporablja z 2 žicami (protokol i2c), vendar mi je všeč poceni. To je knjižnica Arduino in esp8266 za serijo DHT12 o
"Moteč stroj": hitra kiparska umetnina za začetnike: 8 korakov (s slikami)
"The Unsettling Machine": Hitra umetniška skulptura za začetnike: (Če vam je všeč ta pouk, ga glasujte na natečaju " Trash to Treasure ". Če iščete manj moteč projekt, preverite moj zadnji ena: Kako ustvariti hojo robota Lambada! Hvala!) Recimo, da imate šolo
PCF8591 (i2c Analog I/O Expander) Hitra enostavna uporaba: 9 korakov
PCF8591 (i2c Analog I/O Expander) Hitra enostavna uporaba: Knjižnica za uporabo i2c pcf8591 IC z arduinom in esp8266. Ta IC lahko nadzoruje (do 4) analogni vhod in/ali 1 analogni izhod, kot je merilna napetost, bere vrednost termistorja ali zbledi LED
Hitra, hitra, poceni, dobro videti LED osvetlitev prostora (za vsakogar): 5 korakov (s slikami)
Hitra, hitra, poceni, dobro videti LED osvetlitev prostora (za vsakogar): Dobrodošli vsi :-) To je moj prvi pouk, zato so komentarji dobrodošli :-) Upam, da vam bom pokazal, kako narediti hitro LED osvetlitev TINY buget. Kaj potrebujete: kabliLED -ji, upori (510Ohms za 12V), spenjalniki, spajkalnik, rezalniki in drugo