Obsah:

1024 vzoriek analyzátora spektra FFT pomocou Atmega1284: 9 krokov
1024 vzoriek analyzátora spektra FFT pomocou Atmega1284: 9 krokov

Video: 1024 vzoriek analyzátora spektra FFT pomocou Atmega1284: 9 krokov

Video: 1024 vzoriek analyzátora spektra FFT pomocou Atmega1284: 9 krokov
Video: КТО ПОСЛЕДНИЙ ПЕРЕСТАНЕТ ВЫПОЛНЯТЬ ЗАДАНИЯ, ПОЛУЧИТ 1000$ 2024, November
Anonim
1024 vzoriek analyzátora spektra FFT pomocou zariadenia Atmega1284
1024 vzoriek analyzátora spektra FFT pomocou zariadenia Atmega1284
1024 vzoriek analyzátora spektra FFT pomocou zariadenia Atmega1284
1024 vzoriek analyzátora spektra FFT pomocou zariadenia Atmega1284

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:

  1. 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.
  2. 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.
  3. 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

Simulácia signálu
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

Analýza simulovaného signálu - výsledky
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

Analýza skutočného signálu - zapojenie ADC
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

Analýza skutočného signálu - výsledky
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?

Čo orezaný sínusový signál?
Čo orezaný sínusový signál?

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: