Sisukord:
- Samm: kogu installimine
- 2. samm: Fourier 'teisendus ja FFT mõisted
- 3. samm: signaali simuleerimine
- 4. samm: simuleeritud signaali analüüs - kodeerimine
- 5. samm: simuleeritud signaali analüüs - tulemused
- 6. samm: tõelise signaali analüüs - ADC juhtmestik
- 7. samm: tegeliku signaali analüüs - kodeerimine
- 8. samm: tõelise signaali analüüs - tulemused
- Samm 9: Kuidas on lood kärbitud sinusoidaalse signaaliga?
Video: 1024 proovi FFT spektrinalüsaator Atmega1284 abil: 9 sammu
2024 Autor: John Day | [email protected]. Viimati modifitseeritud: 2024-01-30 08:47
See suhteliselt lihtne õpetus (arvestades selle teema keerukust) näitab teile, kuidas saate Arduino tüüpi plaati (1284 Narrow) ja jadaplotterit kasutades valmistada väga lihtsa 1024 proovi spektrinalüsaatori. Igasugune Arduinoga ühilduv plaat sobib, kuid mida rohkem on sellel RAM -i, seda parem on teie eraldusvõime. 1024 prooviga FFT arvutamiseks on vaja rohkem kui 8 KB muutmälu.
Spektri analüüsi kasutatakse signaali peamiste sageduskomponentide määramiseks. Paljud helid (nagu muusikainstrumendi helid) koosnevad põhisagedusest ja mõnest harmoonilisest, mille sagedus on põhisageduse täisarvuline mitmekordne. Spektrianalüsaator näitab teile kõiki neid spektrikomponente.
Võib -olla soovite seda seadet kasutada sagedusloendurina või kontrollida mis tahes signaale, mis kahtlustavad teie elektroonilises vooluringis müra.
Keskendume siin tarkvarale. Kui soovite luua konkreetse rakenduse jaoks alalisvooluahela, peate signaali võimendama ja filtreerima. See eelkonditsioneerimine sõltub täielikult signaalist, mida soovite uurida, sõltuvalt selle amplituudist, impedantsist, maksimaalsest sagedusest jne … Saate vaadata
Samm: kogu installimine
Kasutame ArduinoFFT raamatukogu, mille on kirjutanud Enrique Condes. Kuna tahame RAM -i võimalikult palju säästa, kasutame selle hoidla arendusharu, mis võimaldab proovivõetud ja arvutatud andmete salvestamiseks kasutada ujukandmetüüpi (kahekordse asemel). Seetõttu peame selle käsitsi installima. Ärge muretsege, laadige lihtsalt arhiiv alla ja pakkige see oma Arduino raamatukogu kausta lahti (näiteks Windows 10 vaikekonfiguratsioonis: C: / Users / _your_user_name_ / Documents / Arduino / libraries)
Saate kontrollida, kas kogu on õigesti installitud, koostades ühe esitatud näidetest, näiteks „FFT_01.ino”.
2. samm: Fourier 'teisendus ja FFT mõisted
Hoiatus: kui te ei talu ühtegi matemaatilist märget, võiksite minna 3. sammu juurde. Kui te ei saa sellest kõigest aru, kaaluge lihtsalt lõigu lõpus tehtud järeldust.
Sagedusspekter saadakse kiire Fourier -teisenduse algoritmi abil. FFT on digitaalne rakendus, mis lähendab Fourier 'teisenduse matemaatilist kontseptsiooni. Selle kontseptsiooni kohaselt, kui olete signaali evolutsiooni ajateljele järgnenud, saate teada selle esitamist sageduspiirkonnas, mis koosneb keerukatest (reaalsetest + kujuteldavatest) väärtustest. Kontseptsioon on vastastikune, nii et kui teate sageduspiirkonna esitusviisi, saate selle muuta ajadomeeniks ja saada signaal tagasi täpselt nagu enne teisendamist.
Aga mida me selle arvutuslike kompleksväärtuste kogumiga ajavaldkonnas tegema hakkame? Noh, suurem osa jääb inseneride hooleks. Meie jaoks kutsume teist algoritmi, mis muudab need keerukad väärtused spektraalse tiheduse andmeteks: see on iga sagedusalaga seotud suurusjärgu (= intensiivsuse) väärtus. Sagedusribade arv on sama, mis proovide arv.
Olete kindlasti kursis ekvalaiseri kontseptsiooniga, nagu see Tagasi 1980ndatesse graafilise ekvalaiseriga. Noh, me saame samalaadseid tulemusi, kuid 1024 riba asemel 16 ja palju suurema intensiivsusega. Kui ekvalaiser annab muusikale globaalse ülevaate, võimaldab peen spektraalanalüüs täpselt arvutada iga 1024 riba intensiivsuse.
Ideaalne kontseptsioon, kuid:
- Kuna FFT on Fourier 'teisenduse digitaliseeritud versioon, lähendab see digitaalsignaali ja kaotab teatud teabe. Seega, rangelt võttes, ei anna FFT tulemus ümberpööratud FFT algoritmiga tagasi teisendamisel täpselt algset signaali.
- Ka teooria käsitleb signaali, mis ei ole lõplik, kuid see on alati kestev signaal. Kuna me digitaliseerime selle ainult teatud aja jooksul (st proovid), tuuakse sisse veel mõned vead.
- Lõpuks mõjutab analoog -digitaalse muundamise eraldusvõime arvutatud väärtuste kvaliteeti.
Praktikas
1) proovivõtu sagedus (märgitud fs)
Proovime signaali, st mõõdame selle amplituudi iga 1/fs sekundi järel. fs on proovivõtu sagedus. Näiteks kui võtame proovi sagedusel 8 KHz, annab kiibil olev ADC (analoog -digitaalmuundur) mõõtmise iga 1/8000 sekundi järel.
2) Proovide arv (koodis märgitud N või proovid)
Kuna peame enne FFT käivitamist hankima kõik väärtused, peame need salvestama ja seega piirame proovide arvu. FFT algoritm vajab mitut näidist, mille võimsus on 2. Mida rohkem proove meil on, seda parem, kuid see võtab palju mälu, seda enam, et meil on vaja salvestada ka teisendatud andmed, mis on keerulised väärtused. Arduino FFT raamatukogu säästab kasutamisel ruumi
- Üks massiiv nimega "vReal", et salvestada proovivõetud andmed ja seejärel teisendatud andmete tegelik osa
- Üks massiiv nimega "vImag" teisendatud andmete kujuteldava osa salvestamiseks
Vajalik RAM -i kogus on 2 (massiivid) * 32 (bitti) * N (proovid).
Nii et meie Atmega1284, millel on kena 16 KB muutmälu, salvestame maksimaalselt N = 16000*8/64 = 2000 väärtust. Kuna väärtuste arv peab olema 2, salvestame maksimaalselt 1024 väärtust.
3) Sageduse eraldusvõime
FFT arvutab väärtused nii paljude sagedusribade jaoks kui proovide arv. Need ribad ulatuvad 0 HZ -st kuni proovivõtu sageduseni (fs). Seega on sageduse eraldusvõime järgmine:
Lahutusvõime = fs / N
Eraldusvõime on madalamal parem. Nii et parema eraldusvõime (madalama) tagamiseks soovime:
- rohkem proove ja/või
- madalam fs
Aga…
4) Minimaalne fs
Kuna me tahame näha palju sagedusi, millest mõned on "põhisagedusest" palju kõrgemad, ei saa me fs liiga madalaks seada. Tegelikult on olemas Nyquisti - Shannoni proovivõtu teoreem, mis sunnib meid valimissagedust tunduvalt ületama maksimaalsest sagedusest, mida tahaksime testida.
Näiteks kui tahame analüüsida kogu spektrit vahemikus 0 Hz kuni 15 KHz, mis on ligikaudu maksimaalne sagedus, mida enamik inimesi selgelt kuuleb, peame proovivõtmise sageduseks seadistama 30 KHz. Tegelikult määravad elektroonikud sageli maksimaalse sageduse 2,5 (või isegi 2,52) *. Selles näites oleks see 2,5 * 15 KHz = 37,5 KHz. Tavalised proovivõtu sagedused professionaalses helis on 44,1 KHz (audio -CD salvestus), 48 KHz ja rohkem.
Järeldus:
Punktid 1 kuni 4 toovad kaasa: me tahame kasutada võimalikult palju proove. 16 KB RAM -i puhul kaalume 1024 proovi. Tahame võtta proove võimalikult madalal diskreetimissagedusel, kui see on piisavalt kõrge, et analüüsida kõrgeimat sagedust, mida me oma signaalis ootame (vähemalt 2,5 korda).
3. samm: signaali simuleerimine
Esimese katse jaoks muudame veidi raamatukogus toodud TFT_01.ino näidet, et analüüsida signaali, mis koosneb
- Põhisagedus, 440 Hz (muusikaline A)
- Kolmas harmooniline põhivõimsuse poole võimsusega ("-3 dB")
- 5. harmooniline 1/4 põhivõimsuse võimsusest ("-6 dB)
Saadud signaali kohal oleval pildil näete. See näeb tõepoolest välja nagu tõeline signaal, mida ostsilloskoopil (ma nimetaksin seda "Batmaniks") mõnikord näha olukorras, kus toimub sinusoidaalse signaali lõikamine.
4. samm: simuleeritud signaali analüüs - kodeerimine
0) Kaasa raamatukogu
#include "arduinoFFT.h"
1) Mõisted
Deklaratsioonide osades on meil
konst bait adcPin = 0; // A0
const uint16_t proovid = 1024; // See väärtus PEAB ALATI olema võimsus 2 const uint16_t samplingFrequency = 8000; // Mõjutab taimeri max väärtust timer_setup () SYSCLOCK/8/samplingSagedus peab olema täisarv
Kuna signaalil on 5. harmooniline (selle harmoonilise sagedus = 5 * 440 = 2200 Hz), peame proovivõtusageduse seadma üle 2,5 * 2200 = 5500 Hz. Siin valisin 8000 Hz.
Samuti deklareerime massiivid, kuhu töötlemata ja arvutatud andmed salvestame
float vReal [proovid];
float vImag [proovid];
2) Instantiatsioon
Loome ArduinoFFT objekti. ArduinoFFT arendusversioon kasutab malli, et saaksime kasutada kas ujukit või kahekordset andmetüüpi. Ujuk (32 bitti) on meie programmi üldise täpsuse seisukohast piisav.
ArduinoFFT FFT = ArduinoFFT (vReal, vImag, proovid, proovide võtmise sagedus);
3) Signaali simuleerimine vReal massiivi täitmisega, selle asemel, et seda täita ADC väärtustega.
Tsükli alguses täidame massiivi vReal järgmiselt:
ujuktsüklid = ((((proovid) * signalFrequency) / samplingFrequency); // Signaalitsüklite arv, mida proovivõtt loeb
jaoks (uint16_t i = 0; i <proovid; i ++) {vReal = float ((amplituud * (sin ((i * (TWO_PI * tsüklit))) / proovid)))))); / * Koostage andmed positiivse ja negatiivsed väärtused */ vReal += float ((amplituud * (sin ((3 * i * (TWO_PI * tsüklit)))))))/) += ujuk ((amplituud * (sin ((5 * i * (TWO_PI * tsüklit))))) / proovid))) / 4,0); / * Koostage andmed positiivsete ja negatiivsete väärtustega * / vImag = 0,0; // Kujuteldav osa tuleb loopimise korral nullida, et vältida valesid arvutusi ja ületäitumist}
Lisame põhilaine ja kahe väiksema amplituudiga harmoonilise digitaliseerimise. Seejärel lähtestame kujuteldava massiivi nullidega. Kuna see massiiv on täidetud FFT algoritmiga, peame selle enne iga uut arvutust uuesti tühjendama.
4) FFT andmetöötlus
Seejärel arvutame FFT ja spektraaltiheduse
FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Edasi);
FFT.compute (FFTDirection:: Edasi); / * Arvuta FFT */ FFT.complexToMagnitude (); / * Arvuta suurusjärgud */
FFT.windowing (…) toiming muudab lähteandmeid, kuna käivitame FFT piiratud arvu proovide puhul. Esimesel ja viimasel proovil on katkestus (ühel küljel pole "midagi"). See on vigade allikas. Operatsioon "akendamine" kipub seda viga vähendama.
FFT.compute (…) suunaga "Edasi" arvutab teisenduse ajadomeenist sagedusdomeeniks.
Seejärel arvutame iga sagedusala jaoks suuruse (st intensiivsuse) väärtused. Massiiv vReal on nüüd täisväärtuste väärtustega täidetud.
5) Seeriaplotteri joonis
Prindime väärtused jadaplotterile, kutsudes funktsiooni printVector (…)
PrintVector (vReal, (näidised >> 1), SCL_FREQUENCY);
See on üldine funktsioon, mis võimaldab printida andmeid ajatelje või sagedusteljega.
Prindime ka sagedusriba, millel on suurim suurusjärk
float x = FFT.majorPeak ();
Seeria.print ("f0 ="); Seeriatrükk (x, 6); Serial.println ("Hz");
5. samm: simuleeritud signaali analüüs - tulemused
Näeme 3 naelu, mis vastavad põhisagedusele (f0), 3. ja 5. harmoonilist, poolega ja 1/4 f0 suurusjärgust, nagu oodatud. Akna ülaosast saame lugeda f0 = 440,430114 Hz. Kõigi ülalkirjeldatud põhjuste tõttu ei ole see väärtus täpselt 440 Hz, kuid on tegelikule väärtusele väga lähedal. Nii palju tühiseid kümnendkohti polnud tegelikult vaja näidata.
6. samm: tõelise signaali analüüs - ADC juhtmestik
Kuna teame, kuidas teoorias edasi minna, tahaksime analüüsida tõelist signaali.
Juhtmestik on väga lihtne. Ühendage maapind ja signaalliin oma plaadi A0 tihvtiga jadatakistuse abil, mille väärtus on 1 KOhm kuni 10 KOhm.
See seeria takisti kaitseb analoogsisendit ja väldib helisemist. See peab olema helisemise vältimiseks võimalikult kõrge ja võimalikult madal, et tagada piisavalt voolu ADC kiireks laadimiseks. Vaadake MCU andmelehte, et teada saada ADC sisendiga ühendatud signaali eeldatav takistus.
Selle demo jaoks kasutasin funktsioonigeneraatorit, et toita sinusoidaalset signaali sagedusega 440 Hz ja amplituudiga umbes 5 volti (kõige parem, kui amplituud on vahemikus 3 kuni 5 volti, nii et ADC -d kasutatakse täisskaala lähedal), 1,2 KOhm takisti kaudu.
7. samm: tegeliku signaali analüüs - kodeerimine
0) Kaasa raamatukogu
#include "arduinoFFT.h"
1) Deklaratsioonid ja instants
Deklaratsiooni osas määratleme ADC sisendi (A0), proovide arvu ja proovivõtu sageduse, nagu eelmises näites.
konst bait adcPin = 0; // A0
const uint16_t proovid = 1024; // See väärtus PEAB ALATI olema võimsuseks 2 const uint16_t samplingFrequency = 8000; // Mõjutab taimeri max väärtust timer_setup () SYSCLOCK/8/samplingSagedus peab olema täisarv
Loome ArduinoFFT objekti
ArduinoFFT FFT = ArduinoFFT (vReal, vImag, proovid, proovide võtmise sagedus);
2) Taimer ja ADC seadistamine
Seadsime taimeri 1 nii, et see toimiks diskreetimissagedusel (8 KHz) ja tõstaks katkestust väljundi võrdlemisel.
void timer_setup () {
// lähtesta taimer 1 TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; TCCR1B = bit (CS11) | bit (WGM12); // CTC, eelseadistaja 8 TIMSK1 = bit (OCIE1B); OCR1A = (((16000000 /8) / proovivõtu sagedus) -1; }
Ja seadke ADC nii
- Kasutab sisendina A0
- Käivitab automaatselt igal taimeri 1 väljundil võrdlus vaste B
- Loob katkestuse, kui teisendus on lõpule viidud
ADC kell on seatud 1 MHz -le, eelkvalifitseerides süsteemi kella (16 MHz) 16 -ga. Kuna iga teisendus võtab täies ulatuses umbes 13 kella, saab teisendusi teha sagedusel 1/13 = 0,076 MHz = 76 KHz. Proovivõtu sagedus peaks olema oluliselt madalam kui 76 KHz, et ADC -l oleks aega andmete proovimiseks. (valisime fs = 8 KHz).
void adc_setup () {
ADCSRA = bit (ADEN) | bit (ADIE) | bit (ADIF); // lülita ADC sisse, taha katkestada lõpetamisel ADCSRA | = bit (ADPS2); // Eelskaala 16 ADMUX = bit (REFS0) | (adcPin & 7); // ADC sisendi seadistamine ADCSRB = bit (ADTS0) | bit (ADTS2); // Taimer/loendur1 Võrdle mängu B päästikuallikat ADCSRA | = bit (ADATE); // automaatse käivitamise sisselülitamine}
Deklareerime katkestuste käitleja, kellele pärast iga ADC konversiooni helistatakse, et salvestada teisendatud andmed vReal massiivi ja katkestuse kustutamine
// ADC täielik ISR
ISR (ADC_vect) {vReal [resultNumber ++] = ADC; if (resultNumber == proovid) {ADCSRA = 0; // lülita ADC välja}} EMPTY_INTERRUPT (TIMER1_COMPB_vect);
Arduino (analogRead) ADC konversiooni kohta saate ammendava selgituse.
3) Seadistamine
Seadistusfunktsioonis kustutame kujuteldava andmetabeli ning kutsume taimer ja ADC seadistusfunktsioonid
nullI (); // funktsioon, mis seadis kõik kujuteldavad andmed väärtuseks 0 - selgitatud eelmises osas
timer_setup (); adc_setup ();
3) Silmus
FFT.dcRemoval (); // Eemaldage selle signaali alalisvoolukomponent, kuna ADC on viidatud maandusele
FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Edasi); // Kaaluge andmeid FFT.compute (FFTDirection:: Edasi); // Arvuta FFT FFT.complexToMagnitude (); // Suuruste arvutamine // spektri ja põhisageduse trükkimine f0 PrintVector (vReal, (proovid >> 1), SCL_FREQUENCY); float x = FFT.majorPeak (); Seeria.print ("f0 ="); Seeriatrükk (x, 6); Serial.println ("Hz");
Me eemaldame alalisvoolukomponendi, kuna ADC on viidatud maapinnale ja signaal on umbes 2,5 volti ümber.
Seejärel arvutame andmed, nagu eelmises näites selgitatud.
8. samm: tõelise signaali analüüs - tulemused
Tõepoolest, selles lihtsas signaalis näeme ainult ühte sagedust. Arvutatud põhisagedus on 440,118194 Hz. Ka siin on väärtus tegeliku sageduse väga lähedane ligikaudne väärtus.
Samm 9: Kuidas on lood kärbitud sinusoidaalse signaaliga?
Nüüd laseme ADC -l veidi üle sõita, suurendades signaali amplituudi üle 5 volti, nii et see on kärbitud. Ärge suruge liiga pudru, et mitte hävitada ADC sisendit!
Näeme mõningate harmooniliste ilmumist. Signaali lõikamine loob kõrgsageduslikud komponendid.
Olete näinud Arduino tahvlil FFT analüüsi põhialuseid. Nüüd võite proovida muuta proovivõtu sagedust, proovide arvu ja aknaparameetrit. Raamatukogu lisab ka mõned parameetrid, et FFT kiiremini ja vähem täpselt välja arvutada. Märkate, et kui seate diskreetimissageduse liiga madalaks, tunduvad arvutatud suurused spektri voltimise tõttu täiesti ekslikud.
Soovitan:
Isetegemine -- Kuidas teha ämblikrobotit, mida saab nutitelefoni abil Arduino Uno abil juhtida: 6 sammu
Isetegemine || Kuidas teha ämblikrobotit, mida saab nutitelefoni abil Arduino Uno abil juhtida: Ämblikroboti tegemisel saab robootika kohta nii mõndagi õppida. Nagu robotite tegemine, on see nii meelelahutuslik kui ka väljakutsuv. Selles videos näitame teile, kuidas teha ämblikrobot, mida saame juhtida oma nutitelefoni abil (Androi
ATmega328 programmeerimine Arduino IDE abil 8MHz kristalli abil: 4 sammu
ATmega328 programmeerimine Arduino IDE -ga, kasutades 8MHz kristalli: Selles süstitavas kirjeldan samm -sammult ATmega328P IC (sama mikrokontroller olemas Arudino UNO -l) programmeerimise juhendit, kasutades Arduino IDE -d ja Arduino UNO -d programmeerijana, et teha endale kohandatud Arduino, et oma projekte teha
Inimese ja arvuti liides: Funktsioon Gripper (valmistatud Kirigami poolt) randmeliigutuse abil EMG abil: 7 sammu
Inimese ja arvuti liides: Funktsioon Gripper (valmistatud Kirigami poolt) randmeliigutuse abil EMG abil. Nii et see oli minu esimene katse inimese ja arvuti liideses. Ma püüdsin randme liikumise lihaste aktiveerimissignaale EMG anduri abil, töödeldi seda läbi pythoni ja arduino ning käivitas origamipõhise haaratsi
Kella tegemine M5stick C abil Arduino IDE abil RTC reaalajas kell M5stack M5stick-C abil: 4 sammu
Kella tegemine M5stick C abil, kasutades Arduino IDE | RTC reaalajas kell koos M5stack M5stick-C-ga: Tere, selles juhendis olevad poisid, me õpime, kuidas Arduino IDE abil kella m5stick-C arendusplaadiga teha. Nii kuvab m5stick kuupäeva, kellaaja ja amp; kuunädal ekraanil
RGB maatriks + spektrinalüsaator: 10 sammu (piltidega)
RGB maatriks + spektraalanalüsaator: armastan LED -e? Mina ka! Sellepärast näitan selles juhendis teile, kuidas teha vinge RGB LED -maatriks, mis võib ühe nupuvajutusega hõlpsasti muutuda spektraalanalüsaatoriks. , kui arvate, et see Instructable on selle teeninud, palun hääletage