Բովանդակություն:

1024 նմուշ FFT սպեկտրի անալիզատոր `օգտագործելով Atmega1284: 9 քայլերը
1024 նմուշ FFT սպեկտրի անալիզատոր `օգտագործելով Atmega1284: 9 քայլերը

Video: 1024 նմուշ FFT սպեկտրի անալիզատոր `օգտագործելով Atmega1284: 9 քայլերը

Video: 1024 նմուշ FFT սպեկտրի անալիզատոր `օգտագործելով Atmega1284: 9 քայլերը
Video: Сравнение отрисовки спектра (FFT 1024 сэмпла на 20кГц) разным числом полос 2024, Նոյեմբեր
Anonim
1024 նմուշ FFT սպեկտրի անալիզատոր `օգտագործելով Atmega1284
1024 նմուշ FFT սպեկտրի անալիզատոր `օգտագործելով Atmega1284
1024 նմուշ FFT սպեկտրի անալիզատոր `օգտագործելով Atmega1284
1024 նմուշ FFT սպեկտրի անալիզատոր `օգտագործելով Atmega1284

Այս համեմատաբար հեշտ ձեռնարկը (հաշվի առնելով այս նյութի բարդությունը) ցույց կտա ձեզ, թե ինչպես կարող եք պատրաստել շատ պարզ 1024 նմուշի սպեկտրի անալիզատոր ՝ օգտագործելով Arduino տիպի տախտակ (1284 նեղ) և սերիական գծագրիչ: Arduino- ի հետ համատեղելի ցանկացած տիպի տախտակ կանի, բայց որքան ավելի շատ RAM ունենա, այնքան հաճախականության լավագույն լուծում կստանաք: FFT- ը 1024 նմուշով հաշվարկելու համար այն կպահանջի ավելի քան 8 ԿԲ օպերատիվ հիշողություն:

Սպեկտրի վերլուծությունը օգտագործվում է ազդանշանի հիմնական հաճախականության բաղադրիչները որոշելու համար: Շատ հնչյուններ (ինչպես երաժշտական գործիքի հնչյունները) կազմված են հիմնարար հաճախականությունից և որոշ ներդաշնակներից, որոնք ունեն հաճախականություն, որը հիմնական հաճախականության ամբողջ բազմապատիկն է: Սպեկտրի անալիզատորը ցույց կտա ձեզ այս բոլոր սպեկտրալ բաղադրիչները:

Դուք կարող եք օգտագործել այս կարգավորումը որպես հաճախությունների հաշվիչ կամ ստուգել ցանկացած տեսակի ազդանշաններ, որոնք կասկածում եք, որ ինչ -որ աղմուկ է բերում ձեր էլեկտրոնային շղթայում:

Այստեղ մենք կկենտրոնանանք ծրագրային ապահովման մասի վրա: Եթե ցանկանում եք մշտական միացում կատարել որոշակի ծրագրի համար, ապա ձեզ հարկավոր է ուժեղացնել և զտել ազդանշանը: Այս նախնական պայմանավորումը լիովին կախված է այն ազդանշանից, որը ցանկանում եք ուսումնասիրել ՝ կախված դրա լայնությունից, դիմադրությունից, առավելագույն հաճախականությունից և այլն … Կարող եք ստուգել

Քայլ 1: Գրադարանի տեղադրում

