Sadržaj:

1024 uzorka FFT analizator spektra pomoću Atmega1284: 9 koraka
1024 uzorka FFT analizator spektra pomoću Atmega1284: 9 koraka

Video: 1024 uzorka FFT analizator spektra pomoću Atmega1284: 9 koraka

Video: 1024 uzorka FFT analizator spektra pomoću Atmega1284: 9 koraka
Video: Training Midjourney Level Style And Yourself Into The SD 1.5 Model via DreamBooth Stable Diffusion 2024, Srpanj
Anonim
1024 uzorka FFT analizator spektra pomoću Atmege1284
1024 uzorka FFT analizator spektra pomoću Atmege1284
1024 uzorka FFT analizator spektra pomoću Atmege1284
1024 uzorka FFT analizator spektra pomoću Atmege1284

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 pomoću ploče tipa Arduino (1284 uski) i serijskog plotera. Bilo koja vrsta Arduino kompatibilne ploče će poslužiti, ali što više RAM -a ima, najbolju frekvencijsku rezoluciju ćete dobiti. Za izračun FFT -a s 1024 uzorka trebat će više od 8 KB RAM -a.

Analiza spektra koristi se za određivanje glavnih frekvencijskih komponenti signala. Mnogi se zvukovi (poput onih koje proizvodi glazbeni instrument) sastoje od osnovne frekvencije i nekih harmonika koji imaju frekvenciju koja je cijeli broj višekratnik osnovne frekvencije. Analizator spektra pokazat će vam sve te spektralne komponente.

Možda biste htjeli koristiti ovu postavku kao brojač frekvencija ili provjeriti bilo koju vrstu signala za koje sumnjate da unose šum u vaš elektronički krug.

Ovdje ćemo se usredotočiti 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 knjižnice

Koristit ćemo ArduinoFFT knjižnicu koju je napisao Enrique Condes. Budući da želimo maksimalno uštedjeti RAM, upotrijebit ćemo razvojnu granu ovog spremišta koja omogućuje 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 svoju mapu knjižnice Arduino (na primjer na zadanoj konfiguraciji sustava Windows 10: C: / Users / _vaše_korisničko_naziv_ / Dokumenti / Arduino / knjižnice)

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 aproksimira matematički koncept Fourierove transformacije. Prema ovom konceptu, nakon što dobijete evoluciju signala koja slijedi vremensku os, možete znati njegovu reprezentaciju u frekvencijskoj domeni, sastavljenoj od složenih (stvarnih + zamišljenih) vrijednosti. Koncept je recipročan, pa kad znate prikaz frekvencijske domene možete ga transformirati natrag u vremensku domenu i vratiti signal točno kao prije transformacije.

No, što ćemo učiniti s ovim skupom izračunatih složenih vrijednosti u vremenskoj domeni? Pa, većina će biti prepuštena inženjerima. Za nas ćemo nazvati drugi algoritam koji će pretvoriti te 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 s konceptom ekvilajzera, poput ovog Povratak u 1980 -e s grafičkim ekvilajzerom. Pa, dobit ćemo iste vrste rezultata, ali s 1024 pojasa umjesto 16 i mnogo većom rezolucijom intenziteta. Kad ekvilajzer daje globalni prikaz glazbe, fina spektralna analiza omogućuje precizno izračunavanje intenziteta svakog od 1024 pojasa.

Savršen koncept, ali:

  1. 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 natrag s obrnutim algoritmom FFT, ne bi dao točno izvorni signal.
  2. Također teorija razmatra signal koji nije konačan, već je to trajan konstantan signal. Budući da ćemo ga digitalizirati samo određeno vrijeme (tj. Uzorci), bit će uvedene još neke pogreške.
  3. Konačno, razlučivost analogno -digitalne pretvorbe utjecat će na kvalitetu izračunatih vrijednosti.

U praksi

1) Učestalost uzorkovanja (zabilježeno fs)

Uzorit ćemo signal, tj. Mjeriti 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 izvođenja FFT -a, morat ćemo ih pohraniti pa ćemo ograničiti broj uzoraka. FFT algoritam treba niz uzoraka koji imaju snagu 2. Što više uzoraka imamo, to je bolje, ali zauzima puno memorije, utoliko ćemo više trebati za pohranu transformiranih podataka, koji su složene vrijednosti. Arduino FFT knjižnica štedi dio prostora korištenjem

  • Jedan niz pod nazivom "vReal" za pohranu uzorkovanih podataka, a zatim 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 stupanj 2, pohranit ćemo najviše 1024 vrijednosti.

3) Razlučivost frekvencije

FFT će izračunati vrijednosti za onoliko frekvencijskih područja koliko ima uzoraka. Ti će se rasponi protezati od 0 HZ do frekvencije uzorkovanja (fs). Dakle, frekvencijska rezolucija je:

Fresolucija = fs / N

Rezolucija je bolja ako je niža. Dakle, za bolju rezoluciju (nižu) ž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. Zapravo postoji Nyquist -Shannonov teorem uzorkovanja koji 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 otprilike najveća frekvencija koju većina ljudi može jasno čuti, moramo postaviti frekvenciju uzorkovanja na 30 KHz. Zapravo, 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 više uzoraka. U našem slučaju s 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 (barem 2,5 * ova frekvencija).

Korak 3: Simulacija signala

Simulacija signala
Simulacija signala

