Мазмұны:
- 1 -қадам: Кітапхананы орнату
- 2 -қадам: Фурье трансформациясы және ФФТ тұжырымдамалары
- 3 -қадам: сигналды модельдеу
- 4 -қадам: имитациялық сигналды талдау - кодтау
- 5 -қадам: имитациялық сигналды талдау - нәтижелер
- 6 -қадам: Нақты сигналды талдау - ADC сымдарын қосу
- 7 -қадам: Нақты сигналды талдау - кодтау
- 8 -қадам: нақты сигналды талдау - нәтижелер
- 9 -қадам: Қысылған синусоидалы сигнал туралы не деуге болады?
Бейне: Atmega1284: 9 қадамдарын қолданатын 1024 үлгісі FFT спектр анализаторы
2024 Автор: John Day | [email protected]. Соңғы өзгертілген: 2024-01-30 10:23
Бұл салыстырмалы түрде оңай оқулық (осы тақырыптың күрделілігін ескере отырып) сізге Arduino типті тақтаны (1284 тар) және сериялық плоттерді қолдана отырып, өте қарапайым 1024 үлгідегі спектр анализаторын қалай жасауға болатынын көрсетеді. Кез келген Arduino үйлесімді тақтасы жасайды, бірақ оның RAM -і неғұрлым көп болса, жиіліктің ең жақсы ажыратымдылығын аласыз. 1024 үлгісі бар FFT есептеу үшін 8 Кбайт -тан астам жедел жады қажет болады.
Спектрлік талдау сигналдың негізгі жиілік компоненттерін анықтау үшін қолданылады. Көптеген дыбыстар (музыкалық аспапта шығарылатын сияқты) негізгі жиіліктің бүтін сан еселі жиілігі бар негізгі гармоникадан тұрады. Спектрлік анализатор сізге барлық спектрлік компоненттерді көрсетеді.
Сіз бұл қондырғыны жиілік есептегіші ретінде қолданғыңыз келуі мүмкін немесе сіздің электронды тізбегіңізде шу шығарады деп күдіктенетін кез келген сигналдарды тексергіңіз келуі мүмкін.
Біз мұнда бағдарламалық қамтамасыз ету бөлігіне тоқталамыз. Егер сіз белгілі бір қосымшаның тұрақты схемасын жасағыңыз келсе, сізге сигналды күшейту және сүзу қажет болады. Бұл алдын ала баптау сіз зерттегіңіз келетін сигналға байланысты, оның амплитудасына, кедергісіне, максималды жиілігіне және т.б.… Сіз https://www.instructables.com/id/Analog-Sensor-Sig… тексере аласыз.
1 -қадам: Кітапхананы орнату
Біз Enrique Condes жазған ArduinoFFT кітапханасын қолданамыз. Біз оперативті жадты мүмкіндігінше үнемдегіміз келетіндіктен, біз іріктелген және есептелген деректерді сақтау үшін өзгермелі деректер түрін (екі еселенгеннің орнына) пайдалануға мүмкіндік беретін осы репозиторийдің даму бөлімін қолданамыз. Сондықтан біз оны қолмен орнатуымыз керек. Уайымдамаңыз, мұрағатты жүктеп алып, оны Arduino кітапхана қалтасынан ашыңыз (мысалы, Windows 10 әдепкі конфигурациясында: C: / Пайдаланушылар _ пайдаланушыңыздың_атауы_ / Құжаттар / Arduino / кітапханалары)
«FFT_01.ino» сияқты берілген мысалдардың бірін құрастыру арқылы кітапхананың дұрыс орнатылғанын тексеруге болады.
2 -қадам: Фурье трансформациясы және ФФТ тұжырымдамалары
Ескерту: егер сіз математикалық белгілерді көре алмасаңыз, 3 -қадамға өтуді қалауыңыз мүмкін. Қалай болғанда да, егер сіз мұның бәрін ала алмасаңыз, бөлімнің соңындағы қорытындыға назар аударыңыз.
Жиілік спектрі Fast Fourier Transform алгоритмі арқылы алынады. FFT - бұл Фурье түрлендіруінің математикалық тұжырымдамасын жақындататын сандық енгізу. Уақыт осінен кейін сигналдың эволюциясын алғаннан кейін, бұл тұжырымдамаға сәйкес оның күрделі (нақты + қиялдық) мәндерден тұратын жиілік аймағындағы көрінісін білуге болады. Тұжырымдама өзара байланысты, сондықтан сіз жиілік доменінің көрінісін білсеңіз, оны уақыт доменіне қайта түрлендіріп, түрлендіру алдындағыдай сигналды қайтаруға болады.
Бірақ уақыттық домендегі осы есептелген күрделі мәндер жиынтығымен не істейміз? Оның көп бөлігі инженерлерге қалады. Біз үшін біз бұл күрделі мәндерді спектрлік тығыздық мәліметтеріне айналдыратын басқа алгоритмді атаймыз: бұл әр жиілік диапазонымен байланысты шаманың (= қарқындылығы) мәні. Жиілік диапазонының саны үлгі санына тең болады.
Сіз, әрине, эквалайзер тұжырымдамасымен таныссыз, мысалы 1980 жылдарға графикалық эквивалентпен. Біз дәл осындай нәтижеге қол жеткіземіз, бірақ 16 емес 1024 диапазонында және одан да жоғары қарқындылықта. Эквалайзер музыканың ғаламдық көрінісін бергенде, жұқа спектрлік талдау 1024 диапазонының әрқайсысының қарқындылығын дәл есептеуге мүмкіндік береді.
Керемет тұжырымдама, бірақ:
- FFT Фурье түрлендіруінің цифрланған нұсқасы болғандықтан, ол цифрлық сигналға жақындайды және кейбір ақпаратты жоғалтады. Қысқаша айтқанда, FFT нәтижесі кері FFT алгоритмімен қайта өзгертілгенде, бастапқы сигнал берілмейді.
- Сондай-ақ, теория шектеусіз сигналды қарастырады, бірақ бұл мәңгілік тұрақты сигнал. Біз оны белгілі бір уақыт ішінде ғана цифрландыратындықтан (мысалы, үлгілер), тағы бірнеше қателер енгізіледі.
- Ақырында аналогты цифрлық түрлендіруге рұқсат ету есептелген мәндердің сапасына әсер етеді.
Тәжірибеде
1) іріктеу жиілігі (fs ескерілген)
Біз сигналды таңдаймыз, яғни оның амплитудасын әр 1/секунд сайын өлшейміз. fs - іріктеу жиілігі. Мысалы, егер біз 8 кГц жиілікте сынақ жүргізетін болсақ, чиптің бортында орналасқан ADC (цифрлық түрлендіргіш) әр 1/8000 секунд сайын өлшеуді қамтамасыз етеді.
2) Үлгілер саны (N немесе кодтағы үлгілер)
Біз FFT -ті іске қоспас бұрын барлық мәндерді алуымыз керек болғандықтан, біз оларды сақтауымыз керек, сондықтан біз үлгілер санын шектейміз. FFT алгоритмі 2 -ге тең болатын көптеген үлгілерді қажет етеді. Бізде неғұрлым көп үлгілер болса, соғұрлым жақсы, бірақ ол көп жадты қажет етеді. Arduino FFT кітапханасы пайдалану арқылы біраз орынды үнемдейді
- Таңдалған деректерді, содан кейін түрлендірілген деректердің нақты бөлігін сақтау үшін «vReal» деп аталатын бір массив
- Түрлендірілген деректердің ойдан шығарылған бөлігін сақтау үшін «vImag» деп аталатын бір массив
ЖЖҚ қажетті көлемі 2 (массивтер) * 32 (бит) * N (үлгілерге) тең.
16 ГБ жедел жады бар Atmega1284 -те біз максимум N = 16000*8/64 = 2000 мәндерін сақтаймыз. Мәндер саны 2 -ге тең болуы керек болғандықтан, біз максимум 1024 мәнді сақтаймыз.
3) жиіліктің ажыратымдылығы
FFT үлгілер саны сияқты жиілік диапазондарының мәндерін есептейді. Бұл диапазондар 0 Гц -тен іріктеу жиілігіне (fs) дейін созылады. Демек, жиіліктің ажыратымдылығы:
Fresolution = fs / N
Ажыратымдылық төмен болған кезде жақсы. Сондықтан жақсы ажыратымдылық (төмен) үшін біз қажет:
- басқа үлгілер және/немесе
- төменгі fs
Бірақ…
4) минималды fs
Біз көптеген жиіліктерді көргіміз келетіндіктен, олардың кейбіреулері «негізгі жиіліктен» әлдеқайда жоғары, біз fs тым төмен қоя алмаймыз. Іс жүзінде бізді іріктеу жиілігі біз тексергіміз келетін максималды жиіліктен екі есе жоғары болуға мәжбүрлейтін Nyquist -Shannon іріктеу теоремасы бар.
Мысалы, егер біз барлық спектрді 0 Гц -тен 15 КГц -ке дейін талдағымыз келсе, бұл шамамен адамдардың көпшілігі еститін ең жоғарғы жиілік болса, біз іріктеу жиілігін 30 КГц -ке қоюымыз керек. Іс жүзінде электрониктер оны 2,5 (немесе тіпті 2,52) * максималды жиілікке қояды. Бұл мысалда бұл 2,5 * 15 КГц = 37,5 КГц болады. Кәсіби аудиода әдеттегі іріктеу жиіліктері - 44,1 КГц (аудио CD жазу), 48 КГц және одан жоғары.
Қорытынды:
1 -ден 4 -ке дейінгі нүктелер мыналарға әкеледі: біз мүмкіндігінше көп үлгіні қолданғымыз келеді. Біздің жағдайда 16 Кбайт жедел жады құрылғысымен біз 1024 үлгіні қарастырамыз. Біз сигналды күткен ең жоғары жиілікті талдауға жеткілікті жоғары болғанша, мүмкіндігінше ең төменгі іріктеу жиілігінде іріктегіміз келеді (бұл жиілік кем дегенде 2,5 *).
3 -қадам: сигналды модельдеу
Алғашқы әрекетті орындау үшін біз кітапханада берілген TFT_01.ino мысалын сәл өзгертеміз, ол сигналды талдау үшін.
- Негізгі жиілік, 440 Гц (музыкалық А)
- 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/sampling ішіндегі таймердің максималды мәніне әсер етеді Жиілік бүтін сан болуы керек
Сигнал 5 -ші гармоникаға ие болғандықтан (бұл гармониканың жиілігі = 5 * 440 = 2200 Гц) бізге таңдау жиілігін 2,5 * 2200 = 5500 Гц -тен жоғары қою керек. Мұнда мен 8000 Гц жиілігін таңдадым.
Біз сондай -ақ шикізат пен есептелген деректерді сақтайтын массивтерді жариялаймыз
float vReal [үлгілер];
float vImag [үлгілер];
2) Жылдамдық
Біз ArduinoFFT нысанын жасаймыз. ArduinoFFT әзірлеуші нұсқасы үлгіні қолданады, сондықтан біз өзгермелі немесе қосарланған деректер түрін қолдана аламыз. Float (32 бит) біздің бағдарламаның жалпы дәлдігіне жеткілікті.
ArduinoFFT FFT = ArduinoFFT (vReal, vImag, үлгілер, іріктеу жиілігі);
3) vReal массивін толтыру арқылы сигналды имитациялау, оны ADC мәндерімен толтырудың орнына.
Циклдың басында біз vReal массивін толтырамыз:
өзгермелі циклдар = (((үлгілер) * signalFrequency) / іріктеу жиілігі); // Таңдау оқылатын сигнал циклдарының саны
for (uint16_t i = 0; i <үлгілер; i ++) {vReal = float ((амплитудасы * (sin ((i * (TWO_PI * циклдары)) / үлгілер))))); / * Оң және теріс мәндер */ vReal += float ((амплитудасы * (sin ((3 * i * (TWO_PI * циклдары))/ үлгілер)))/ 2.0);/ * Оң және теріс мәндері бар деректерді құру */ vReal += float ((амплитудасы * (sin ((5 * i * (TWO_PI * циклдары)) / үлгілер))) / 4.0); / * Оң және теріс мәндері бар деректерді құру * / vImag = 0.0; // Қате есептеулер мен толып кетулерді болдырмау үшін цикл болған жағдайда ойдан шығарылған бөлікті нөлге қою керек}
Біз іргелі толқын мен амплитудасы аз гармониканы цифрландыруды қосамыз. Біз қиялдағы массивті нөлдермен инициализациялаймыз. Бұл массив FFT алгоритмімен толтырылғандықтан, біз оны әрбір жаңа есептеулер алдында қайтадан тазалауымыз керек.
4) FFT есептеуі
Содан кейін біз FFT мен спектрлік тығыздықты есептейміз
FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward);
FFT.compute (FFTDirection:: Forward); / * Compute 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 -қадам: имитациялық сигналды талдау - нәтижелер
Біз күтілгендей f0 шамасының жартысы мен 1/4 бөлігімен 3 -ші және 5 -ші гармониканың негізгі жиілігіне (f0) сәйкес келетін 3 шоқты көреміз. Біз терезенің жоғарғы жағында оқи аламыз f0 = 440.430114 Гц. Бұл мән дәл 440 Гц емес, жоғарыда түсіндірілген барлық себептерге байланысты, бірақ ол нақты мәнге өте жақын. Мынадай ондық бөлшектерді көрсетудің қажеті жоқ еді.
6 -қадам: Нақты сигналды талдау - ADC сымдарын қосу
Біз теорияда қалай әрекет ету керектігін білетіндіктен, біз нақты сигналды талдағымыз келеді.
Сымдар өте қарапайым. Алаңды және сигнал желісін тақтаның A0 түйреуішіне 1 КОм -нан 10 КОм -ге дейінгі тізбекті резистор арқылы қосыңыз.
Бұл сериялы резистор аналогтық кірісті қорғайды және қоңырау шалуды болдырмайды. Ол қоңырау шалуды болдырмау үшін мүмкіндігінше жоғары болуы керек және ADC жылдам зарядтауға жеткілікті ток беру үшін мүмкіндігінше төмен болуы керек. ADC кірісіне қосылған сигналдың күтілетін кедергісін білу үшін MCU деректер кестесін қараңыз.
Бұл демо үшін мен жиілігі 440 Гц пен амплитудасы 5 вольт шамасындағы синусоидальды сигналды беру үшін функция генераторын қолдандым (егер амплитудасы 3 пен 5 вольт аралығында болса, онда ADC толық масштабта қолданылады), 1,2 КОм резистор арқылы.
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) Таймер мен ADC орнату
Біз таймер 1 -ді таңдайтын жиілікте (8 КГц) айналатындай етіп орнатамыз және өнімділікті салыстыруды үземіз.
жарамсыз timer_setup () {
// қалпына келтіру таймері 1 TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; TCCR1B = бит (CS11) | бит (WGM12); // CTC, 8 TIMSK1 = бит (OCIE1B) алдын ала есептегіші; OCR1A = ((16000000 /8) / іріктеу жиілігі) -1; }
ADC -ді осылай орнатыңыз
- Кіріс ретінде A0 пайдаланады
- Әр таймерде автоматты түрде іске қосылады 1 шығыс салыстыру B
- Түрлендіру аяқталған кезде үзіліс жасайды
ADC сағаты жүйелік сағатты (16 МГц) 16 -ға дейін алдын -ала өлшеу арқылы 1 МГц -ге орнатылады, өйткені әрбір конверсия толық масштабта шамамен 13 сағатты алатындықтан, конверсияға 1/13 = 0,076 МГц = 76 КГц жиілікте қол жеткізуге болады. ADC деректерді іріктеуге уақыт беру үшін таңдау жиілігі 76 КГц -тен едәуір төмен болуы керек. (біз fs = 8 кГц таңдадық).
жарамсыз adc_setup () {
ADCSRA = бит (ADEN) | бит (ADIE) | бит (ADIF); // ADC қосу, ADCSRA | = бит (ADPS2) аяқталғаннан кейін үзіліс қажет; // 16 ADMUX = бит (REFS0) алдын ала есептегіші | (adcPin & 7); // ADC кірісін орнату ADCSRB = бит (ADTS0) | бит (ADTS2); // Таймер/Санауыш1 салыстыру Match B триггер көзі ADCSRA | = бит (ADATE); // автоматты түрде қосуды қосу}
Біз vReal массивінде түрлендірілген деректерді сақтау және үзілісті жою үшін әрбір ADC конверсиясынан кейін шақырылатын үзіліс өңдегішін жариялаймыз.
// 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 (); // 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 («Гц»);
Біз тұрақты ток компонентін алып тастаймыз, себебі ADC жерге сілтеме жасайды және сигнал шамамен 2,5 вольт шамасында орталықтандырылған.
Содан кейін біз деректерді алдыңғы мысалда түсіндірілгендей есептейміз.
8 -қадам: нақты сигналды талдау - нәтижелер
Шынында да, біз бұл қарапайым сигналда бір ғана жиілікті көреміз. Есептелген негізгі жиілік - 440.118194 Гц. Мұнда тағы да мән нақты жиіліктің өте жақын жуықтауы болып табылады.
9 -қадам: Қысылған синусоидалы сигнал туралы не деуге болады?
Енді сигналдың амплитудасын 5 вольттен жоғарылату арқылы ADC шамалы шамадан тыс жүргізуге рұқсат етіңіз, сондықтан ол кесіледі. ADC кірісін бұзбау үшін тым қатты басуға болмайды!
Біз кейбір гармоникалардың пайда болғанын көреміз. Сигналды кесу жоғары жиілікті компоненттерді жасайды.
Сіз Arduino тақтасында FFT талдауының негізін көрдіңіз. Енді сіз іріктеу жиілігін, үлгілер санын және терезе параметрін өзгертуге тырысуға болады. Кітапхана FFT жылдамдығын азырақ дәлдікпен есептеу үшін кейбір параметрлерді қосады. Егер сіз іріктеу жиілігін тым төмен орнатсаңыз, спектрлік бүктелуге байланысты есептелген шамалар мүлдем қате болып шығатынын байқайсыз.
Ұсынылған:
DIY FFT аудио спектр анализаторы: 3 қадам
DIY FFT аудио спектр анализаторы: FFT спектр анализаторы - спектрлік талдауды қамтамасыз ету үшін Фурье анализі мен цифрлық сигналды өңдеу әдістерін қолданатын сынақ жабдығы. Фурье анализін қолдана отырып, мысалы, үздіксіз уақыт аймағындағы бір мәнді түрлендіруге болады
Би фонтаны: MSGEQ7 спектр анализаторы бар Arduino: 8 қадам
Би фонтаны: Arduino MSGEQ7 спектр анализаторымен: Дыбыстық сигналды қабылдау және оны визуалды немесе механикалық реакцияға айналдыру өте қызықты. Бұл жобада біз Arduino Mega -ді MSGEQ7 спектрлік анализаторына қосылу үшін қолданамыз, ол кіріс дыбыстық сигналды қабылдайды және диапазонды орындайды
Raspberry Pi 3 үлгісі B үлгісі: 5 қадам
Таңқурай Pi 3 корпусы B үлгісі: тазартады
Аудио спектр анализаторы (VU метр): 6 қадам
Аудио спектр анализаторы (VU Meter): Музыка дегеніміз не? Техникалық тұрғыдан алғанда, музыка - бұл кернеуі мен жиілігі әр түрлі сигнал. Аудио спектр анализаторы - белгілі бір жиіліктегі кернеу деңгейін көрсететін құрылғы. Бұл негізінен басқа жерлерде қолданылатын құрал
Тікелей нысанды анықтауды қолданатын трафик үлгісі анализаторы: 11 қадам (суреттермен)
Тікелей нысанды анықтауды қолданатын трафик үлгісі анализаторы: Қазіргі әлемде бағдаршам қауіпсіз жол үшін өте қажет. Алайда, көп жағдайда бағдаршам біреу қызылға айналған кезде жарыққа жақындағанда тітіркендіреді. Бұл уақытты жоғалтады, әсіресе жарық шамы шамалы болса