Մենք կօգտագործենք Էնրիկե Կոնդեսի հեղինակած ArduinoFFT գրադարանը: Քանի որ մենք ցանկանում ենք հնարավորինս խնայել RAM- ը, մենք կօգտագործենք այս շտեմարանի զարգացող ճյուղը, որը թույլ է տալիս օգտագործել float տվյալների տեսակը (կրկնակի փոխարեն) `ընտրանքային և հաշվարկված տվյալները պահելու համար: Այսպիսով, մենք պետք է այն ձեռքով տեղադրենք: Մի անհանգստացեք, պարզապես ներբեռնեք արխիվը և հանեք այն ձեր Arduino գրադարանի թղթապանակում (օրինակ ՝ Windows 10 -ի կանխադրված կազմաձևում ՝ C: / Users / _your_user_name_ / Documents / Arduino / libraries)

Դուք կարող եք ստուգել, որ գրադարանը ճիշտ է տեղադրված ՝ կազմելով մատուցված օրինակներից մեկը, օրինակ ՝ «FFT_01.ino»:

Քայլ 2. Fourier Transform և FFT հասկացություններ

Youգուշացում. Եթե դուք չեք դիմանում որևէ մաթեմատիկական նշան տեսնելուն, գուցե ցանկանաք անցնել Քայլ 3 -ին: Ամեն դեպքում, եթե այդ ամենը չեք ստանում, պարզապես հաշվի առեք եզրակացությունը հատվածի վերջում:

Հաճախականությունների սպեկտրը ձեռք է բերվում Fast Fourier Transform ալգորիթմի միջոցով: FFT- ը թվային իրականացում է, որը մոտեցնում է Ֆուրիեի տրանսֆորմացիայի մաթեմատիկական հայեցակարգին: Այս հայեցակարգի համաձայն, երբ դուք ստանում եք ազդանշանի էվոլյուցիան ժամանակային առանցքի հետևից, կարող եք իմանալ դրա ներկայացումը հաճախականությունների տիրույթում `կազմված բարդ (իրական + երևակայական) արժեքներից: Հայեցակարգը փոխադարձ է, ուստի, երբ իմանում եք հաճախականության տիրույթի ներկայացուցչությունը, կարող եք այն դարձնել ժամանակի տիրույթ և հետ ստանալ ազդանշանը ճիշտ այնպես, ինչպես փոխակերպումից առաջ:

Բայց ի՞նչ ենք անելու ժամանակային տիրույթում հաշվարկված բարդ արժեքների այս փաթեթով: Դե, դրա մեծ մասը կմնա ինժեներներին: Մեզ համար մենք կանվանենք մեկ այլ ալգորիթմ, որը այս բարդ արժեքները կվերածի սպեկտրալ խտության տվյալների. Դա մեծության (= ինտենսիվության) արժեք է ՝ կապված յուրաքանչյուր հաճախականությունների գոտու հետ: Հաճախականությունների գոտու քանակը նույնը կլինի, ինչ նմուշների թիվը:

Դուք, անշուշտ, ծանոթ եք հավասարեցնողի հայեցակարգին, ինչպիսին է սա ՝ 1980 -ականներին Graphic EQ- ով: Դե, մենք կստանանք նույն տեսակի արդյունքներ, բայց 1024 ժապավեններով ՝ 16 -ի փոխարեն և շատ ավելի ինտենսիվ լուծաչափով: Երբ հավասարեցուցիչը տալիս է երաժշտության գլոբալ պատկերացում, նուրբ սպեկտրալ վերլուծությունը թույլ է տալիս ճշգրիտ հաշվարկել 1024 խմբերից յուրաքանչյուրի ինտենսիվությունը:

Կատարյալ հասկացություն, բայց.

  1. Քանի որ FFT- ը Ֆուրիեի փոխակերպման թվայնացված տարբերակն է, այն մոտեցնում է թվային ազդանշանին և կորցնում որոշ տեղեկություններ: Այսպիսով, խստորեն ասած, FFT- ի արդյունքը, եթե հետ փոխարկվի շրջված FFT ալգորիթմով, չի տա հենց սկզբնական ազդանշանը:
  2. Նաև տեսությունը համարում է ազդանշան, որը վերջնական չէ, բայց դա մշտական կայուն ազդանշան է: Քանի որ մենք այն կթվայնացնենք միայն որոշակի ժամանակահատվածի համար (այսինքն ՝ նմուշներ), ևս մի քանի սխալներ կներդրվեն:
  3. Ի վերջո, անալոգային թվային փոխակերպման լուծումը կազդի հաշվարկված արժեքների որակի վրա:

Գործնականում

1) ընտրանքի հաճախականությունը (նշվում է fs)

Մենք ազդանշան ենք վերցնում, այսինքն ՝ չափում դրա ամպլիտուդը, յուրաքանչյուր 1/fs վայրկյանում: fs նմուշառման հաճախականությունն է: Օրինակ, եթե մենք նմուշ ենք վերցնում 8 ԿՀց հաճախականությամբ, ապա չիպի վրա գտնվող ADC (անալոգային թվային փոխարկիչ) չափումը կտրամադրի յուրաքանչյուր 1/8000 վայրկյանը մեկ:

2) Նմուշների քանակը (նշվում է N կամ նմուշներ ծածկագրում)

Քանի որ FFT- ն գործարկելուց առաջ մենք պետք է ստանանք բոլոր արժեքները, մենք ստիպված կլինենք դրանք պահել, ուստի մենք կսահմանափակենք նմուշների քանակը: FFT ալգորիթմին անհրաժեշտ են մի շարք նմուշներ, որոնք ունեն 2 հզորություն: Որքան շատ նմուշներ ունենանք, այնքան ավելի լավ, բայց կպահանջվի շատ հիշողություն, առավել ևս կպահանջվի նաև փոխակերպված տվյալները պահելու համար, որոնք բարդ արժեքներ են: Arduino FFT գրադարանը որոշակի տարածք է խնայում ՝ օգտագործելով

  • «VReal» անունով մեկ զանգված ՝ ընտրանքային տվյալները պահելու համար, այնուհետև փոխակերպված տվյալների իրական մասը
  • «VImag» անունով մեկ զանգված ՝ փոխակերպված տվյալների երևակայական մասը պահելու համար

RAM- ի անհրաժեշտ քանակը հավասար է 2 -ի (զանգվածներ) * 32 (բիթեր) * N (նմուշներ):

Այսպիսով, մեր Atmega1284- ում, որն ունի գեղեցիկ 16 ԿԲ օպերատիվ հիշողություն, մենք կպահենք առավելագույնը N = 16000*8 /64 = 2000 արժեք: Քանի որ արժեքների թիվը պետք է լինի 2 հզորություն, մենք կպահենք առավելագույնը 1024 արժեք:

3) հաճախականության լուծում

FFT- ն կհաշվարկի արժեքներ նույնքան հաճախականությունների տիրույթների համար, որքան նմուշների թիվը: Այս գոտիները կտարածվեն 0 HZ- ից մինչև ընտրանքի հաճախականությունը (fs): Այսպիսով, հաճախականության լուծումը հետևյալն է.

Բանաձև = fs / N

Բանաձևն ավելի լավ է, երբ ցածր է: Այսպիսով, ավելի լավ լուծման համար (ավելի ցածր) մենք ցանկանում ենք.

  • ավելի շատ նմուշներ և/կամ
  • ավելի ցածր ֆ

Բայց…

4) Նվազագույն ֆ

Քանի որ մենք ցանկանում ենք շատ հաճախականություններ տեսնել, դրանցից մի քանիսը շատ ավելի բարձր են, քան «հիմնարար հաճախականությունը», մենք չենք կարող fs- ն շատ ցածր դնել: Իրականում կա Nyquist – Shannon նմուշառման թեորեմը, որը մեզ ստիպում է ունենալ նմուշառման հաճախականություն, որը գերազանցում է առավելագույն հաճախականությունը, որը մենք կցանկանայինք ստուգել:

Օրինակ, եթե մենք ցանկանում ենք վերլուծել 0 Հց -ից մինչև 15 ԿՀց սպեկտրը, որը մոտավորապես այն առավելագույն հաճախականությունն է, որը շատերը կարող են հստակ լսել, մենք պետք է ընտրանքի հաճախականությունը սահմանենք 30 ԿՀց: Իրականում էլեկտրոնիկայի մասնագետները հաճախ այն սահմանում են 2,5 (կամ նույնիսկ 2,52) * առավելագույն հաճախականությամբ: Այս օրինակում դա կլինի 2,5 * 15 ԿՀց = 37,5 ԿՀց: Սովորական ընտրանքային հաճախականությունները պրոֆեսիոնալ աուդիոյում կազմում են 44.1 ԿՀց (ձայնասկավառակ ձայնագրում), 48 ԿՀց և ավելի:

Եզրակացություն