Za naš prvi pokušaj malo ćemo izmijeniti primjer TFT_01.ino dat u knjižnici kako bismo analizirali signal sastavljen od

  • Osnovna frekvencija, postavljena na 440 Hz (mjuzikl A)
  • 3. harmonik na pola snage osnovnog ("-3 dB")
  • 5. harmonik na 1/4 snage temeljnog ("-6 dB)

Rezultat signala možete vidjeti na slici iznad. Uistinu jako slič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 knjižnicu

#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 mjerača vremena 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) Instancijacija

Izrađujemo ArduinoFFT objekt. Dev verzija ArduinoFFT -a koristi predložak pa možemo koristiti ili float ili dvostruki tip podataka. Float (32 bita) dovoljan je s obzirom na ukupnu preciznost našeg programa.

ArduinoFFT FFT = ArduinoFFT (vReal, vImag, uzorci, frekvencija uzorkovanja);

3) Simulacija signala popunjavanjem polja vReal, 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 * ciklusi))) / 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 izračuni i prelijevanja}

Dodajemo digitalizaciju temeljnog vala i dva harmonika s manjom amplitudom. Nakon toga zamišljeni niz inicijaliziramo nulama. Budući da je ovaj niz popunjen algoritmom FFT, moramo ga očistiti prije svakog novog izračuna.

4) FFT računanje

Zatim izračunavamo FFT i spektralnu gustoću

FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward);

FFT.compute (FFTDirection:: Naprijed); / * 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 tu pogreš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 pojaseva. Niz vReal sada je ispunjen veličinama.

5) Crtež serijskog plotera

Ispisujmo vrijednosti na serijskom ploteru pozivanjem funkcije printVector (…)

PrintVector (vReal, (uzorci >> 1), SCL_FREQUENCY);

Ovo je generička funkcija koja omogućuje ispis podataka s vremenskom osi ili osi frekvencije.

Tiskamo i frekvenciju pojasa koja ima najveću vrijednost veličine

float x = FFT.majorPeak ();

Serial.print ("f0 ="); Serijski.ispis (x, 6); Serial.println ("Hz");

Korak 5: Analiza simuliranog signala - rezultati

Analiza simuliranog signala - rezultati
Analiza simuliranog signala - rezultati

Vidimo 3 skoka koji odgovaraju osnovnoj frekvenciji (f0), 3. i 5. harmonik, s polovicom i 1/4 veličine f0, kako se očekivalo. Možemo očitati pri vrhu prozora f0 = 440.430114 Hz. Ova vrijednost nije točno 440 Hz, iz svih gore navedenih razloga, ali je vrlo blizu stvarne vrijednosti. Nije baš bilo potrebno pokazivati toliko beznačajnih decimala.

Korak 6: Analiza stvarnog signala - ožičenje ADC -a

Analiza stvarnog signala - ožičenje ADC -a
Analiza stvarnog signala - ožičenje ADC -a

Budući da znamo kako postupiti u teoriji, 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 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 podatkovnu tablicu 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 u gotovo punoj skali), kroz otpornik od 1,2 KOhm.

Korak 7: Analiza stvarnog signala - kodiranje

0) Uključite knjižnicu

#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; // Utjecat će na maksimalnu vrijednost mjerača vremena u timer_setup () SYSCLOCK/8/samplingFrequency bi trebao biti cijeli broj

Izrađujemo ArduinoFFT objekt

ArduinoFFT FFT = ArduinoFFT (vReal, vImag, uzorci, frekvencija uzorkovanja);

2) Podešavanje timera i ADC -a

Timer 1 smo postavili tako da radi na frekvenciji uzorkovanja (8 KHz) i pokreće prekid pri usporedbi izlaza.

void timer_setup () {

// resetiranje mjerača vremena 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
  • Pokreće se automatski na svakom izlaznom odbrojavanju 1 uspoređuje podudaranje B
  • Generira prekid kada je pretvorba dovršena

Sat ADC -a postavljen je na 1 MHz, predskaliranjem takta sustava (16 MHz) za 16. Budući da svaka pretvorba zauzima 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 nakon dovršetka ADCSRA | = bit (ADPS2); // Predkaler od 16 ADMUX = bit (REFS0) | (adcPin & 7); // postavljanje ADC ulaza ADCSRB = bit (ADTS0) | bit (ADTS2); // Mjerač vremena/brojač1 Usporedi izvor okidača podudaranja B ADCSRA | = bit (ADATE); // uključi automatsko aktiviranje}

Deklariramo rukovatelja prekida koji će biti pozvan nakon svake ADC konverzije za spremanje pretvorenih podataka u niz vReal i brisanje prekida

// ADC potpuni 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) Postavljanje

U funkciji postavljanja brišemo zamišljenu tablicu podataka i pozivamo funkcije postavljanja timera i ADC -a

nulaI (); // 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 budući da je ADC spojen na masu

FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward); // Vaganje podataka FFT.compute (FFTDirection:: Forward); // Izračunaj 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 ="); Serijski.ispis (x, 6); Serial.println ("Hz");

Uklanjamo istosmjernu komponentu jer se ADC odnosi na masu, a 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

Analiza stvarnog signala - rezultati
Analiza stvarnog signala - rezultati

Zaista vidimo samo jednu frekvenciju u ovom jednostavnom signalu. Izračunata osnovna frekvencija je 440.118194 Hz. Ovdje je opet vrijednost vrlo bliska aproksimacija stvarne frekvencije.

Korak 9: Što je s izrezanim sinusoidnim signalom?

Što je s izrezanim sinusoidnim signalom?
Što je s 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 ulaz ADC -a!

Možemo vidjeti neke harmonike koji se pojavljuju. Isjecanjem 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. Knjižnica također dodaje neke parametre za brže izračunavanje FFT -a s manje preciznosti. Primijetit ćete da će, ako frekvenciju uzorkovanja postavite prenisko, izračunate veličine izgledati potpuno pogrešne zbog spektralnog presavijanja.

Preporučeni: