Sisukord:
- 1. samm: sissejuhatus sagedusmuundamisse
- 2. samm: kiire Fourier -teisendus
- 3. samm: koodi selgitamine
- 4. samm: koodi selgitus: FFT -funktsioon
- Samm: koodi testimine
- 6. samm: järeldus
Video: EasyFFT: kiire Fourier 'teisendus (FFT) Arduino jaoks: 6 sammu
2024 Autor: John Day | [email protected]. Viimati modifitseeritud: 2024-01-30 08:46
Sageduse mõõtmine salvestatud signaalist võib olla keeruline ülesanne, eriti Arduino puhul, kuna sellel on väiksem arvutusvõimsus. Nullpunkti jäädvustamiseks on saadaval meetodeid, kus sagedust püütakse kontrollida, kontrollides, mitu korda signaal antud aja jooksul nulljooni ületab. Selline meetod ei pruugi töötada, kui signaal on erinevate sageduste kombinatsioon.
Seda on kuidagi raske kodeerida, kui te pole sellisest taustast pärit. Kuid näppijana võib see kood olla väga kasulik erinevate muusika- ja signaalianalüüsiga seotud projektide jaoks. Selle projekti motiiv oli valmistada ette kood, mida on lihtne Arduinole rakendada ilma selle taustale sattumata.
See projekt ei selgita FFT toimimist, vaid selgitab FFT funktsiooni rakendamist. Sama protsessi selgitatakse ka lisatud videos.
Kui olete huvitatud ainult koodi rakendamisest ja mitte selle selgitusest. Võite minna otse sammu nr 3 juurde.
1. samm: sissejuhatus sagedusmuundamisse
Iga signaal võib koosneda erinevate siinuslainete kombinatsioonist. Seega saab mis tahes ajapõhist signaali näidata ka erinevate amplituudide erinevate siinuste kombinatsioonina.
Üritasin selgitada DFT (diskreetne Fourier 'teisendus) toimimist ühes eelmistest juhenditest (https://www.instructables.com/id/Arduino-Frequency…). Need meetodid on reaalajas rakenduste jaoks äärmiselt aeglased. mis muudab selle peaaegu kasutuks.
Pildil on näidatud signaal, mis koosneb kahest sagedusest f2 ja f5. See signaal korrutatakse väärtuste f1 kuni f5 katse siinuslainetega.
Matemaatiliselt saab näidata, et kahe erineva sagedusega harmoonilise andmekogumi korrutamise kokkuvõte kaldub nulli (suurem andmete arv võib viia taigna tulemuseni). Meie puhul, kui neil kahel korrutussagedusel on sama (või väga lähedane) sagedus, on korrutussumma nullist erinev arv.
Seega, kui meie signaal korrutatakse f1 -ga, on korrutamine korrutamine null (reaalse rakenduse korral nullilähedane). sama on ka f3, f4 puhul. Kuid väärtuse puhul ei ole f2 ja f5 väljund null, vaid oluliselt suurem kui ülejäänud väärtused.
Siin testitakse signaali 5 sagedusega, seega tuleb signaal korrutada viie sagedusega. Selline intensiivne arvutamine võtab rohkem aega. Matemaatiliselt on näidatud, et N proovide arvu jaoks kulub N*N komplekskorrutamine.
2. samm: kiire Fourier -teisendus
DFT arvutamise kiirendamiseks töötasid James Cooley ja John Tukey välja FFT algoritmi. Seda algoritmi peetakse ka üheks 20. sajandi olulisemaks algoritmiks. See jagab signaali paaritu ja paaritu sektsiooniks, mis vähendab mitmeid nõutavaid arvutusi. Seda kasutades saab kogu vajaliku keerulise korrutamise vähendada NlogN -ni. mis on märkimisväärne paranemine.
FFT taga oleva matemaatika üksikasjalikuks mõistmiseks võite viidata allpool viidetele, millele viitasin koodi kirjutamise ajal:
1.
2.
3.
4.
3. samm: koodi selgitamine
1. Kiire siinus ja koosinus:
Arvutamine FFT võtab erinevate siinuste ja koosinususte väärtuse mitu korda. Arduino sisseehitatud funktsioon ei ole piisavalt kiire ja võtab vajaliku väärtuse andmiseks palju aega. Mis muudab koodi oluliselt aeglasemaks (64 proovi puhul kahekordistub aeg). Selle probleemi lahendamiseks salvestatakse siinuse väärtus 0 kuni 90 kraadi juures kordajana 255. Seda tehes kaob vajadus numbrite salvestamiseks ujukina ja saame selle salvestada baitidena, mis võtab Arduinole 1/4 ruumi. Sine_data tuleb kleepida koodi ülaossa, et kuulutada see globaalseks muutujaks.
Peale sine_data deklareeriti massiiv nimega f_peaks globaalse muutujana. Pärast iga FFT -funktsiooni käivitamist seda massiivi värskendatakse. Kus f_peaks [0] on kõige domineerivam sagedus ja edasised väärtused kahanevas järjekorras.
bait 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];
Kuna siinuse väärtus on salvestatud 0 kuni 90 kraadi, saab arvutada mis tahes siinuse või koosinuse väärtuse. Allpool on funktsiooni esimene voor numbrikohani pärast koma ja tagastatakse salvestatud andmete väärtus. see meetod vajab ainult ühte ujuvjaotust. Seda saab veelgi vähendada siinusväärtuste (mitte 255 mitmekordse) salvestamisega. kuid see sööb Arduino kõrge mälu.
Ülaltoodud protseduuri kasutamine vähendab täpsust, kuid parandab kiirust. 64 punkti eest annab see eelise 8 ms ja 128 punkti puhul 20 ms.
4. samm: koodi selgitus: FFT -funktsioon
FFT -d saab teha ainult valimi suurusega 2, 4, 8, 16, 32, 64 ja nii edasi. kui väärtus ei ole 2^n, siis võtab see väärtuse alumise külje. Näiteks kui valime valimi suuruseks 70, võtab see arvesse ainult 64 esimest proovi ja jätab ülejäänud välja.
Valimi suurus on alati soovitatav 2^n. mis võib olla:
2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, …
Kaks ujukit out_r ja out_im võtavad palju mälu. Arduino jaoks nano ei tööta saadaolevate mälu puudumise tõttu proovide puhul, mis on suuremad kui 128 (ja mõnel juhul 128).
allkirjastamata int andmed [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};
int a, c1, f, o, x; a = N; jaoks (int i = 0; i <12; i ++) // tasemete arvutamiseks {if (andmed <= a) {o = i;}} int in_ps [andmed [o] = {}; // sisend järjestamiseks float out_r [andmed [o] = {}; // tegelik osa teisendusest float out_im [andmed [o] = {}; // kujuteldav osa teisendusest
Edasine voog on järgmine:
1. Kood genereerib antud valimi suuruse jaoks natuke vastupidise järjekorra (üksikasjad bittide tagasipööramise kohta viidetel: samm 2)
2. Sisestatud andmed on tellitud vastavalt genereeritud tellimusele, 3. FFT teostatud
4. Arvutatud kompleksarvu amplituud, 5. Piigid tuvastatakse ja järjestatakse kahanevas järjekorras
6. Tulemustele pääseb ligi aadressilt f_peaks.
[muudele andmetele (peale tippsageduse) juurdepääsemiseks tuleks koodi muuta, et kohalikku muutujat saaks kopeerida mõnele eelnevalt määratletud globaalsele muutujale]
Samm: koodi testimine
Sisendiks on näidis kolmnurga laine. selle laine proovivõtu sagedus on 10 Hz ja laine sagedus on 1,25 Hz.
Nagu toortoodangust võib näha, on väärtus vastavuses Scilabi arvutatud FFT -ga. need väärtused pole aga täpselt samad, mis meil madala täpsusega, vaid kiirem siinuslaine.
Väljundsageduse massiivi sagedus on 1,25 ja 3,75. pole vaja iga kord täpset väärtust saada. tavaliselt nimetatakse neid numbreid sageduskaustadeks. seega võib väljundväärtus olla ükskõik kus määratud prügikastide piires.
Kiirus:
Arduino nano jaoks kulub:
16 punkti: 4ms32 punkti: 10ms 64 punkti: 26ms 128 punkti: 53ms
6. samm: järeldus
Seda FFT-koodi saab kasutada reaalajas rakendustes. Kuna arvutuse lõpuleviimiseks kulub umbes 30 ms. Selle eraldusvõime on aga piiratud mitmete proovidega. Proovi arvu piirab Arduino mälu. Arduino Mega või mõne muu suurema jõudlusega plaadi täpsust saab parandada.
kui teil on küsimusi, ettepanekuid või parandusi, kommenteerige.
Värskendus (2/5/21)
Uuendused: // ----------------------------- FFT-funktsioon --------------- ------------------------------- // float FFT (int in , int N, float Frequency)
N andmetüüp muudeti täisarvuks (olemasolev bait), et toetada> 255 valimi suurust. Kui valimi suurus on <= 128, tuleks kasutada baidi andmetüüpi.
Soovitan:
Tonka veoauto RC teisendus prügikasti ja 4WS nelikjuhtimisega: 6 sammu (piltidega)
Tonka veoauto RC teisendus prügikasti ja 4WS nelikjuhtimisega: möönan, et Tonka veoauto RC muundamine ei ole algne idee, kuid kui ma sellele mõtlesin, arvasin, et olen esimene … see on seni, kuni otsisin veebist, D'oh. Jah, seda on varem tehtud, kuid minu arvates tegid kõik teised seda raskel viisil ja ebaõnnestusid
QuickFFT: kiire FFT Arduino jaoks: 3 sammu
QuickFFT: kiire FFT Arduino jaoks: Tüüpilisel Arduino'l on piiratud RAM ja töötlemisvõimsus ning FFT on arvutusmahukas protsess. Paljude reaalajas rakenduste puhul on ainus nõue saada maksimaalse amplituudiga või sageduspiikide tuvastamiseks vajalik sagedus. Ühes
Kiire kell aegluubis videote jaoks: 4 sammu
Kiire kell aegluubis videote jaoks: peaaegu kõigil kaasaegse nutitelefoni kasutajatel on kiire kaamera, mida saab kasutada suurejooneliste aegluubis videote tegemiseks. Aga kui soovite mõõta, kui kaua seebimull lõhkeb või arbuus plahvatab, võite
Suure võimsusega LED Mag-lite teisendus: 9 sammu (piltidega)
Suure võimsusega LED Mag-lite muundamine: see juhend annab teile ülevaate, kuidas võtta tavaline Mag-lite taskulamp ja muuta seda 12–10 mm suure võimsusega LED-de hoidmiseks. Seda tehnikat saab rakendada ka teiste tulede puhul, nagu näitan tulevastes juhendites
Kiire, kiire, odav, hea väljanägemisega LED -ruumi valgustus (kõigile): 5 sammu (piltidega)
Kiire, kiire, odav, hea väljanägemisega LED-ruumi valgustus (kõigile): Tere tulemast kõigile :-) See on minu esimene juhendatav, nii et kommentaarid on teretulnud :-) Loodan teile näidata, kuidas teha kiire LED-valgustus PISIKE kott. Mida vajate: kaabelLED -id Takistid (510Ohm 12V jaoks) StapelsLotis