Sadržaj:
- Korak 1: Instaliranje biblioteke
- Korak 2: Fourierova transformacija i FFT koncepti
- Korak 3: Simulacija signala
- Korak 4: Analiza simuliranog signala - kodiranje
- Korak 5: Analiza simuliranog signala - rezultati
- Korak 6: Analiza stvarnog signala - Ožičenje ADC -a
- Korak 7: Analiza stvarnog signala - kodiranje
- Korak 8: Analiza stvarnog signala - rezultati
- Korak 9: Šta je sa izrezanim sinusoidnim signalom?
Video: 1024 uzorka FFT analizator spektra pomoću Atmega1284: 9 koraka
2024 Autor: John Day | [email protected]. Zadnja izmjena: 2024-01-30 08:05
Ovaj relativno jednostavan vodič (s obzirom na složenost ove teme) pokazat će vam kako možete napraviti vrlo jednostavan analizator spektra od 1024 uzorka koristeći ploču tipa Arduino (1284 uska) i serijski ploter. Bilo koja vrsta Arduino kompatibilne ploče će poslužiti, ali što više RAM -a ima, najbolju frekvencijsku rezoluciju ćete dobiti. Za računanje FFT -a sa 1024 uzorka trebat će mu više od 8 KB RAM -a.
Analiza spektra koristi se za određivanje glavnih frekvencijskih komponenti signala. Mnogi zvukovi (poput onih koje proizvodi muzički instrument) sastoje se od osnovne frekvencije i nekih harmonika koji imaju frekvenciju koja je cijeli broj višekratnik osnovne frekvencije. Analizator spektra će vam pokazati sve ove spektralne komponente.
Možda biste htjeli koristiti ovu postavku kao brojač frekvencija ili provjeriti bilo koju vrstu signala za koji sumnjate da unosi buku u vaše elektroničko kolo.
Ovdje ćemo se fokusirati na softverski dio. Ako želite napraviti stalni krug za određenu aplikaciju, morat ćete pojačati i filtrirati signal. Ovo predkondicioniranje u potpunosti ovisi o signalu koji želite proučavati, ovisno o njegovoj amplitudi, impedanciji, maksimalnoj frekvenciji itd … Možete provjeriti
Korak 1: Instaliranje biblioteke
Koristit ćemo ArduinoFFT biblioteku koju je napisao Enrique Condes. Budući da želimo maksimalno uštedjeti RAM, upotrijebit ćemo razvojnu granu ovog spremišta koja omogućava korištenje float tipa podataka (umjesto dvostrukog) za pohranu uzorkovanih i izračunatih podataka. Zato ga moramo instalirati ručno. Ne brinite, samo preuzmite arhivu i raspakirajte je u fasciklu Arduino biblioteke (na primjer na Windows 10 zadanoj konfiguraciji: C: / Users / _vaše_korisničko_ime_ / Dokumenti / Arduino / biblioteke)
Možete provjeriti je li knjižnica ispravno instalirana sastavljanjem jednog od ponuđenih primjera, poput "FFT_01.ino."
Korak 2: Fourierova transformacija i FFT koncepti
Upozorenje: ako ne podnosite bilo koju matematičku notaciju, možda biste htjeli preskočiti na korak 3. U svakom slučaju, ako ne razumijete sve, samo razmislite o zaključku na kraju odjeljka.
Frekvencijski spektar dobiven je algoritmom brze Fourierove transformacije. FFT je digitalna implementacija koja približava matematički koncept Fourierove transformacije. Prema ovom konceptu, nakon što dobijete evoluciju signala koja slijedi vremensku osu, možete znati njegovu reprezentaciju u frekvencijskom domenu, sastavljenom od složenih (realnih + imaginarnih) vrijednosti. Koncept je recipročan, pa kada znate prikaz frekvencijske domene, možete ga transformirati natrag u vremensku domenu i vratiti signal točno kao prije transformacije.
Ali što ćemo učiniti s ovim skupom izračunatih kompleksnih vrijednosti u vremenskoj domeni? Pa, većina će biti prepuštena inženjerima. Za nas ćemo nazvati drugi algoritam koji će pretvoriti ove složene vrijednosti u podatke o spektralnoj gustoći: to je veličina (= intenzitet) povezana sa svakim frekvencijskim pojasom. Broj frekvencijskog pojasa bit će isti kao i broj uzoraka.
Sigurno ste upoznati sa konceptom ekvilajzera, poput ovog Povratak u 1980 -te sa grafičkim ekvilajzerom. Pa, dobit ćemo istu vrstu rezultata, ali sa 1024 opsega umjesto 16 i mnogo većom rezolucijom intenziteta. Kada ekvilajzer daje globalni prikaz muzike, fina spektralna analiza omogućava precizno izračunavanje intenziteta svakog od 1024 opsega.
Savršen koncept, ali:
- Budući da je FFT digitalizirana verzija Fourierove transformacije, on aproksimira digitalni signal i gubi neke informacije. Dakle, strogo govoreći, rezultat FFT -a ako se transformira unatrag s obrnutim algoritmom FFT -a ne bi dao točno izvorni signal.
- Također teorija razmatra signal koji nije konačan, već je to konstantni konstantni signal. Budući da ćemo ga digitalizirati samo određeno vrijeme (tj. Uzorci), bit će uvedene još neke greške.
- Konačno, rezolucija analogno -digitalne konverzije će utjecati na kvalitetu izračunatih vrijednosti.
U praksi
1) Učestalost uzorkovanja (zabilježeno fs)
Uzorkovaćemo signal, odnosno meriti njegovu amplitudu svakih 1/fs sekundi. fs je frekvencija uzorkovanja. Na primjer, ako uzorkujemo na 8 KHz, ADC (analogno -digitalni pretvarač) koji je na čipu omogućit će mjerenje svakih 1/8000 sekundi.
2) Broj uzoraka (zabilježen N ili uzorci u kodu)
Budući da moramo dobiti sve vrijednosti prije pokretanja FFT -a, morat ćemo ih pohraniti, pa ćemo ograničiti broj uzoraka. FFT algoritmu je potreban određeni broj uzoraka snage 2. Što više uzoraka imamo, to smo bolji, ali zauzima puno memorije, utoliko će nam više trebati i za pohranu transformiranih podataka, koji su složene vrijednosti. Arduino FFT biblioteka štedi dio prostora korištenjem
- Jedan niz pod nazivom "vReal" za spremanje uzorkovanih podataka, a zatim i stvarni dio transformiranih podataka
- Jedan niz pod nazivom "vImag" za spremanje zamišljenog dijela transformiranih podataka
Potrebna količina RAM -a jednaka je 2 (nizovi) * 32 (bitovi) * N (uzorci).
Tako ćemo u našu Atmega1284 koja ima lijepih 16 KB RAM -a pohraniti najviše N = 16000*8 /64 = 2000 vrijednosti. Budući da broj vrijednosti mora biti 2, pohranit ćemo najviše 1024 vrijednosti.
3) Rezolucija frekvencije
FFT će izračunati vrijednosti za onoliko frekvencijskih opsega koliko je uzoraka. Ovi opsezi će se protezati od 0 HZ do frekvencije uzorkovanja (fs). Dakle, rezolucija frekvencije je:
Fresolution = fs / N
Rezolucija je bolja ako je niža. Dakle, za bolju rezoluciju (manju) želimo:
- više uzoraka i/ili
- niži fs
Ali…
4) Minimalni fs
Budući da želimo vidjeti mnogo frekvencija, od kojih su neke mnogo veće od "osnovne frekvencije", ne možemo postaviti fs premalo. U stvari, postoji Nyquist -Shannonova teorema uzorkovanja koja nas tjera da imamo frekvenciju uzorkovanja znatno iznad dvostruko veće od maksimalne frekvencije koju bismo željeli testirati.
Na primjer, ako želimo analizirati cijeli spektar od 0 Hz do recimo 15 KHz, što je približno maksimalna frekvencija koju većina ljudi može jasno čuti, moramo postaviti frekvenciju uzorkovanja na 30 KHz. U stvari, elektroničari ga često postavljaju na 2,5 (ili čak 2,52) * maksimalnu frekvenciju. U ovom primjeru to bi bilo 2,5 * 15 KHz = 37,5 KHz. Uobičajene frekvencije uzorkovanja u profesionalnom zvuku su 44,1 KHz (snimanje audio CD -a), 48 KHz i više.
Zaključak:
Točke 1 do 4 vode do: želimo upotrijebiti što je moguće više uzoraka. U našem slučaju sa 16 KB RAM uređaja razmotrit ćemo 1024 uzorka. Želimo uzorkovati na najmanjoj mogućoj frekvenciji uzorkovanja, sve dok je dovoljno visoka da analiziramo najveću frekvenciju koju očekujemo u našem signalu (najmanje 2,5 * ove frekvencije).
Korak 3: Simulacija signala
Za naš prvi pokušaj, malo ćemo izmijeniti primjer TFT_01.ino dat u biblioteci, kako bismo analizirali signal sastavljen od
- Osnovna frekvencija, postavljena na 440 Hz (muzički A)
- 3. harmonik na pola snage fundamentalnog ("-3 dB")
- 5. harmonik na 1/4 snage fundamentalne ("-6 dB)
Rezultat signala možete vidjeti na slici iznad. Zaista jako liči na pravi signal koji se ponekad može vidjeti na osciloskopu (ja bih to nazvao "Batman") u situaciji kada dolazi do isjecanja sinusnog signala.
Korak 4: Analiza simuliranog signala - kodiranje
0) Uključite biblioteku
#include "arduinoFFT.h"
1) Definicije
U odjeljcima deklaracija imamo
const bajt adcPin = 0; // A0
const uint16_t uzorci = 1024; // Ova vrijednost MORA UVIJEK biti snaga 2 const uint16_t samplingFrequency = 8000; // Utjecat će na maksimalnu vrijednost tajmera u timer_setup () SYSCLOCK/8/samplingFrequency bi trebao biti cijeli broj
Budući da signal ima 5. harmonik (frekvencija ovog harmonika = 5 * 440 = 2200 Hz), moramo postaviti frekvenciju uzorkovanja iznad 2,5 * 2200 = 5500 Hz. Ovdje sam odabrao 8000 Hz.
Također deklariramo nizove u koje ćemo pohraniti neobrađene i izračunate podatke
float vReal [uzorci];
plutajući vImag [uzorci];
2) Instancija
Kreiramo ArduinoFFT objekt. Dev verzija ArduinoFFT -a koristi predložak pa možemo koristiti ili float ili dvostruki tip podataka. Float (32 bita) je dovoljan s obzirom na ukupnu preciznost našeg programa.
ArduinoFFT FFT = ArduinoFFT (vReal, vImag, uzorci, samplingFrequency);
3) Simulacija signala popunjavanjem vReal niza, umjesto da se popuni ADC vrijednostima.
Na početku petlje popunjavamo niz vReal sa:
float ciklusi = (((uzorci) * signalFrequency) / samplingFrequency); // Broj ciklusa signala koje će uzorkovanje očitati
za (uint16_t i = 0; i <uzorci; i ++) {vReal = float ((amplituda * (sin ((i * (TWO_PI * ciklusa))) / uzorci)))); / * Izgradite podatke s pozitivnim i negativne vrijednosti */ vReal += float ((amplituda * (sin ((3 * i * (TWO_PI * ciklusa))/ uzorci)))/ 2.0);/ * Izgradite podatke s pozitivnim i negativnim vrijednostima */ vReal += float ((amplituda * (sin ((5 * i * (TWO_PI * ciklusa))) / uzorci))) / 4,0); / * Izgradite podatke s pozitivnim i negativnim vrijednostima * / vImag = 0,0; // Zamišljeni dio mora biti nuliran u slučaju petlje kako bi se izbjegli pogrešni proračuni i prelijevanje}
Dodajemo digitalizaciju temeljnog vala i dva harmonika s manjom amplitudom. Zatim inicijaliziramo zamišljeni niz nulama. Budući da je ovaj niz popunjen algoritmom FFT, moramo ga ponovo očistiti prije svakog novog izračunavanja.
4) FFT računarstvo
Zatim izračunavamo FFT i spektralnu gustoću
FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward);
FFT.compute (FFTDirection:: Forward); / * Izračunaj FFT */ FFT.complexToMagnitude (); / * Izračunajte veličine */
Operacija FFT.windowing (…) mijenja neobrađene podatke jer pokrećemo FFT na ograničenom broju uzoraka. Prvi i posljednji uzorak predstavljaju diskontinuitet (s jedne strane nema "ništa"). Ovo je izvor greške. Operacija "prozora" nastoji smanjiti ovu grešku.
FFT.compute (…) sa smjerom "Naprijed" izračunava transformaciju iz vremenske domene u frekvencijsku domenu.
Zatim izračunavamo vrijednosti veličine (tj. Intenziteta) za svaki od frekvencijskih opsega. Niz vReal sada je ispunjen veličinama.
5) Crtež serijskog plotera
Odštampajmo vrijednosti na serijskom ploteru pozivanjem funkcije printVector (…)
PrintVector (vReal, (uzorci >> 1), SCL_FREQUENCY);
Ovo je generička funkcija koja omogućava ispis podataka s vremenskom osi ili osi frekvencije.
Štampamo i frekvenciju opsega koja ima najveću vrijednost veličine
float x = FFT.majorPeak ();
Serial.print ("f0 ="); Serial.print (x, 6); Serial.println ("Hz");
Korak 5: Analiza simuliranog signala - rezultati
Vidimo 3 skoka koji odgovaraju osnovnoj frekvenciji (f0), 3. i 5. harmonik, sa polovinom i 1/4 veličine f0, kako se očekivalo. Možemo očitati na vrhu prozora f0 = 440.430114 Hz. Ova vrijednost nije baš 440 Hz, iz svih gore navedenih razloga, ali je vrlo blizu stvarne vrijednosti. Zaista nije bilo potrebno pokazivati toliko beznačajnih decimala.
Korak 6: Analiza stvarnog signala - Ožičenje ADC -a
Pošto znamo kako teoretski postupiti, htjeli bismo analizirati pravi signal.
Ožičenje je vrlo jednostavno. Spojite uzemljenje zajedno i signalnu liniju na A0 pin vaše ploče kroz serijski otpornik vrijednosti od 1 KOhm do 10 KOhm.
Ovaj serijski otpornik će zaštititi analogni ulaz i izbjeći zvonjenje. Mora biti što je moguće veće kako bi se izbjeglo zvonjenje, a što je moguće niže kako bi se osigurala dovoljna struja za brzo punjenje ADC -a. Pogledajte tehnički list MCU -a kako biste saznali očekivanu impedanciju signala spojenog na ADC ulaz.
Za ovaj demo koristio sam funkcijski generator za napajanje sinusoidnog signala frekvencije 440 Hz i amplitude oko 5 volti (najbolje je ako je amplituda između 3 i 5 volti, tako da se ADC koristi blizu pune skale), kroz otpornik od 1,2 KOhm.
Korak 7: Analiza stvarnog signala - kodiranje
0) Uključite biblioteku
#include "arduinoFFT.h"
1) Deklaracije i instalacije
U odjeljku deklaracije definiramo ADC ulaz (A0), broj uzoraka i frekvenciju uzorkovanja, kao u prethodnom primjeru.
const bajt adcPin = 0; // A0
const uint16_t uzorci = 1024; // Ova vrijednost MORA UVIJEK biti snaga 2 const uint16_t samplingFrequency = 8000; // Uticat će na maksimalnu vrijednost tajmera u timer_setup () SYSCLOCK/8/samplingFrequency bi trebao biti cijeli broj
Kreiramo ArduinoFFT objekt
ArduinoFFT FFT = ArduinoFFT (vReal, vImag, uzorci, samplingFrequency);
2) Podešavanje tajmera i ADC -a
Tajmer 1 smo postavili tako da radi na frekvenciji uzorkovanja (8 KHz) i pokreće prekid pri usporedbi izlaza.
void timer_setup () {
// resetiranje tajmera 1 TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; TCCR1B = bit (CS11) | bit (WGM12); // CTC, predskaler od 8 TIMSK1 = bit (OCIE1B); OCR1A = ((16000000/8) / frekvencija uzorkovanja) -1; }
I postavite ADC tako
- Koristi A0 kao ulaz
- Aktivira se automatski na svakom izlazu tajmera 1 uporedi podudaranje B
- Generira prekid kada je konverzija dovršena
ADC sat je postavljen na 1 MHz, predskaliranjem sistemskog takta (16 MHz) za 16. Budući da svaka konverzija traje približno 13 taktova u punom opsegu, konverzije se mogu postići na frekvenciji 1/13 = 0,076 MHz = 76 KHz. Učestalost uzorkovanja trebala bi biti znatno niža od 76 KHz kako bi ADC imao vremena za uzorkovanje podataka. (odabrali smo fs = 8 KHz).
void adc_setup () {
ADCSRA = bit (ADEN) | bit (ADIE) | bit (ADIF); // uključiti ADC, želim prekid po završetku ADCSRA | = bit (ADPS2); // Predkaler od 16 ADMUX = bit (REFS0) | (adcPin & 7); // postavljanje ADC ulaza ADCSRB = bit (ADTS0) | bit (ADTS2); // Tajmer/brojač1 Usporedi izvor okidača podudaranja B ADCSRA | = bit (ADATE); // uključi automatsko aktiviranje}
Deklariramo rukovatelj prekida koji će biti pozvan nakon svake ADC konverzije za spremanje pretvorenih podataka u niz vReal i brisanje prekida
// ADC kompletan ISR
ISR (ADC_vect) {vReal [broj rezultata ++] = ADC; if (broj rezultata == uzorci) {ADCSRA = 0; // isključuje ADC}} EMPTY_INTERRUPT (TIMER1_COMPB_vect);
Možete dobiti iscrpno objašnjenje o ADC konverziji na Arduinu (analogRead).
3) Podešavanje
U funkciji postavljanja brišemo zamišljenu tablicu podataka i pozivamo funkcije za postavljanje mjerača vremena i ADC -a
zeroI (); // funkcija koja postavlja na 0 sve imaginarne podatke - objašnjeno u prethodnom odjeljku
timer_setup (); adc_setup ();
3) Petlja
FFT.dcRemoval (); // Uklonite istosmjernu komponentu ovog signala jer se ADC odnosi na masu
FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward); // Vaganje podataka FFT.compute (FFTDirection:: Forward); // Računanje FFT FFT.complexToMagnitude (); // Računanje veličina // ispisivanje spektra i osnovne frekvencije f0 PrintVector (vReal, (uzorci >> 1), SCL_FREQUENCY); float x = FFT.majorPeak (); Serial.print ("f0 ="); Serial.print (x, 6); Serial.println ("Hz");
Uklanjamo istosmjernu komponentu jer se ADC odnosi na masu i signal je centriran približno na 2,5 volta.
Zatim izračunavamo podatke kako je objašnjeno u prethodnom primjeru.
Korak 8: Analiza stvarnog signala - rezultati
Zaista vidimo samo jednu frekvenciju u ovom jednostavnom signalu. Izračunata osnovna frekvencija je 440.118194 Hz. I ovdje je vrijednost vrlo bliska aproksimacija stvarne frekvencije.
Korak 9: Šta je sa izrezanim sinusoidnim signalom?
Hajde sada malo prenagliti ADC povećavajući amplitudu signala iznad 5 volti, tako da je odrezan. Ne gurajte previše da ne uništite ADC ulaz!
Možemo vidjeti neke harmonike koji se pojavljuju. Odsecanjem signala stvaraju se komponente visoke frekvencije.
Vidjeli ste osnove FFT analize na Arduino ploči. Sada možete pokušati promijeniti frekvenciju uzorkovanja, broj uzoraka i parametar prozora. Biblioteka dodaje i neke parametre za brže izračunavanje FFT -a s manje preciznosti. Primijetit ćete da će, ako postavite frekvenciju uzorkovanja prenisko, izračunate veličine izgledati potpuno pogrešne zbog spektralnog preklapanja.
Preporučuje se:
Kako napraviti LED analizator audio audio spektra: 7 koraka (sa slikama)
Kako napraviti LED analizator audio audio spektra: LED analizator audio spektra stvara prekrasan uzorak osvjetljenja prema intenzitetu muzike. Na tržištu je dostupno mnogo DIY LED muzičkih spektra, ali ovdje ćemo napraviti LED audio spektar Analizator koji koristi NeoPixe
Kako DIY 32 Band LED analizator audio audio muzičkog spektra pomoću Arduino Nano kod kuće #arduinoproject: 8 koraka
Kako DIY 32 -pojasni LED analizator audio audio muzičkog spektra koristiti Arduino Nano kod kuće #arduinoproject: Danas ćemo kod kuće napraviti 32 -pojasni analizator audio audio muzičkog spektra kod kuće koristeći Arduino, on može istovremeno prikazivati frekvencijski spektar i svirati muziku. mora biti spojen ispred otpornika od 100 k, u protivnom buka pipa
Analizator akrilnog spektra super veličine: 7 koraka (sa slikama)
Izuzetno veliki akrilni analizator spektra: Zašto biste htjeli pogledati te male LED zaslone ili one male LCD -ove ako to možete učiniti? Ovo je korak po korak opis o tome kako izgraditi vlastiti analizator spektra velike veličine. Korištenje akrilnih pločica i LED trake za izgradnju prostorije koja ispunjava svjetlost
DIY FFT analizator audio spektra: 3 koraka
DIY FFT analizator audio spektra: FFT analizator spektra je ispitna oprema koja koristi Fourierovu analizu i tehnike digitalne obrade signala za pružanje analize spektra. Pomoću Fourierove analize moguće je pretvoriti jednu vrijednost u, na primjer, neprekidnom vremenskom domenu
Analizator uzorka stijene: 4 koraka
Analizator uzoraka stijena: Analizator uzoraka stijena koristi se za identifikaciju i analizu vrsta uzoraka stijena tehnikom vibracija mekim udarcem. To je nova metoda u identifikaciji uzoraka stijena. Ako postoji meteorit ili bilo koji nepoznati uzorak stijene, može se procijeniti