Мазмұны:

EasyFFT: Arduino үшін Fast Fourier Transform (FFT): 6 қадам
EasyFFT: Arduino үшін Fast Fourier Transform (FFT): 6 қадам

Бейне: EasyFFT: Arduino үшін Fast Fourier Transform (FFT): 6 қадам

Бейне: EasyFFT: Arduino үшін Fast Fourier Transform (FFT): 6 қадам
Бейне: FFT Vibration using a PicoW via mpu6050 2024, Қыркүйек
Anonim
Image
Image

Түсірілген сигналдан жиілікті өлшеу қиын жұмыс болуы мүмкін, әсіресе Ардуинода, өйткені оның есептеу қуаты төмен. Нөлдік қиылысты алудың әдістері бар, онда жиілік сигнал берілген уақыт ішінде нөлдік сызықтан қанша рет өтетінін тексеру арқылы түсіріледі. Сигнал әр түрлі жиіліктердің тіркесімі болған кезде мұндай әдіс жұмыс істемеуі мүмкін.

Егер сіз осындай фоннан болмасаңыз, кодтау қиын. Бірақ бұл код музыкаға, сигналды талдауға қатысты әр түрлі жобалар үшін өте пайдалы болуы мүмкін. Бұл жобаның мотиві - бұл Arduino -да фонға енбестен оңай енгізілетін код дайындау.

Бұл жоба FFT жұмысын түсіндірмейді, бірақ FFT функциясының қолданылуын түсіндіреді. Дәл сол процесс бейнеде көрсетілген.

Егер сіз кодты түсіндіруге емес, оны қолдануға қызығушылық танытсаңыз. 3 -қадамға тікелей өтуге болады.

1 -қадам: Жиілік түрлендіруге кіріспе

Жиілік түрлендіруге кіріспе
Жиілік түрлендіруге кіріспе
Жиілік түрлендіруге кіріспе
Жиілік түрлендіруге кіріспе

Кез келген сигнал әр түрлі синусоидальды толқындардың комбинациясынан тұруы мүмкін. Уақытқа негізделген кез келген сигналды әр түрлі амплитуда синусының қосындысы ретінде көрсетуге болады.

