Obsah:
- Krok 1: Inštalácia knižnice
- Krok 2: Fourierova transformácia a koncepty FFT
- Krok 3: Simulácia signálu
- Krok 4: Analýza simulovaného signálu - kódovanie
- Krok 5: Analýza simulovaného signálu - výsledky
- Krok 6: Analýza skutočného signálu - zapojenie ADC
- Krok 7: Analýza skutočného signálu - kódovanie
- Krok 8: Analýza skutočného signálu - výsledky
- Krok 9: Čo s orezaným sínusovým signálom?
Video: 1024 vzoriek analyzátora spektra FFT pomocou Atmega1284: 9 krokov
2024 Autor: John Day | [email protected]. Naposledy zmenené: 2024-01-30 11:57
Tento relatívne ľahký tutoriál (vzhľadom na zložitosť tohto predmetu) vám ukáže, ako je možné vytvoriť veľmi jednoduchý analyzátor spektra 1024 vzoriek pomocou dosky typu Arduino (1284 Narrow) a sériového plotra. Postačí akýkoľvek druh dosky kompatibilnej s Arduino, ale čím viac pamäte RAM má, tým lepšie frekvenčné rozlíšenie získate. Na výpočet FFT s 1024 vzorkami bude potrebovať viac ako 8 KB RAM.
Spektrálna analýza sa používa na určenie hlavných frekvenčných zložiek signálu. Mnoho zvukov (ako tie, ktoré produkuje hudobný nástroj) pozostáva zo základnej frekvencie a niektorých harmonických, ktoré majú frekvenciu, ktorá je celým číslom násobkom základnej frekvencie. Spektrálny analyzátor vám ukáže všetky tieto spektrálne zložky.
Toto nastavenie možno budete chcieť použiť ako čítač frekvencie alebo na kontrolu akéhokoľvek druhu signálov, o ktorých máte podozrenie, že spôsobujú rušenie vo vašom elektronickom obvode.
Tu sa zameriame na softvérovú časť. Ak chcete vytvoriť trvalý obvod pre konkrétnu aplikáciu, budete musieť zosilniť a filtrovať signál. Toto predkondicionovanie úplne závisí od signálu, ktorý chcete študovať, v závislosti od jeho amplitúdy, impedancie, maximálnej frekvencie atď. Môžete to skontrolovať
Krok 1: Inštalácia knižnice
Budeme používať knižnicu ArduinoFFT napísanú Enrique Condesom. Pretože chceme čo najviac ušetriť RAM, použijeme vývojovú vetvu tohto úložiska, ktorá umožňuje ukladať vzorkované a vypočítané údaje pomocou typu float (namiesto dvojitého). Musíme ho teda nainštalovať ručne. Nebojte sa, stačí stiahnuť archív a dekomprimovať ho do priečinka knižnice Arduino (napríklad v predvolenej konfigurácii systému Windows 10: C: / Users / _vase_uzivatelske_jméno_ / Documents / Arduino / libraries)
Zostavením jedného z uvedených príkladov, ako napríklad „FFT_01.ino“, môžete skontrolovať, či je knižnica správne nainštalovaná.
Krok 2: Fourierova transformácia a koncepty FFT
Varovanie: Ak nemôžete vystáť žiadny matematický zápis, možno budete chcieť preskočiť na krok 3. V prípade, že nerozumiete všetkému, vezmite do úvahy záver na konci sekcie.
Frekvenčné spektrum sa získava pomocou algoritmu Fast Fourierovej transformácie. FFT je digitálna implementácia, ktorá približuje matematický koncept Fourierovej transformácie. Podľa tohto konceptu, akonáhle získate evolúciu signálu po časovej osi, môžete poznať jeho reprezentáciu vo frekvenčnej oblasti, zloženej zo zložitých (skutočných + imaginárnych) hodnôt. Tento koncept je recipročný, takže keď poznáte reprezentáciu frekvenčnej domény, môžete ju transformovať späť do časovej domény a získať signál späť presne ako pred transformáciou.
Čo však urobíme s touto sadou vypočítaných komplexných hodnôt v časovej oblasti? Väčšina z toho bude ponechaná na inžinierov. Budeme pre nás nazývať ďalší algoritmus, ktorý transformuje tieto komplexné hodnoty na údaje spektrálnej hustoty: to je hodnota veľkosti (= intenzita) spojená s každým frekvenčným pásmom. Počet frekvenčných pásiem bude rovnaký ako počet vzoriek.
Určite ste oboznámení s konceptom ekvalizéra, ako je tento Späť do osemdesiatych rokov minulého storočia s grafickým ekvalizérom. Získame rovnaký druh výsledkov, ale s 1024 pásmami namiesto 16 a oveľa intenzívnejším rozlíšením. Keď ekvalizér poskytuje celkový pohľad na hudbu, jemná spektrálna analýza umožňuje presne vypočítať intenzitu každého z 1024 pásiem.
Perfektný koncept, ale:
- Pretože FFT je digitalizovaná verzia Fourierovej transformácie, aproximuje digitálny signál a stráca niektoré informácie. Presne povedané, výsledok FFT, ak by bol transformovaný späť pomocou invertovaného algoritmu FFT, by neposkytoval presne pôvodný signál.
- Teória tiež zvažuje signál, ktorý nie je konečný, ale je to stále trvajúci konštantný signál. Pretože ho budeme digitalizovať iba na určité časové obdobie (t.j. vzorky), zavedie sa niekoľko ďalších chýb.
- Rozlíšenie analógovej a digitálnej konverzie bude mať vplyv na kvalitu vypočítaných hodnôt.
V praxi
1) Vzorkovacia frekvencia (uvedené fs)
Signál, tj. Zmerajte jeho amplitúdu, budeme vzorkovať každú 1/fs sekundy. fs je vzorkovacia frekvencia. Ak napríklad vzorkujeme pri 8 KHz, ADC (analógovo -digitálny prevodník), ktorý je súčasťou čipu, poskytne meranie každých 1/8 000 sekúnd.
2) Počet vzoriek (v kóde je uvedené N alebo vzoriek)
Pretože pred spustením FFT potrebujeme získať všetky hodnoty, budeme ich musieť uložiť, a tak obmedzíme počet vzoriek. Algoritmus FFT potrebuje množstvo vzoriek, ktorých sila je 2. Čím viac vzoriek máme, tým lepšie, ale zaberie to veľa pamäte, o to viac budeme potrebovať aj uloženie transformovaných údajov, čo sú komplexné hodnoty. Knižnica Arduino FFT šetrí miesto pomocou
- Jedno pole s názvom „vReal“na uloženie vzorkovaných údajov a potom skutočnej časti transformovaných údajov
- Jedno pole s názvom „vImag“na uloženie imaginárnej časti transformovaných údajov
Potrebné množstvo pamäte RAM sa rovná 2 (polia) * 32 (bity) * N (vzorky).
Takže v našom Atmega1284, ktorý má pekných 16 KB RAM, uložíme maximálne N = 16 000*8/64 = 2000 hodnôt. Pretože počet hodnôt musí byť mocninou 2, uložíme maximálne 1024 hodnôt.
3) Rozlíšenie frekvencie
FFT vypočíta hodnoty pre toľko frekvenčných pásiem, ako je počet vzoriek. Tieto pásma budú mať rozsah od 0 Hz do vzorkovacej frekvencie (fs). Rozlíšenie frekvencie je teda:
Fresolution = fs / N
Rozlíšenie je lepšie, keď je nižšie. Pre lepšie rozlíšenie (nižšie) teda chceme:
- viac vzoriek a/alebo
- nižšia fs
Ale…
4) Minimálne fs
Pretože chceme vidieť veľa frekvencií, niektoré z nich sú oveľa vyššie ako „základná frekvencia“, nemôžeme nastaviť fs príliš nízko. V skutočnosti existuje vzorkovacia veta Nyquist – Shannon, ktorá nás núti mať vzorkovaciu frekvenciu výrazne nad dvojnásobkom maximálnej frekvencie, ktorú by sme chceli testovať.
Ak by sme napríklad chceli analyzovať celé spektrum od 0 Hz, povedzme 15 KHz, čo je približne maximálna frekvencia, ktorú väčšina ľudí zreteľne počuje, musíme nastaviť vzorkovaciu frekvenciu na 30 KHz. V skutočnosti ho elektronici často nastavujú na 2,5 (alebo dokonca 2,52) * maximálnej frekvencie. V tomto prípade by to bolo 2,5 * 15 KHz = 37,5 KHz. Obvyklé vzorkovacie frekvencie v profesionálnom zvuku sú 44,1 KHz (záznam zvukového disku CD), 48 KHz a ďalšie.
Záver:
Body 1 až 4 vedú k: chceme použiť čo najviac vzoriek. V našom prípade so 16 KB zariadením RAM zvážime 1024 vzoriek. Chceme vzorkovať na najnižšej vzorkovacej frekvencii, ako je to možné, pokiaľ je dostatočne vysoká na analýzu najvyššej frekvencie, ktorú v našom signáli očakávame (najmenej 2,5 x táto frekvencia).
Krok 3: Simulácia signálu
Pri prvom pokuse mierne upravíme príklad TFT_01.ino uvedený v knižnici, aby sme analyzovali signál zložený z
- Základná frekvencia nastavená na 440 Hz (hudobné A)
- 3. harmonická pri polovičnom výkone základného („-3 dB“)
- 5. harmonická pri 1/4 výkonu základného („-6 dB)
Na obrázku nad výsledným signálom môžete vidieť. Vyzerá to naozaj veľmi podobne ako skutočný signál, ktorý je niekedy možné vidieť na osciloskope (nazval by som to „Batman“) v situácii, keď dôjde k orezaniu sínusového signálu.
Krok 4: Analýza simulovaného signálu - kódovanie
0) Zahrnúť knižnicu
#include "arduinoFFT.h"
1) Definície
V sekciách vyhlásení máme
const byte adcPin = 0; // A0
const uint16_t vzorky = 1024; // Táto hodnota VŽDY musí byť silou 2 konšt uint16_t samplingFrequency = 8000; // Ovplyvní maximálnu hodnotu časovača v timer_setup () SYSCLOCK/8/samplingFrekvencia by mala byť celé číslo
Pretože signál má 5. harmonickú (frekvencia tejto harmonickej = 5 * 440 = 2200 Hz), musíme nastaviť vzorkovaciu frekvenciu nad 2,5 * 2200 = 5500 Hz. Tu som zvolil 8 000 Hz.
Deklarujeme tiež polia, do ktorých budeme ukladať nespracované a vypočítané údaje
float vReal [vzorky];
float vImag [vzorky];
2) Inštancia
Vytvárame objekt ArduinoFFT. Verzia ArduinoFFT pre vývoj používa šablónu, takže môžeme použiť buď dátový typ float, alebo dvojitý údaj. Float (32 bitov) stačí na celkovú presnosť nášho programu.
ArduinoFFT FFT = ArduinoFFT (vReal, vImag, vzorky, vzorkovacia frekvencia);
3) Simulácia signálu vyplnením poľa vReal namiesto toho, aby bol osadený hodnotami ADC.
Na začiatku slučky naplníme pole vReal pomocou:
float cykly = ((((vzorky) * signálna frekvencia) / vzorkovacia frekvencia); // Počet signálnych cyklov, ktoré vzorkovanie načíta
pre (uint16_t i = 0; i <vzorky; i ++) {vReal = float ((amplitúda * (sin ((i * (TWO_PI * cykly)) / vzorky)))) / / * Zostavte údaje s pozitívnymi a záporné hodnoty */ vReal += float ((amplitúda * (sin ((3 * i * (TWO_PI * cykly))/ vzorky))))/ 2,0);/ * Zostavenie údajov s kladnými a zápornými hodnotami */ vReal += float ((amplitúda * (sin ((5 * i * (TWO_PI * cyklov)) / vzorky))) / 4,0); / * Zostavte údaje s kladnými a zápornými hodnotami * / vImag = 0,0; // Imaginárna časť sa musí v prípade cyklu opakovať, aby sa predišlo nesprávnym výpočtom a pretečeniu}
Pridávame digitalizáciu základnej vlny a dvoch harmonických s menšou amplitúdou. Potom inicializujeme imaginárne pole nulami. Pretože toto pole je obsadené algoritmom FFT, musíme ho pred každým novým výpočtom znova vyčistiť.
4) FFT výpočty
Potom vypočítame FFT a spektrálnu hustotu
FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward);
FFT.compute (FFTDirection:: Forward); / * Compute FFT */ FFT.complexToMagnitude (); / * Výpočtové veličiny */
Operácia FFT.windowing (…) upravuje nespracované údaje, pretože FFT prevádzkujeme na obmedzenom počte vzoriek. Prvá a posledná vzorka predstavujú diskontinuitu (na jednej z ich strán nie je „nič“). Toto je zdroj chýb. Operácia „otváranie okien“má tendenciu túto chybu znižovať.
FFT.compute (…) so smerom „Vpred“vypočíta transformáciu z časovej domény do frekvenčnej oblasti.
Potom vypočítame hodnoty veľkosti (t.j. intenzity) pre každé z frekvenčných pásiem. Pole vReal je teraz plné hodnôt veličín.
5) Výkres sériového plotra
Vytlačme hodnoty na sériový plotter zavolaním funkcie printVector (…)
PrintVector (vReal, (vzorky >> 1), SCL_FREQUENCY);
Ide o generickú funkciu, ktorá umožňuje tlač údajov s časovou osou alebo frekvenčnou osou.
Vytlačíme tiež frekvenciu pásma, ktoré má najvyššiu hodnotu veľkosti
float x = FFT.majorPeak ();
Serial.print ("f0 ="); Serial.print (x, 6); Serial.println ("Hz");
Krok 5: Analýza simulovaného signálu - výsledky
Vidíme 3 hroty zodpovedajúce základnej frekvencii (f0), 3. a 5. harmonickú, s polovicou a 1/4 magnitúdy f0, ako sa očakávalo. V hornej časti okna môžeme čítať f0 = 440,430114 Hz. Táto hodnota nie je presne 440 Hz, kvôli všetkým vyššie vysvetleným dôvodom, ale je veľmi blízko skutočnej hodnote. Ukázať toľko bezvýznamných desatinných miest nebolo skutočne potrebné.
Krok 6: Analýza skutočného signálu - zapojenie ADC
Keďže vieme, ako teoreticky postupovať, chceli by sme analyzovať skutočný signál.
Zapojenie je veľmi jednoduché. Pripojte uzemnenie dohromady a signálne vedenie k pinu A0 vašej dosky pomocou sériového odporu s hodnotou od 1 KOhm do 10 KOhm.
Tento sériový odpor bude chrániť analógový vstup a zabráni zvoneniu. Musí byť čo najvyššia, aby sa zabránilo zvoneniu, a čo najnižšia, aby poskytovala dostatok prúdu na rýchle nabitie ADC. V údajovom liste MCU sa dozviete očakávanú impedanciu signálu pripojeného na vstup ADC.
Na toto demo som použil funkčný generátor na napájanie sínusového signálu s frekvenciou 440 Hz a amplitúdou okolo 5 voltov (najlepšie je, ak je amplitúda medzi 3 a 5 voltmi, takže sa ADC používa v blízkosti plného rozsahu), cez odpor 1,2 KOhm.
Krok 7: Analýza skutočného signálu - kódovanie
0) Zahrnúť knižnicu
#include "arduinoFFT.h"
1) Vyhlásenia a inštancia
V deklaračnej časti definujeme vstup ADC (A0), počet vzoriek a vzorkovaciu frekvenciu, ako v predchádzajúcom prípade.
const byte adcPin = 0; // A0
const uint16_t vzorky = 1024; // Táto hodnota VŽDY musí byť silou 2 konšt uint16_t samplingFrequency = 8000; // Ovplyvní maximálnu hodnotu časovača v timer_setup () SYSCLOCK/8/samplingFrekvencia by mala byť celé číslo
Vytvárame objekt ArduinoFFT
ArduinoFFT FFT = ArduinoFFT (vReal, vImag, vzorky, vzorkovacia frekvencia);
2) Nastavenie časovača a ADC
Nastavili sme časovač 1 tak, aby cykloval pri vzorkovacej frekvencii (8 KHz) a spôsobil prerušenie pri porovnaní výstupu.
neplatné timer_setup () {
// reset časovača 1 TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; TCCR1B = bit (CS11) | bit (WGM12); // CTC, prescaler 8 TIMSK1 = bit (OCIE1B); OCR1A = ((16000000 /8) / vzorkovacia frekvencia) -1; }
A nastavte ADC tak
- Ako vstup používa A0
- Spúšťa automaticky pri každom výstupe časovača 1 porovnanie zápasu B
- Po dokončení prevodu generuje prerušenie
Hodiny ADC sú nastavené na 1 MHz tak, že systémový takt (16 MHz) sa predbežne predmerá na 16. Pretože každá konverzia trvá približne 13 hodín v plnom rozsahu, je možné prevody dosiahnuť na frekvencii 1/13 = 0,076 MHz = 76 KHz. Vzorkovacia frekvencia by mala byť výrazne nižšia ako 76 KHz, aby mal ADC čas na vzorkovanie údajov. (vybrali sme fs = 8 KHz).
neplatné adc_setup () {
ADCSRA = bit (ADEN) | bit (ADIE) | bit (ADIF); // zapnite ADC, chcete prerušenie po dokončení ADCSRA | = bit (ADPS2); // Predzmerovač 16 ADMUX = bit (REFS0) | (adcPin & 7); // nastavenie vstupu ADC ADCSRB = bit (ADTS0) | bit (ADTS2); // Časovač/Počítadlo1 Porovnať zdroj spúšťača zhody B ADCSRA | = bit (ADATE); // zapnite automatické spúšťanie}
Deklarujeme obslužný program prerušenia, ktorý sa bude volať po každej konverzii ADC na uloženie konvertovaných údajov do poľa vReal a vymazanie prerušenia
// ADC kompletný ISR
ISR (ADC_vect) {vReal [resultNumber ++] = ADC; if (resultNumber == vzorky) {ADCSRA = 0; // vypnúť ADC}} EMPTY_INTERRUPT (TIMER1_COMPB_vect);
Môžete mať vyčerpávajúce vysvetlenie prevodu ADC na Arduino (analogRead).
3) Nastavenie
Vo funkcii nastavenia vymažeme imaginárnu tabuľku údajov a vyvoláme funkcie nastavenia časovača a ADC
nula I (); // funkcia, ktorá nastavila na 0 všetky imaginárne údaje - vysvetlené v predchádzajúcej časti
timer_setup (); adc_setup ();
3) Slučka
FFT.dcRemoval (); // Odstráňte DC zložku tohto signálu, pretože ADC je odkazovaný na uzemnenie
FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward); // Odvážte údaje FFT.compute (FFTDirection:: Forward); // Vypočítajte FFT FFT.complexToMagnitude (); // Výpočtové veličiny // tlač spektra a základnej frekvencie f0 PrintVector (vReal, (vzorky >> 1), SCL_FREQUENCY); float x = FFT.majorPeak (); Serial.print ("f0 ="); Serial.print (x, 6); Serial.println ("Hz");
Jednosmernú zložku odstránime, pretože ADC sa vzťahuje na uzemnenie a signál je vycentrovaný približne na 2,5 voltov.
Potom vypočítame údaje podľa vysvetlenia v predchádzajúcom príklade.
Krok 8: Analýza skutočného signálu - výsledky
V tomto jednoduchom signáli skutočne vidíme iba jednu frekvenciu. Vypočítaná základná frekvencia je 440,118194 Hz. Aj tu je hodnota veľmi blízkym priblížením skutočnej frekvencie.
Krok 9: Čo s orezaným sínusovým signálom?
Teraz umožňuje trocha preťažiť ADC zvýšením amplitúdy signálu nad 5 voltov, takže je orezaný. Netlačte príliš kašovito, aby ste nezničili vstup ADC!
Môžeme vidieť, ako sa objavujú niektoré harmonické. Orezaním signálu sa vytvoria vysokofrekvenčné komponenty.
Na doske Arduino ste videli základy analýzy FFT. Teraz sa môžete pokúsiť zmeniť vzorkovaciu frekvenciu, počet vzoriek a parameter okna. Knižnica tiež pridáva niektoré parametre na rýchlejší výpočet FFT s menšou presnosťou. Všimnite si, že ak nastavíte vzorkovaciu frekvenciu príliš nízku, vypočítané veličiny budú kvôli spektrálnemu skladaniu pôsobiť úplne chybne.
Odporúča:
Mikrofón dychového analyzátora: 25 krokov (s obrázkami)
Mikrofón dychového analyzátora: Mikrofón dychového analyzátora je systém na nenápadné zhromažďovanie údajov o hladine obsahu alkoholu v krvi. Inými slovami, triezvosť osoby môžete zmerať pomocou zariadenia, ktoré na všetky účely a účely nevyzerá inak ako stojan
DIY FFT analyzátor zvukového spektra: 3 kroky
DIY FFT analyzátor zvukového spektra: FFT spektrálny analyzátor je testovacie zariadenie, ktoré na analýzu spektra používa Fourierovu analýzu a techniky spracovania digitálneho signálu. Pomocou Fourierovej analýzy je možné jednu hodnotu, napríklad v spojitej časovej oblasti, previesť
Hodiny analyzátora signálu Arduino DCF77: 17 krokov
Hodiny analyzátora signálu Arduino DCF77: Hodiny & Arduino DCF77 Analyzátor signálu Tieto hodiny môžete vidieť aj na webe myweb tu, Stránka hodín analyzátora DCF77Tieto hodiny zobrazujú prijaté & dekódovaný časový kód DCF77 na troch bodových displejoch 8x8 a informácie o čase, dátume a signáli na štyroch 8
Skalný analyzátor vzoriek: 4 kroky
Analyzátor vzoriek hornín: Analyzátor vzoriek kameňov sa používa na identifikáciu a analýzu typov vzoriek hornín pomocou vibračnej techniky s mäkkým príklepom. Je to nová metóda pri identifikácii vzoriek hornín. Ak je tu meteorit alebo akákoľvek neznáma vzorka hornín, je možné odhadnúť
Stupeň pečeného infračerveného analyzátora pre pražiarne kávy: 13 krokov (s obrázkami)
Stupeň praženého infračerveného analyzátora pre pražiarne kávy: ÚvodKáva je nápoj konzumovaný po celom svete pre svoje senzorické a funkčné vlastnosti. Káva, chuť, aróma, kofeín a obsah antioxidantov sú len niektoré z vlastností, vďaka ktorým je kávový priemysel taký úspešný. Kým g