Sadržaj:
- Korak 1: Uvod u frekvencijsku transformaciju
- Korak 2: Brza Furijeova transformacija
- Korak 3: Objašnjenje koda
- Korak 4: Objašnjenje koda: FFT funkcija
- Korak 5: Testiranje koda
- Korak 6: Zaključak
Video: EasyFFT: Brza Furijeova transformacija (FFT) za Arduino: 6 koraka
2024 Autor: John Day | [email protected]. Zadnja izmjena: 2024-01-30 08:04
Mjerenje frekvencije iz snimljenog signala može biti težak zadatak, posebno na Arduinu jer ima manju računsku snagu. Dostupne su metode za snimanje ukrštanja nulte točke pri čemu se frekvencija hvata provjeravajući koliko puta signal prelazi nultu liniju unutar zadanog vremena. Takva metoda možda neće raditi ako je signal kombinacija različitih frekvencija.
Ovo je nekako teško kodirati ako niste iz takvog porijekla. No, budući da je to tinker, ovaj kôd može biti vrlo koristan za razne projekte vezane za muziku, analizu signala. Motiv ovog projekta bio je pripremiti kod koji je lako implementirati na Arduino, a da ne ulazi u njegovu pozadinu.
Ovaj projekt ne objašnjava rad FFT -a, ali objašnjava primjenu funkcije FFT -a. Isti proces je objašnjen i u priloženom videu.
Ako vas zanima samo primjena koda, a ne i njegovo objašnjenje. Možete direktno preći na korak 3.
Korak 1: Uvod u frekvencijsku transformaciju
Svaki signal može biti sastavljen od kombinacije različitih sinusoidnih valova. Dakle, svaki signal zasnovan na vremenu može se prikazati i kao kombinacija različitih sinusa različitih amplituda.
Pokušao sam objasniti rad DFT-a (diskretna Fourierova transformacija) u jednoj od prethodnih instrukcija (https://www.instructables.com/id/Arduino-Frequency…). Ove metode su izuzetno spore za bilo koju aplikaciju u stvarnom vremenu. što ga čini gotovo beskorisnim.
Na slici je prikazan signal koji je kombinacija dvije frekvencije f2 i f5. Ovaj signal se množi testnim sinusnim valovima vrijednosti od f1 do f5.
Matematički se može pokazati da -zbir množenja dva skupa podataka harmonika različitih frekvencija teži nuli (veći broj podataka može dovesti do rezultata testa). U našem slučaju, ako ove dvije frekvencije množenja imaju istu (ili vrlo blisku) frekvenciju, taj zbir množenja je broj različit od nule.
Dakle, ako se naš signal pomnoži sa f1, zbir množenja bit će nula (blizu nule za stvarnu primjenu). sličan je slučaj za f3, f4. Međutim, za vrijednost, izlaz f2 i f5 neće biti nula, već znatno veći od ostalih vrijednosti.
Ovdje se testira signal sa 5 frekvencija, pa se signal mora pomnožiti sa pet frekvencija. Za tako intenzivno računanje potrebno je duže vrijeme. Matematički je pokazano da je za N broj uzoraka potrebno N*N kompleksno množenje.
Korak 2: Brza Furijeova transformacija
Da bi izračunavanje DFT -a bilo brže, algoritam FFT razvili su James Cooley i John Tukey. Ovaj algoritam se takođe smatra jednim od najvažnijih algoritama 20. veka. On dijeli signal na neparan i paran niz koji smanjuje broj potrebnih proračuna. Njegovom upotrebom ukupno potrebno kompleksno množenje može se smanjiti na NlogN. što je značajno poboljšanje.
U nastavku možete pogledati reference na koje sam se pozivao dok sam pisao kôd za detaljnije razumijevanje matematike koja stoji iza FFT -a:
1.
2.
3.
4.
Korak 3: Objašnjenje koda
1. Brzi sinus i kosinus:
Proračun FFT uzima vrijednost različitih sinusnih i kosinusnih više puta. Ugrađena funkcija Arduina nije dovoljno brza i potrebno je dosta vremena da se osigura potrebna vrijednost. Što kôd čini znatno sporijim (udvostručuje vrijeme za 64 uzorka). Kako bi se suprotstavili ovom problemu, vrijednost sinusa za 0 do 90 stupnjeva pohranjuje se kao višekratnik 255. Time ćete ukloniti potrebu za pohranjivanjem brojeva kao float, a možemo ga pohraniti i kao bajt koji zauzima 1/4 prostora na Arduinu. Sine_data treba zalijepiti na vrh koda da bi ga deklarirao kao globalnu varijablu.
Osim sine_data, niz nazvan f_peaks deklariran kao globalna varijabla. Nakon svakog pokretanja funkcije FFT ovaj niz se ažurira. Gdje je f_peaks [0] najdominantnija frekvencija i dalje vrijednosti u opadajućem redoslijedu.
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];
Kako smo vrijednost sinusa pohranili za 0 do 90 stupnjeva, može se izračunati bilo koja vrijednost sinusa ili kosinusa. Ispod funkcionira prvi krug broja do nule decimalnog zareza i povratna vrijednost iz pohranjenih podataka. ovoj metodi je potrebna samo jedna plutajuća podjela. Ovo se može dodatno smanjiti izravnim pohranjivanjem sinusnih vrijednosti (ne 255 višestrukih). ali to jede mnogo memorije na Arduinu.
Korištenje gornjeg postupka smanjuje točnost, ali poboljšava brzinu. Za 64 boda daje prednost od 8 ms, a za 128 bodova prednost od 20 ms.
Korak 4: Objašnjenje koda: FFT funkcija
FFT se može izvesti samo za uzorke veličine 2, 4, 8, 16, 32, 64 itd. ako vrijednost nije 2^n, tada će uzeti donju stranu vrijednosti. Na primjer, ako odaberemo veličinu uzorka 70, tada će se uzeti u obzir samo prva 64 uzorka i izostaviti ostatak.
Uvijek se preporučuje veličina uzorka 2^n. koje mogu biti:
2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, …
Dva plutajuća out_r i out_im će zauzeti veliku količinu memorije. jer Arduino nano neće raditi za uzorke veće od 128 (a u nekim slučajevima i 128) zbog nedostatka dostupne memorije.
nepotpisani int podaci [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čunavanje nivoa {if (data <= a) {o = i;}} int in_ps [data [o] = {}; // ulaz za sekvenciranje float out_r [data [o] = {}; // stvarni dio transformacije float out_im [data [o] = {}; // imaginarni dio transformacije
Daljnji tok je sljedeći:
1. Kôd generira obrnuti redoslijed bita za datu veličinu uzorka (detalji o preokretanju bita na referencama: korak 2)
2. Ulazni podaci poredani prema generiranoj narudžbi, 3. Izvršen FFT
4. Izračunata amplituda kompleksnog broja, 5. Vrhovi se otkrivaju i poredaju opadajućim redoslijedom
6. rezultatima se može pristupiti iz f_peaks.
[za pristup drugim podacima (osim vršne frekvencije) kod treba izmijeniti, tako da se lokalna varijabla može kopirati u neku unaprijed definiranu globalnu varijablu]
Korak 5: Testiranje koda
Uzorak trokutastog vala je dan kao ulaz. za ovaj talas frekvencija uzorkovanja je 10 Hz, a sama frekvencija talasa je 1,25 Hz.
Kao što se može vidjeti iz sirovog rezultata, vrijednost se podudara s FFT -om koji je izračunao Scilab. međutim, ove vrijednosti nisu potpuno iste kao kod nas niske preciznosti, već bržeg sinusnog vala.
U izlaznom frekvencijskom nizu frekvencije su 1,25 i 3,75. nije potrebno svaki put dobiti tačnu vrijednost. obično se ti brojevi nazivaju frekventni pretinci. tako da izlazna vrijednost može biti bilo gdje unutar navedenih kanti.
Brzina:
za Arduino nano potrebno je:
16 poena: 4ms32 poena: 10ms 64 poena: 26ms 128 poena: 53ms
Korak 6: Zaključak
Ovaj FFT kod može se koristiti u aplikacijama u stvarnom vremenu. Kako je potrebno oko 30 ms da se dovrši proračun. Međutim, njegova rezolucija ograničena je brojem uzoraka. Broj uzorka ograničen je Arduino memorijom. Korištenjem Arduino Mega ili drugih ploča može se poboljšati preciznost.
ako imate bilo kakvih pitanja, prijedloga ili ispravki, slobodno komentirajte.
Ažuriranje (2/5/21)
Ažuriranja: // ----------------------------- FFT funkcija --------------- ------------------------------- // float FFT (int u , int N, float frekvencija)
Tip podataka N promijenjen je u Integer (postojeći bajt) kako bi podržao> 255 veličinu uzorka. Ako je veličina uzorka <= 128, treba koristiti bajtni tip podataka.
Preporučuje se:
Arduino: Frekvencijska transformacija (DFT): 6 koraka
Arduino: Frekvencijska transformacija (DFT): ovaj program služi za izračunavanje frekvencijske transformacije na arduinu uz kontrolu nad parametrima. Rješava se pomoću oskrnavljene četverostruke transformacije. ovo nije FFT. FFT je algoritam koji se koristi za rješavanje DFT -a s kraćim vremenom. Kôd za FFT možete pronaći ovdje
Brza narukvica za igralište s muzičkim krugovima: 5 koraka
Ekspresna narukvica za igralište s muzičkim krugovima: Za izradu ove muzičke narukvice trebat će vam Circuit Playground Express Kompjuter Igla za šivanje Konac Duge i škare od filca
Aruduino LED igra Brza igra za dva igrača: 8 koraka
Aruduino LED igra Brza igra za dva igrača: Ovaj projekat je inspirisan @HassonAlkeim. Ako ste voljni detaljno pogledati, evo linka koji možete provjeriti https://www.instructables.com/id/Arduino-Two-Player-Fast-Button-Clicking-Game/. Ova igra je poboljšana verzija Alkeima. To je
"Uznemirujuća mašina": brza skulptura bez umjetnosti za početnike: 8 koraka (sa slikama)
"The Unsettling Machine": Brza skulptura bezvrijedne umjetnosti za početnike: (Ako vam se sviđa ova instrukcija, glasajte za nju na natječaju "Trash to Treasure". No, ako tražite manje uznemirujući projekt, provjerite moj posljednji jedan: Kako stvoriti Lambada hodajućeg robota! Hvala!) Pretpostavimo da imate školu
Brza Arduino futrola: 3 koraka (sa slikama)
Brzo kućište Arduino: Ovo je kratka uputa o pametnoj maloj ideji kućišta Arduino koju možete napraviti od prazne kutije s vijcima