Мен DFT (дискретті Фурье түрлендіруі) жұмысын алдыңғы нұсқаулықтардың бірінде түсіндіруге тырыстым (https://www.instructables.com/id/Arduino-Frequency…). Бұл әдістер кез келген нақты уақыт режимінде өте баяу. бұл оны іс жүзінде пайдасыз етеді.

Суретте f2 және f5 жиіліктерінің қосындысы болып табылатын сигнал көрсетілген. Бұл сигнал f1 - f5 мәндерінің сынақ синус толқындарына көбейтіледі.

Математикалық түрде көрсетуге болады -жиілігі әр түрлі екі гармониялық деректер жиынтығының көбейтілуі нөлге тең (деректер санының көп болуы соққыға әкелуі мүмкін). Біздің жағдайда, егер бұл екі көбейту жиілігі бірдей (немесе өте жақын) жиілікке ие болса, онда көбейтудің қосындысы нөлдік емес сан болып табылады.

Егер біздің сигнал f1 -ге көбейтілсе, көбейтудің қосындысы нөлге тең болады (нақты қолдану үшін нөлге жақын). f3, f4 үшін ұқсас жағдай. Дегенмен, f2 және f5 шығысы нөлге тең болмайды, бірақ қалған мәндерге қарағанда айтарлықтай жоғары.

Мұнда сигнал 5 жиілікте тексеріледі, сондықтан сигналды бес жиілікке көбейту қажет. Мұндай қарқынды есептеу көп уақытты алады. Үлгілердің N саны үшін N*N комплексті көбейту қажет болатыны математикалық түрде көрсетілген.

2 -қадам: Фурье жылдам трансформациясы

DFT есептеуді тездету үшін FFT алгоритмін Джеймс Кули мен Джон Туки жасаған. Бұл алгоритм 20 ғасырдың ең маңызды алгоритмдерінің бірі болып саналады. Ол сигналды тақ және жұпталған бөлікке бөледі, бұл бірқатар қажетті есептеулерді төмендетеді. Оны қолдану арқылы жалпы қажет күрделі көбейтуді NlogN дейін азайтуға болады. бұл айтарлықтай жақсарту.

Сіз FFT математикасын егжей -тегжейлі түсіну үшін кодты жазу кезінде сілтеме жасаған сілтемелерге сілтеме жасай аласыз:

1.

2.

3.

4.

3 -қадам: кодты түсіндіру

1. Жылдам синус және косинус:

FFT есептеуі әр түрлі синус пен косинустың мәнін бірнеше рет қабылдайды. Arduino кіріктірілген функциясы жеткілікті жылдам емес және қажетті мәнді қамтамасыз ету үшін көп уақыт қажет. Бұл кодты айтарлықтай баяулатады (64 үлгі үшін уақытты екі есе арттырады). Бұл мәселені шешу үшін синустың 0 -ден 90 градусқа дейінгі мәні 255 еселігі ретінде сақталады. Бұл сандарды флоат ретінде қолдану қажеттілігін жояды және біз оны Arduino -да 1/4 орын алатын байт ретінде сақтай аламыз. Sine_data оны жаһандық айнымалы деп жариялау үшін кодтың жоғарғы жағына қою керек.

Sine_data -дан басқа, f_peaks деп аталатын массив жаһандық айнымалы ретінде жарияланды. FFT функциясының әр жұмысынан кейін бұл массив жаңартылады. Мұндағы f_peaks [0] - ең басым жиілік және одан әрі мәндер кему ретімен.

байт sine_data [91] = {0, 4, 9, 13, 18, 22, 27, 31, 35, 40, 44, 49, 53, 57, 62, 66, 70, 75, 79, 83, 87, 91, 96, 100, 104, 108, 112, 116, 120, 124, 127, 131, 135, 139, 143, 146, 150, 153, 157, 160, 164, 167, 171, 174, 177, 180, 183, 186, 189, 192, 195, 198, 201, 204, 206, 209, 211, 214, 216, 219, 221, 223, 225, 227, 229, 231, 233, 235, 236, 238, 240, 241, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 253, 254, 254, 254, 255, 255, 255, 255}; float f_peaks [5];

Бізде синустың мәні 0 -ден 90 градусқа дейін сақталғандықтан, синустың немесе косинустың кез келген мәнін есептеуге болады. Төменде санның бірінші айналымы нөлдік ондық нүктеге дейін және сақталған деректердің мәнін қайтарады. бұл әдіс тек бір өзгермелі бөлуді қажет етеді. Бұл синустық мәндерді (255 еселік емес) тікелей сақтау арқылы одан әрі азайтылуы мүмкін. бірақ бұл Arduino жадысын жояды.

Жоғарыда көрсетілген процедураны қолдану дәлдікті төмендетеді, бірақ жылдамдықты жақсартады. 64 ұпай үшін ол 8 мс, 128 ұпай үшін 20 мс артықшылық береді.

4 -қадам: Кодты түсіндіру: FFT функциясы

FFT тек 2, 4, 8, 16, 32, 64 және т.б. үлгі өлшемдері үшін орындалады. егер мән 2^n болмаса, онда ол мәннің төменгі жағын алады. Мысалы, егер біз 70 өлшемді таңдайтын болсақ, онда ол тек алғашқы 64 үлгіні қарастырады және қалғанын алып тастайды.

Үлгі өлшемі 2^n болуы әрқашан ұсынылады. болуы мүмкін:

2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048, …

Out_r және out_im екі өзгермелі жады үлкен көлемді алады. Arduino нано 128 -ден жоғары үлгілерде жұмыс істемейді (кейбір жағдайларда 128), жадтың жетіспеушілігіне байланысты.

қол қойылмаған int деректері [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

int a, c1, f, o, x; a = N; for (int i = 0; i <12; i ++) // деңгейлерді есептеу {if (data <= a) {o = i;}} int in_ps [data [o] = {}; // реттеуге арналған енгізу float out_r [data [o] = {}; // трансформацияның нақты бөлігі float out_im [data [o] = {}; // трансформацияның қиялдық бөлігі

Әрі қарай ағын келесідей:

1. Код берілген үлгі өлшемі үшін сәл кері тәртіпті жасайды (сілтемелер бойынша биттерді кері қайтару туралы мәліметтер: 2 -қадам)

2. Жасалған тапсырысқа сәйкес реттелген кіріс деректері, 3. FFT орындалды

4. Комплекс санының амплитудасы есептеледі, 5. Шыңдар кему ретімен анықталады және реттеледі

6. нәтижелерге f_peaks арқылы қол жеткізуге болады.

[басқа деректерге қол жеткізу үшін (ең жоғары жиіліктен басқа) кодты өзгерту керек, осылайша жергілікті айнымалы мәнді алдын ала анықталған кейбір ғаламдық айнымалыға көшіру мүмкін болады)

5 -қадам: кодты тексеру

Кодты тексеру
Кодты тексеру
Кодты тексеру
Кодты тексеру

Үшбұрыш толқынының үлгісі кіріс ретінде беріледі. бұл үшін толқындарды іріктеу жиілігі 10 Гц және толқынның өзі 1,25 Гц.

Шикі өнімнен көрініп тұрғандай, мән Scilab есептеген FFT сәйкес келеді. алайда бұл мәндер дәлдігі төмен, бірақ синусоиданың жылдамдығымен бірдей емес.

Шығу жиілігінде жиілік жиілігі 1,25 және 3,75. әр уақытта нақты мәнді алу қажет емес. Әдетте бұл сандар жиіліктер деп аталады. сондықтан шығыс мәні белгіленген қоқыс жәшіктерінің кез келген жерінде болуы мүмкін.

Жылдамдық:

Arduino нано үшін қажет:

16 ұпай: 4ms32 ұпай: 10ms 64 ұпай: 26ms 128 ұпай: 53ms

6 -қадам: Қорытынды

Бұл FFT кодын нақты уақыттағы қосымшаларда қолдануға болады. Есептеуді аяқтау үшін шамамен 30 мс қажет. Алайда, оның шешімі бірқатар үлгілермен шектелген. Үлгі саны Arduino жадымен шектеледі. Arduino Mega немесе басқа жоғары өнімділік тақтасының көмегімен дәлдікті жақсартуға болады.

егер сізде сұрақтар, ұсыныстар немесе түзетулер болса, түсініктеме беруден тартынбаңыз.

Жаңарту (05.02.21)

Жаңартулар: // ---------------------------- FFT функциясы --------------- ------------------------------- // float FFT (int [in, int N, float Frequency)

Деректер түрі N 255 үлгі өлшемін қолдау үшін Integer (қолданыстағы байт) болып өзгертілді. Егер үлгі өлшемі <= 128 болса, байт деректер түрі қолданылуы керек.

Ұсынылған: