Satura rādītājs:
- 1. darbība: bibliotēkas instalēšana
- 2. solis: Furjē transformācijas un FFT jēdzieni
- 3. darbība: signāla simulācija
- 4. solis: Simulēta signāla - kodēšanas analīze
- 5. solis: Simulēta signāla analīze - rezultāti
- 6. darbība: reāla signāla analīze - ADC vadu savienošana
- 7. solis: reāla signāla analīze - kodēšana
- 8. solis: reāla signāla analīze - rezultāti
- 9. darbība: kā ir ar izgrieztu sinusoidālu signālu?
Video: 1024 paraugi FFT spektra analizators, izmantojot Atmega1284: 9 soļus
2024 Autors: John Day | [email protected]. Pēdējoreiz modificēts: 2024-01-30 10:53
Šī salīdzinoši vienkāršā apmācība (ņemot vērā šīs tēmas sarežģītību) parādīs, kā jūs varat izveidot ļoti vienkāršu 1024 paraugu spektra analizatoru, izmantojot Arduino tipa plāksni (1284 šaurs) un sērijveida ploteri. Derēs jebkura veida ar Arduino saderīga tāfele, taču, jo vairāk tajā ir RAM, jo labākā frekvences izšķirtspēja. Lai aprēķinātu FFT ar 1024 paraugiem, būs nepieciešami vairāk nekā 8 KB RAM.
Spektra analīzi izmanto, lai noteiktu signāla galvenās frekvences sastāvdaļas. Daudzas skaņas (piemēram, tās, kuras rada mūzikas instruments) sastāv no pamata frekvences un dažām harmonikām, kuru frekvence ir pamatfrekvences vesels skaitlis. Spektra analizators parādīs visus šos spektrālos komponentus.
Iespējams, vēlēsities izmantot šo iestatījumu kā frekvences skaitītāju vai pārbaudīt jebkāda veida signālus, kas, jūsuprāt, rada troksni jūsu elektroniskajā shēmā.
Šeit mēs koncentrēsimies uz programmatūras daļu. Ja vēlaties izveidot pastāvīgu ķēdi kādam konkrētam lietojumam, signāls ir jānostiprina un jāfiltrē. Šī iepriekšēja kondicionēšana ir pilnībā atkarīga no signāla, kuru vēlaties izpētīt, atkarībā no tā amplitūdas, pretestības, maksimālās frekvences utt. … Jūs varat pārbaudīt
1. darbība: bibliotēkas instalēšana
Mēs izmantosim ArduinoFFT bibliotēku, kuras autors ir Enrike Kondess. Tā kā mēs vēlamies pēc iespējas vairāk rezerves RAM, mēs izmantosim šīs krātuves izstrādes zaru, kas ļauj izmantot peldošo datu tipu (nevis dubultā), lai saglabātu izlases un aprēķinātos datus. Tāpēc mums tas jāinstalē manuāli. Neuztraucieties, vienkārši lejupielādējiet arhīvu un izsaiņojiet to savā Arduino bibliotēkas mapē (piemēram, Windows 10 noklusējuma konfigurācijā: C: / Users / _your_user_name_ / Documents / Arduino / libraries)
Lai pārbaudītu, vai bibliotēka ir pareizi instalēta, apkopojiet vienu no sniegtajiem piemēriem, piemēram, "FFT_01.ino".
2. solis: Furjē transformācijas un FFT jēdzieni
Brīdinājums: ja nevarat redzēt nevienu matemātisku apzīmējumu, iespējams, vēlēsities pāriet uz 3. darbību. Jebkurā gadījumā, ja nesaņemat visu, vienkārši apsveriet secinājumu sadaļas beigās.
Frekvenču spektru iegūst, izmantojot ātrā Furjē transformācijas algoritmu. FFT ir digitāla ieviešana, kas tuvina Furjē transformācijas matemātisko koncepciju. Saskaņā ar šo jēdzienu, kad esat ieguvis signāla evolūciju pēc laika ass, jūs varat uzzināt tā attēlojumu frekvenču apgabalā, kas sastāv no sarežģītām (reālām + iedomātām) vērtībām. Koncepcija ir abpusēja, tāpēc, zinot frekvenču domēna attēlojumu, varat to pārveidot laika domēnā un saņemt signālu tieši tāpat kā pirms pārveidošanas.
Bet ko mēs darīsim ar šo aprēķināto sarežģīto vērtību kopumu laika jomā? Nu, lielākā daļa tiks atstāta inženieru ziņā. Mums būs jāizsauc cits algoritms, kas pārveidos šīs sarežģītās vērtības spektra blīvuma datos: tā ir lieluma (= intensitātes) vērtība, kas saistīta ar katru frekvenču joslu. Frekvenču joslas skaits būs tāds pats kā paraugu skaits.
Jūs noteikti esat iepazinies ar ekvalaizera koncepciju, piemēram, šo Atpakaļ uz astoņdesmitajiem gadiem ar grafisko EQ. Mēs iegūsim tāda paša veida rezultātus, bet ar 1024 joslām, nevis 16 un daudz lielāku intensitātes izšķirtspēju. Kad ekvalaizers sniedz vispārēju priekšstatu par mūziku, smalkā spektrālā analīze ļauj precīzi aprēķināt katras no 1024 joslu intensitāti.
Ideāls jēdziens, bet:
- Tā kā FFT ir Furjē transformācijas digitalizēta versija, tā tuvina digitālo signālu un zaudē daļu informācijas. Tātad, stingri sakot, FFT rezultāts, ja tas tiktu pārveidots ar apgrieztu FFT algoritmu, nedotu tieši sākotnējo signālu.
- Arī teorija uzskata signālu, kas nav galīgs, bet tas ir nemainīgs nemainīgs signāls. Tā kā mēs to digitalizēsim tikai noteiktu laiku (ti, paraugi), tiks ieviestas vēl dažas kļūdas.
- Visbeidzot, analogu un ciparu pārveidošanas izšķirtspēja ietekmēs aprēķināto vērtību kvalitāti.
Praksē
1) paraugu ņemšanas biežums (atzīmēts fs)
Mēs ņemsim signāla paraugu, t.i., izmērīsim tā amplitūdu ik pēc 1 sekundēm. fs ir paraugu ņemšanas biežums. Piemēram, ja mēs ņemam paraugu pie 8 KHz, mikroshēmā esošais ADC (analogo ciparu pārveidotājs) nodrošinās mērījumus ik pēc 1/8000 sekundēm.
2) Paraugu skaits (kodā atzīmēts N vai paraugi)
Tā kā pirms FFT palaišanas mums ir jāiegūst visas vērtības, mums tās būs jāsaglabā, un tāpēc mēs ierobežosim paraugu skaitu. FFT algoritmam nepieciešami vairāki paraugi, kuru jauda ir 2. Jo vairāk paraugu mums ir, jo labāk, bet tas aizņem daudz atmiņas, vēl jo vairāk, ka mums būs arī jāsaglabā pārveidotie dati, kas ir sarežģītas vērtības. Arduino FFT bibliotēka ietaupa vietu, izmantojot
- Viens masīvs ar nosaukumu "vReal", lai saglabātu izlases datus un pēc tam pārveidoto datu reālo daļu
- Viens masīvs ar nosaukumu "vImag", lai saglabātu pārveidoto datu iedomāto daļu
Nepieciešamais RAM apjoms ir vienāds ar 2 (masīvi) * 32 (biti) * N (paraugi).
Tātad mūsu Atmega1284 ar jauku 16 KB RAM mēs saglabāsim ne vairāk kā N = 16000*8/64 = 2000 vērtības. Tā kā vērtību skaitam ir jābūt 2, mēs saglabāsim ne vairāk kā 1024 vērtības.
3) Frekvences izšķirtspēja
FFT aprēķinās vērtības tik daudzām frekvenču joslām kā paraugu skaits. Šīs joslas būs no 0 HZ līdz paraugu ņemšanas frekvencei (fs). Tādējādi frekvences izšķirtspēja ir šāda:
Izšķirtspēja = fs / N
Izšķirtspēja ir labāka, ja tā ir zemāka. Tāpēc labākai izšķirtspējai (zemākai) mēs vēlamies:
- vairāk paraugu un/vai
- zemāks fs
Bet…
4) Minimālais fs
Tā kā mēs vēlamies redzēt daudz frekvenču, dažas no tām ir daudz augstākas par "pamata frekvenci", mēs nevaram iestatīt fs pārāk zemu. Faktiski pastāv Nikvista - Šenona izlases teorēma, kas liek mums iegūt paraugu ņemšanas biežumu, kas krietni pārsniedz divreiz lielāku maksimālo frekvenci, kādu mēs vēlētos pārbaudīt.
Piemēram, ja mēs vēlamies analizēt visu spektru no 0 Hz līdz 15 KHz, kas ir aptuveni maksimālā frekvence, ko lielākā daļa cilvēku var skaidri dzirdēt, mums ir jāiestata paraugu ņemšanas frekvence 30 KHz. Faktiski elektroniķi to bieži nosaka 2,5 (vai pat 2,52) * maksimālajā frekvencē. Šajā piemērā tas būtu 2,5 * 15 KHz = 37,5 KHz. Parastās profesionālās audio paraugu ņemšanas frekvences ir 44,1 KHz (audio CD ierakstīšana), 48 KHz un vairāk.
Secinājums:
1. līdz 4. punkts noved pie: mēs vēlamies izmantot pēc iespējas vairāk paraugu. Mūsu gadījumā ar 16 KB RAM ierīci mēs ņemsim vērā 1024 paraugus. Mēs vēlamies ņemt paraugus pēc iespējas zemākā paraugu ņemšanas biežumā, ja vien tas ir pietiekami augsts, lai analizētu augstāko frekvenci, kādu mēs sagaidām savā signālā (vismaz 2,5 * šī frekvence).
3. darbība: signāla simulācija
Pirmajam mēģinājumam mēs nedaudz pārveidosim bibliotēkā sniegto TFT_01.ino piemēru, lai analizētu signālu, kas sastāv no
- Pamatfrekvence ir iestatīta uz 440 Hz (mūzikas A)
- 3. harmonika ar pusi no pamata jaudas ("-3 dB")
- 5. harmonika pie 1/4 no pamata jaudas ("-6 dB)
Jūs varat redzēt attēlā virs iegūtā signāla. Tas tiešām izskatās ļoti kā īsts signāls, ko dažreiz var redzēt osciloskopā (es to sauktu par "Betmenu") situācijā, kad notiek sinusoidāla signāla izgriešana.
4. solis: Simulēta signāla - kodēšanas analīze
0) Iekļaujiet bibliotēku
#include "arduinoFFT.h"
1) Definīcijas
Deklarāciju sadaļā mums ir
const baits adcPin = 0; // A0
const uint16_t paraugi = 1024; // Šai vērtībai VIENMĒR JĀBŪT 2 jauda konst uint16_t samplingFrequency = 8000; // Ietekmēs taimera maksimālo vērtību timer_setup () SYSCLOCK/8/samplingFrekvencei jābūt veselam skaitlim
Tā kā signālam ir piektā harmonika (šīs harmonikas frekvence = 5 * 440 = 2200 Hz), mums ir jāiestata paraugu ņemšanas frekvence virs 2,5 * 2200 = 5500 Hz. Šeit es izvēlējos 8000 Hz.
Mēs arī deklarējam masīvus, kuros glabāsim neapstrādātus un aprēķinātus datus
float vReal [paraugi];
pludiņš vImag [paraugi];
2) Instantiation
Mēs izveidojam ArduinoFFT objektu. ArduinoFFT izstrādātāja versijā tiek izmantota veidne, lai mēs varētu izmantot peldošo vai dubulto datu tipu. Ar pludiņu (32 bitiem) pietiek, ņemot vērā mūsu programmas vispārējo precizitāti.
ArduinoFFT FFT = ArduinoFFT (vReal, vImag, paraugi, paraugu ņemšanas biežums);
3) Simulējot signālu, aizpildot vReal masīvu, nevis aizpildot to ar ADC vērtībām.
Cikla sākumā mēs aizpildām vReal masīvu ar:
pludiņa cikli = ((((paraugi) * signalFrequency) / samplingFrequency); // Signāla ciklu skaits, ko izlasīs paraugu ņemšana
par (uint16_t i = 0; i <paraugi; i ++) {vReal = pludiņš ((amplitūda * (sin ((i * (TWO_PI * cikli))) / paraugi)))))); / * Veidojiet datus ar pozitīvu un negatīvas vērtības */ vReal += pludiņš ((amplitūda * (sin ((3 * i * (TWO_PI * cikli)))))/ paraugi)))/ 2.0);/ * Veidojiet datus ar pozitīvām un negatīvām vērtībām */ vReal += pludiņš ((amplitūda * (sin ((5 * i * (TWO_PI * cikli)))) / paraugi)))) / 4.0); / * Veidojiet datus ar pozitīvām un negatīvām vērtībām * / vImag = 0.0; // Iedomu daļa ir jāatkārto nulles gadījumā, ja tiek veikta cilpa, lai izvairītos no nepareiziem aprēķiniem un pārplūdēm}
Mēs pievienojam fundamentālā viļņa un divu harmoniku ar mazāku amplitūdu digitalizāciju. Mēs inicializējam iedomāto masīvu ar nullēm. Tā kā šis masīvs ir aizpildīts ar FFT algoritmu, mums tas ir jātīra vēlreiz pirms katra jauna aprēķina.
4) FFT skaitļošana
Tad mēs aprēķinām FFT un spektrālo blīvumu
FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward);
FFT.compute (FFTDirection:: Uz priekšu); / * Aprēķināt FFT */ FFT.complexToMagnitude (); / * Aprēķināt lielumus */
FFT.windowing (…) darbība maina neapstrādātus datus, jo mēs izpildām FFT ierobežotam paraugu skaitam. Pirmajam un pēdējam paraugam ir pārtraukums (vienā pusē nav “nekā”). Tas ir kļūdu avots. Operācija "logošana" mēdz mazināt šo kļūdu.
FFT.compute (…) ar virzienu "Uz priekšu" aprēķina transformāciju no laika domēna uz frekvences domēnu.
Tad mēs aprēķinām lieluma (ti, intensitātes) vērtības katrai frekvenču joslai. Masīvs vReal tagad ir piepildīts ar lieluma vērtībām.
5) Sērijveida plotera zīmējums
Izdrukāsim vērtības sērijveida ploterī, izsaucot funkciju printVector (…)
PrintVector (vReal, (paraugi >> 1), SCL_FREQUENCY);
Šī ir vispārīga funkcija, kas ļauj drukāt datus ar laika vai frekvences asi.
Mēs arī drukājam tās joslas frekvenci, kurai ir vislielākā vērtība
pludiņš x = FFT.majorPeak ();
Sērijas nospiedums ("f0 ="); Sērijas nospiedums (x, 6); Serial.println ("Hz");
5. solis: Simulēta signāla analīze - rezultāti
Mēs redzam 3 tapas, kas atbilst pamatfrekvencei (f0), 3. un 5. harmoniku ar pusi un 1/4 no f0 lieluma, kā gaidīts. Mēs varam nolasīt loga augšdaļā f0 = 440,430114 Hz. Visu iepriekš minēto iemeslu dēļ šī vērtība nav precīzi 440 Hz, taču tā ir ļoti tuvu reālajai vērtībai. Nebija īsti nepieciešams parādīt tik daudz nenozīmīgu decimāldaļu.
6. darbība: reāla signāla analīze - ADC vadu savienošana
Tā kā mēs teorētiski zinām, kā rīkoties, mēs vēlētos analizēt reālu signālu.
Elektroinstalācija ir ļoti vienkārša. Savienojiet pamatni kopā un signāla līniju ar plāksnes A0 tapu, izmantojot sērijveida rezistoru ar vērtību no 1 KOhm līdz 10 KOhm.
Šis sērijas rezistors aizsargās analogo ieeju un izvairīsies no zvana. Tam jābūt pēc iespējas augstākam, lai izvairītos no zvana, un pēc iespējas zemākam, lai nodrošinātu pietiekamu strāvu, lai ātri uzlādētu ADC. Skatiet MCU datu lapu, lai uzzinātu paredzamo ADC ieejai pievienotā signāla pretestību.
Šai demonstrācijai es izmantoju funkciju ģeneratoru, lai, izmantojot 1,2 KOhm rezistoru, ievadītu sinusoidālu signālu ar frekvenci 440 Hz un amplitūdu ap 5 voltiem (vislabāk, ja amplitūda ir no 3 līdz 5 voltiem, tāpēc ADC tiek izmantots gandrīz pilnā mērogā)..
7. solis: reāla signāla analīze - kodēšana
0) Iekļaujiet bibliotēku
#include "arduinoFFT.h"
1) Deklarācijas un instances
Deklarācijas sadaļā mēs definējam ADC ievadi (A0), paraugu skaitu un paraugu ņemšanas biežumu, tāpat kā iepriekšējā piemērā.
const baits adcPin = 0; // A0
const uint16_t paraugi = 1024; // Šai vērtībai VIENMĒR JĀBŪT 2 jauda konst uint16_t samplingFrequency = 8000; // Ietekmēs taimera maksimālo vērtību timer_setup () SYSCLOCK/8/samplingFrekvencei jābūt veselam skaitlim
Mēs izveidojam ArduinoFFT objektu
ArduinoFFT FFT = ArduinoFFT (vReal, vImag, paraugi, paraugu ņemšanas biežums);
2) Taimeris un ADC iestatīšana
Mēs iestatījām taimeri 1, lai tas darbotos paraugu ņemšanas frekvencē (8 KHz) un palielinātu izejas salīdzināšanas pārtraukumu.
void timer_setup () {
// atiestatīt 1. taimeri TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; TCCR1B = bits (CS11) | bits (WGM12); // CTC, prescaler of 8 TIMSK1 = bit (OCIE1B); OCR1A = (((16000000/8) / paraugu ņemšanas biežums) -1; }
Un iestatiet ADC tā
- Kā ievadi izmanto A0
- Aktivizē automātiski katrā 1. taimera izejā salīdzina atbilstību B
- Izveido pārtraukumu, kad konversija ir pabeigta
ADC pulkstenis ir iestatīts uz 1 MHz, iepriekš palielinot sistēmas pulksteni (16 MHz) par 16. Tā kā katra konversija aizņem aptuveni 13 pulksteņus pilnā mērogā, konvertēšanu var panākt ar frekvenci 1/13 = 0,076 MHz = 76 KHz. Paraugu ņemšanas biežumam jābūt ievērojami zemākam par 76 KHz, lai ADC būtu laiks datu paraugu ņemšanai. (mēs izvēlējāmies fs = 8 KHz).
void adc_setup () {
ADCSRA = bits (ADEN) | bits (ADIE) | bits (ADIF); // ieslēgt ADC, vēlēties pārtraukt pēc pabeigšanas ADCSRA | = bit (ADPS2); // Prescaler no 16 ADMUX = bits (REFS0) | (adcPin & 7); // ADC ievades iestatīšana ADCSRB = bits (ADTS0) | bits (ADTS2); // Taimeris/Skaitītājs1 Salīdzināt B spēles sprūda avotu ADCSRA | = bit (ADATE); // ieslēgt automātisko aktivizēšanu}
Mēs paziņojam par pārtraukuma apstrādātāju, kas tiks izsaukts pēc katras ADC reklāmguvuma, lai saglabātu konvertētos datus vReal masīvā un pārtraukuma dzēšanu
// ADC pilnīgs ISR
ISR (ADC_vect) {vReal [resultNumber ++] = ADC; ja (rezultātsNumurs == paraugi) {ADCSRA = 0; // izslēgt ADC}} EMPTY_INTERRUPT (TIMER1_COMPB_vect);
Jums var būt izsmeļošs skaidrojums par ADC konvertēšanu Arduino (analogRead).
3) Iestatīšana
Iestatīšanas funkcijā mēs notīrām iedomāto datu tabulu un izsaucam taimera un ADC iestatīšanas funkcijas
nulleI (); // funkcija, kas visus iedomātos datus iestatījusi uz 0 - paskaidrots iepriekšējā sadaļā
taimeris_iestatījums (); adc_setup ();
3) Cilpa
FFT.dcRemoval (); // Noņemiet šī signāla līdzstrāvas komponentu, jo ADC ir atsauce uz zemi
FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward); // Nosver datus FFT.compute (FFTDirection:: Forward); // Aprēķināt FFT FFT.complexToMagnitude (); // Aprēķināt lielumus // drukāt spektru un pamatfrekvenci f0 PrintVector (vReal, (paraugi >> 1), SCL_FREQUENCY); pludiņš x = FFT.majorPeak (); Sērijas nospiedums ("f0 ="); Sērijas nospiedums (x, 6); Serial.println ("Hz");
Mēs noņemam līdzstrāvas komponentu, jo ADC ir atsauce uz zemi un signāla centrs ir aptuveni 2,5 volti.
Tad mēs aprēķinām datus, kā paskaidrots iepriekšējā piemērā.
8. solis: reāla signāla analīze - rezultāti
Patiešām, šajā vienkāršajā signālā mēs redzam tikai vienu frekvenci. Aprēķinātā pamata frekvence ir 440,118194 Hz. Šeit atkal vērtība ir ļoti tuvu reālajai frekvencei.
9. darbība: kā ir ar izgrieztu sinusoidālu signālu?
Tagad ļaujiet nedaudz pārspēt ADC, palielinot signāla amplitūdu virs 5 voltiem, tāpēc tas tiek apgriezts. Nespiediet pārāk putru, lai neiznīcinātu ADC ievadi!
Mēs varam redzēt dažas harmonikas. Signāla griešana rada augstas frekvences komponentus.
Jūs esat redzējis FFT analīzes pamatus uz Arduino tāfeles. Tagad varat mēģināt mainīt paraugu ņemšanas biežumu, paraugu skaitu un loga parametru. Bibliotēka arī pievieno dažus parametrus, lai ātrāk un mazāk precīzi aprēķinātu FFT. Jūs ievērosiet, ka, iestatot pārāk zemu paraugu ņemšanas biežumu, aprēķinātie lielumi spektrālas locīšanas dēļ šķitīs pilnīgi kļūdaini.
Ieteicams:
Liela izmēra akrila spektra analizators: 7 soļi (ar attēliem)
Īpaši liela izmēra akrila spektra analizators: Kāpēc jūs vēlaties apskatīt šos mazos LED displejus vai mazos LCD, ja varat to izdarīt lielā veidā? Šis ir soli pa solim apraksts par to, kā izveidot savu milzu izmēra spektra analizatoru. vadīja sloksnes, lai izveidotu telpu piepildošu gaismu
DIY FFT audio spektra analizators: 3 soļi
DIY FFT audio spektra analizators: FFT spektra analizators ir testa iekārta, kas izmanto Furjē analīzi un digitālās signālu apstrādes metodes, lai nodrošinātu spektra analīzi. Izmantojot Furjē analīzi, ir iespējams konvertēt vienu vērtību, piemēram, nepārtrauktā laika domēnā
10 joslu LED spektra analizators: 11 soļi
10 Band Led Spectrum Analyzer: Labdien, dārgie skatītāji un lasītāji. Šodien es vēlos jums parādīt pilnu 10 joslu LED spektra analizatora montāžas rokasgrāmatu
RGB 10 joslu LED spektra analizators: 16 soļi
RGB 10 joslu spektra analizators: Labdien, dārgie skatītāji un lasītāji. Šodien es jums parādīšu desmit joslu spektra analizatora modifikāciju ar RGB gaismas diodēm
DIY Arduino audio signālu spektra analizators: 3 soļi
DIY Arduino audio signālu spektra analizators: tas ir ļoti vienkāršs audio analizators ar maināmiem vizuālajiem režīmiem