1 -ից 4 -րդ կետերը հանգեցնում են. Մենք ցանկանում ենք հնարավորինս շատ նմուշներ օգտագործել: Մեր դեպքում 16 ԿԲ RAM սարքի դեպքում մենք հաշվի կառնենք 1024 նմուշ: Մենք ցանկանում ենք հնարավորինս նմուշառման ամենացածր հաճախականությամբ նմուշ վերցնել, քանի դեռ այն բավականաչափ բարձր է ՝ վերլուծելու մեր ազդանշանում ակնկալվող ամենաբարձր հաճախականությունը (առնվազն 2,5 անգամ այս հաճախականությունը):

Քայլ 3: Ազդանշանի մոդելավորում

Ազդանշանի մոդելավորում
Ազդանշանի մոդելավորում

Մեր առաջին փորձի համար մենք փոքր -ինչ կփոխենք գրադարանում տրված TFT_01.ino օրինակը `վերլուծելու համար կազմված ազդանշանը

  • Հիմնական հաճախականությունը ՝ 440 Հց (երաժշտական A)
  • 3-րդ ներդաշնակ ՝ հիմնարարի հզորության կեսով («-3 դԲ»)
  • 5-րդ ներդաշնակությունը հիմնարարի հզորության 1/4-ում ("-6 դԲ)

Դուք կարող եք տեսնել նկարի վերևում ստացված ազդանշանը: Այն իսկապես շատ նման է իսկական ազդանշանի, որը երբեմն կարելի է տեսնել օսլիլոսկոպով (ես դա կանվանեի «Բեթմեն») այն իրավիճակում, երբ կա սինուսոիդային ազդանշանի կտրում:

Քայլ 4. Մոդելացված ազդանշանի վերլուծություն - կոդավորում

0) Ներառել գրադարանը

#ներառել «arduinoFFT.h»

1) սահմանումներ

Հռչակագրերի բաժիններում մենք ունենք

const բայթ adcPin = 0; // A0

const uint16_t նմուշներ = 1024; // Այս արժեքը ՊԻՏԻ ՄԻՇՏ լինի 2 const uint16_t samplingFrequency = 8000 հզորություն; // Կազդի ժամանակաչափի առավելագույն արժեքի վրա timer_setup () SYSCLOCK/8/ընտրանքային հաճախականությունը պետք է լինի ամբողջ թիվ

Քանի որ ազդանշանն ունի 5 -րդ ներդաշնակություն (այս ներդաշնակության հաճախականությունը = 5 * 440 = 2200 Հց) մենք պետք է ընտրանքի հաճախականությունը սահմանենք 2,5 * 2200 = 5500 Հց -ից բարձր: Այստեղ ես ընտրեցի 8000 Հց:

Մենք նաև հայտարարում ենք այն զանգվածները, որտեղ մենք կպահենք հում և հաշվարկված տվյալները

float vReal [նմուշներ];

float vImag [նմուշներ];

2) իրականացում

Մենք ստեղծում ենք ArduinoFFT օբյեկտ: ArduinoFFT- ի dev տարբերակը օգտագործում է ձևանմուշ, որպեսզի մենք կարողանանք օգտագործել կամ բոց կամ կրկնակի տվյալների տեսակը: Float (32 բիթ) բավական է մեր ծրագրի ընդհանուր ճշգրտության առումով:

ArduinoFFT FFT = ArduinoFFT (vReal, vImag, նմուշներ, ընտրանքային հաճախականություն);

3) ազդանշանի մոդելավորում ՝ լրացնելով vReal զանգվածը ՝ այն ADC արժեքներով համալրելու փոխարեն:

Loop- ի սկզբում մենք vReal զանգվածը համալրում ենք հետևյալով.

float cycles = ((((նմուշներ) * signalFrequency) / samplingFrequency); // Ազդանշանի ցիկլերի քանակը, որոնք ընտրանքը կկարդա

for (uint16_t i = 0; i <նմուշներ; i ++) {vReal = float ((amplitude * (sin ((i * (TWO_PI * ցիկլեր)) / նմուշներ)))); / * Ստեղծել տվյալներ դրական և բացասական արժեքներ */ vReal += float ((ամպլիտուդ * (մեղք ((3 * i * (TWO_PI * ցիկլեր))/ նմուշներ)))/ 2.0);/ * Ստեղծել դրական և բացասական արժեքներով տվյալներ */ vReal += float ((ամպլիտուդ * (մեղք ((5 * i * (TWO_PI * ցիկլեր)) / նմուշներ))) / 4.0); / * Ստեղծել դրական և բացասական արժեքներով տվյալներ * / vImag = 0.0; // Երեւակայական մասը պետք է զրոյականացվի շրջադարձի դեպքում `սխալ հաշվարկներից եւ վարարումներից խուսափելու համար}

Մենք ավելացնում ենք հիմնարար ալիքի և երկու ներդաշնակության թվայնացում ավելի փոքր ամպլիտուդով: Դրանից հետո մենք զրոյականորեն նախաստորագրում ենք երևակայական զանգվածը: Քանի որ այս զանգվածը բնակեցված է FFT ալգորիթմով, մենք պետք է այն նորից մաքրենք յուրաքանչյուր նոր հաշվարկից առաջ:

4) FFT հաշվարկ

Այնուհետև մենք հաշվարկում ենք FFT- ն և սպեկտրալ խտությունը

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

FFT.compute (FFTDirection:: Forward); / * Հաշվել FFT */ FFT.complexToMagnitude (); / * Հաշվարկել մեծությունները */

FFT.windowing (…) գործողությունը փոփոխում է հում տվյալները, քանի որ մենք FFT- ն աշխատում ենք սահմանափակ թվով նմուշների վրա: Առաջին և վերջին նմուշները ներկայացնում են անընդհատություն (նրանցից մեկում «ոչինչ» չկա): Սա սխալի աղբյուր է: «Պատուհանների պատուհան» գործողությունը հակված է նվազեցնել այս սխալը:

FFT.compute (…) «Առաջ» ուղղությամբ հաշվարկում է ժամանակի տիրույթից փոխակերպումը հաճախականության տիրույթին:

Հետո մենք հաշվարկում ենք մեծության (այսինքն ՝ ինտենսիվության) արժեքները հաճախականությունների յուրաքանչյուր գոտու համար: VReal զանգվածն այժմ լցված է մեծությունների արժեքներով:

5) սերիական գծանկարչի նկարչություն

Եկեք տպենք արժեքները սերիական գծագրիչի վրա ՝ կանչելով printVector գործառույթը (…)

PrintVector (vReal, (նմուշներ >> 1), SCL_FREQUENCY);

Սա ընդհանուր գործառույթ է, որը թույլ է տալիս տվյալներ տպել ժամանակի կամ հաճախականության առանցքով:

Մենք նաև տպում ենք ամենաբարձր մեծության արժեք ունեցող խմբի հաճախականությունը

float x = FFT.majorPeak ();

Serial.print ("f0 ="); Serial.print (x, 6); Serial.println («Հց»);

Քայլ 5. Մոդելացված ազդանշանի վերլուծություն - արդյունքներ

Մոդելավորված ազդանշանի վերլուծություն - արդյունքներ
Մոդելավորված ազդանշանի վերլուծություն - արդյունքներ

Մենք տեսնում ենք հիմնային հաճախականությանը համապատասխանող 3 ցատկ (f0), 3 -րդ և 5 -րդ ներդաշնակություն, ինչպես և սպասվում էր f0 մեծության կեսով և 1/4 -ով: Մենք կարող ենք կարդալ պատուհանի վերևում f0 = 440.430114 Հց: Այս արժեքը հենց 440 Հց չէ, վերը բացատրված բոլոր պատճառների պատճառով, բայց այն շատ մոտ է իրական արժեքին: Իրականում պետք չէր այդքան աննշան տասնորդականներ ցույց տալ:

Քայլ 6. Իրական ազդանշանի վերլուծություն. ADC- ի միացում

Իրական ազդանշանի վերլուծություն
Իրական ազդանշանի վերլուծություն

Քանի որ մենք գիտենք, թե ինչպես շարունակել տեսականորեն, մենք կցանկանայինք վերլուծել իրական ազդանշանը:

Էլեկտրամոնտաժը շատ պարզ է: Միացրեք հիմքերը և ազդանշանային գիծը ձեր տախտակի A0 կապին ՝ 1 ԿՕմ -ից 10 ԿՕմ արժեք ունեցող մի շարք դիմադրության միջոցով:

Այս շարքի դիմադրությունը կպաշտպանի անալոգային մուտքը և խուսափի զանգերից: Այն պետք է լինի հնարավորինս բարձր `զանգից խուսափելու համար, և հնարավորինս ցածր` ապահովելու համար բավարար հոսանք `ADC- ն արագ լիցքավորելու համար: Անդրադառնացեք MCU- ի տվյալների թերթիկին ՝ ADC- ի մուտքի մոտ միացված ազդանշանի ակնկալվող դիմադրողականությունը իմանալու համար:

Այս ցուցադրման համար ես օգտագործել եմ ֆունկցիայի գեներատոր ՝ 440 Հց հաճախականությամբ սինուսոիդ ազդանշան և 5 վոլտ ամպլիտուդ (լավագույնը, եթե ամպլիտուդը 3 -ից 5 վոլտերի միջև է, այնպես որ ADC- ն օգտագործվում է ամբողջ մասշտաբով), 1,2 KOhm ռեզիստորի միջոցով:.

Քայլ 7. Իրական ազդանշանի վերլուծություն - կոդավորում

0) Ներառել գրադարանը

#ներառել «arduinoFFT.h»

1) հայտարարագրեր և հրահանգներ

Հռչակագրի բաժնում մենք սահմանում ենք ADC մուտքագրումը (A0), նմուշների քանակը և ընտրանքի հաճախականությունը, ինչպես նախորդ օրինակում:

const բայթ adcPin = 0; // A0

const uint16_t նմուշներ = 1024; // Այս արժեքը ՊԻՏԻ ՄԻՇՏ լինի 2 const uint16_t samplingFrequency = 8000 հզորություն; // Կազդի ժամանակաչափի առավելագույն արժեքի վրա timer_setup () SYSCLOCK/8/sampling Հաճախականությունը պետք է լինի ամբողջ թիվ

Մենք ստեղծում ենք ArduinoFFT օբյեկտը

ArduinoFFT FFT = ArduinoFFT (vReal, vImag, նմուշներ, ընտրանքային հաճախականություն);

2) erամաչափի և ADC- ի կարգավորում

Մենք սահմանում ենք ժմչփ 1 -ը, որպեսզի այն պտտվի նմուշառման հաճախականությամբ (8 ԿՀց) և բարձրացնի ելքի համեմատության ընդհատում:

void timer_setup () {

// վերականգնել erամաչափ 1 TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; TCCR1B = բիթ (CS11) | բիթ (WGM12); // CTC, 8 TIMSK1 = նախաքարտաչափ (բիթ) (OCIE1B); OCR1A = ((16000000 /8) / նմուշառման հաճախականություն) -1; }

Եվ այնպես կարգավորեք ADC- ն

  • Օգտագործում է A0 որպես մուտքագրում
  • Automaticallyամաչափի յուրաքանչյուր ելքի վրա ինքնաբերաբար գործարկում է B համընկնումը
  • Ստեղծում է ընդհատում, երբ փոխակերպումն ավարտված է

ADC ժամացույցը սահմանվում է 1 ՄՀց -ով, համակարգի ժամացույցը (16 ՄՀց) նախաստորագրելով 16 -ով: Քանի որ յուրաքանչյուր փոխարկում տևում է մոտ 13 ժամացույց ամբողջ ծավալով, փոխակերպումները կարող են հասնել 1/13 = 0,076 ՄՀց = 76 ԿՀց հաճախականությամբ: Նմուշառման հաճախականությունը պետք է զգալիորեն ցածր լինի 76 ԿՀց -ից, որպեսզի ADC- ն ժամանակ ունենա տվյալների նմուշառման համար: (մենք ընտրեցինք fs = 8 ԿՀց):

void adc_setup () {

ADCSRA = բիթ (ADEN) | բիթ (ADIE) | բիթ (ADIF); // միացնել ADC- ն, ուզում եմ ընդհատել ավարտին ADCSRA | = բիթ (ADPS2); // 16 ADMUX = նախնական սակարկիչ = բիթ (REFS0) | (adcPin & 7); // ADC մուտքագրման կարգավորում ADCSRB = բիթ (ADTS0) | բիթ (ADTS2); // erամաչափ/Counter1 Համեմատել Match B ձգանման աղբյուր ADCSRA | = բիթ (ADATE); // միացնել ավտոմատ ձգումը}

Մենք հայտարարում ենք ընդհատումների մշակողի մասին, որը կանչվելու է յուրաքանչյուր ADC փոխարկումից հետո ՝ փոխակերպված տվյալները պահելու vReal զանգվածում և ընդհատման մաքրում

// ADC ամբողջական ISR

ISR (ADC_vect) {vReal [resultNumber ++] = ADC; if (resultNumber == նմուշներ) {ADCSRA = 0; // անջատել ADC}} EMPTY_INTERRUPT (TIMER1_COMPB_vect);

Դուք կարող եք ունենալ սպառիչ բացատրություն Arduino- ի ADC փոխարկման վերաբերյալ (analogRead):

3) կարգավորումը

Կարգավորման գործառույթում մենք մաքրում ենք երևակայական տվյալների աղյուսակը և կանչում ենք ժամաչափի և ADC կարգաբերման գործառույթները

զրո I (); // ֆունկցիա, որը սահմանում է 0 բոլոր երևակայական տվյալները - բացատրված է նախորդ բաժնում

timer_setup (); adc_setup ();

3) հանգույց

FFT.dcRemoval (); // Հեռացրեք այս ազդանշանի DC բաղադրիչը, քանի որ ADC- ն հղված է գետնին

FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward); // Քաշեք տվյալները FFT.compute (FFTDirection:: Forward); // Հաշվել FFT FFT.complexToMagnitude (); // Հաշվարկել մեծությունները // տպել սպեկտրը և հիմնական հաճախականությունը f0 PrintVector (vReal, (նմուշներ >> 1), SCL_FREQUENCY); float x = FFT.majorPeak (); Serial.print ("f0 ="); Serial.print (x, 6); Serial.println («Հց»);

Մենք հեռացնում ենք DC բաղադրիչը, քանի որ ADC- ն հղված է գետնին, և ազդանշանը կենտրոնացած է մոտ 2,5 վոլտի մոտակայքում:

Այնուհետև մենք հաշվարկում ենք տվյալները, ինչպես բացատրված է նախորդ օրինակում:

Քայլ 8. Իրական ազդանշանի վերլուծություն - արդյունքներ

Իրական ազդանշանի վերլուծություն - արդյունքներ
Իրական ազդանշանի վերլուծություն - արդյունքներ

Իրոք, մենք տեսնում ենք միայն մեկ հաճախականություն այս պարզ ազդանշանի մեջ: Հաշվարկված հիմնարար հաճախականությունը 440.118194 Հց է: Այստեղ կրկին արժեքը իրական հաճախականության շատ մոտ մոտեցում է:

Քայլ 9. Ինչ վերաբերում է ճեղքված սինուսոիդային ազդանշանին:

Ինչ վերաբերում է ճեղքված սինուսոիդային ազդանշանին
Ինչ վերաբերում է ճեղքված սինուսոիդային ազդանշանին

Այժմ թույլ տվեք մի փոքր գերագնահատել ADC- ը ՝ ազդանշանի ամպլիտուդը բարձրացնելով 5 վոլտից, այնպես որ այն կտրված է: Շատ մի՛ մղեք, որպեսզի չկործանեք ADC մուտքագրումը:

Մենք կարող ենք տեսնել, որ որոշ ներդաշնակներ են հայտնվում: Ազդանշանի սեղմումը ստեղծում է բարձր հաճախականության բաղադրիչներ:

Դուք տեսել եք FFT վերլուծության հիմունքները Arduino տախտակի վրա: Այժմ կարող եք փորձել փոխել նմուշառման հաճախականությունը, նմուշների քանակը և պատուհանի պարամետրը: Գրադարանը նաև ավելացնում է որոշ պարամետր ՝ FFT- ն ավելի արագ ճշգրտելու համար: Դուք կնկատեք, որ եթե նմուշառման հաճախականությունը չափազանց ցածր դնեք, հաշվարկված մեծությունները սպեկտրալ ծալման պատճառով բոլորովին սխալ կհայտնվեն:

Խորհուրդ ենք տալիս: