Mundarija:

EasyFFT: Arduino uchun Fast Fourier Transform (FFT): 6 qadam
EasyFFT: Arduino uchun Fast Fourier Transform (FFT): 6 qadam

Video: EasyFFT: Arduino uchun Fast Fourier Transform (FFT): 6 qadam

Video: EasyFFT: Arduino uchun Fast Fourier Transform (FFT): 6 qadam
Video: QuickFFT: High Speed FFT for Arduino 2024, Iyun
Anonim
Image
Image

Qabul qilingan signaldan chastotani o'lchash qiyin ish bo'lishi mumkin, ayniqsa Arduino -da, chunki u hisoblash quvvati past. Nolinchi o'tishni qo'lga kiritish usullari mavjud, bu erda chastota aniqlangan vaqt ichida nol chiziqni necha marta kesib o'tganligi tekshiriladi. Agar signal har xil chastotalarning kombinatsiyasi bo'lsa, bunday usul ishlamasligi mumkin.

Agar siz bunday fondan bo'lmasangiz, kodlash qiyin. Biroq, bu kod musiqa, signallarni tahlil qilish bilan bog'liq turli loyihalar uchun juda foydali bo'lishi mumkin. Loyihaning maqsadi Arduino -ning foniga kirmasdan amalga oshirish oson bo'lgan kodni tayyorlash edi.

Bu loyiha FFT ishini tushuntirmaydi, balki FFT funktsiyasining qo'llanilishini tushuntiradi. Xuddi shu jarayon videoda tasvirlangan.

Agar siz kodni tushuntirish bilan emas, balki faqat uning qo'llanilishi bilan qiziqsangiz. Siz to'g'ridan -to'g'ri 3 -bosqichga o'tishingiz mumkin.

1 -qadam: Chastotani o'zgartirishga kirish

Chastotani o'zgartirishga kirish
Chastotani o'zgartirishga kirish
Chastotani o'zgartirishga kirish
Chastotani o'zgartirishga kirish

Har qanday signal turli xil sinusoidal to'lqinlarning kombinatsiyasidan tuzilishi mumkin. Shunday qilib, vaqtga asoslangan har qanday signalni har xil amplitudali sinuslarning kombinatsiyasi sifatida ko'rsatish mumkin.

Men DFT (diskret Fourier konvertatsiyasi) ishini oldingi ko'rsatmali (https://www.instructables.com/id/Arduino-Frequency…) birida tushuntirishga harakat qildim. Bu usullar har qanday real vaqt rejimida juda sekin. bu uni deyarli foydasiz qiladi.

Rasmda ikkita chastota f2 va f5 kombinatsiyasidan iborat signal ko'rsatiladi. Bu signal f1 dan f5 gacha bo'lgan sinus sinus to'lqinlari bilan ko'paytiriladi.

Matematik tarzda ko'rsatish mumkinki, har xil chastotali ikkita harmonik ma'lumotlar to'plamining ko'payishi nolga teng bo'ladi (ma'lumotlar sonining ko'payishi natijaga olib kelishi mumkin). Bizning holatimizda, agar bu ikkita ko'paytirish chastotasi bir xil (yoki juda yaqin) chastotaga ega bo'lsa, ko'paytmaning yig'indisi nol bo'lmagan raqamdir.

Agar bizning signalimiz f1 ga ko'paytirilsa, ko'paytmaning yig'indisi nolga teng bo'ladi (haqiqiy dastur uchun nolga yaqin). f3, f4 uchun ham xuddi shunday. Biroq, qiymat uchun f2 va f5 chiqishi nolga teng bo'lmaydi, lekin qolgan qiymatlarga qaraganda ancha yuqori.

Bu erda signal 5 chastotali sinovdan o'tkaziladi, shuning uchun signalni beshta chastotaga ko'paytirish kerak. Bunday qizg'in hisoblash ko'proq vaqtni oladi. N ta namunalar soni uchun N*N kompleksli ko'paytirish kerakligi matematik tarzda ko'rsatilgan.

2 -qadam: Furye tez o'zgarishi

DFTni tezroq hisoblash uchun FFT algoritmi Jeyms Kuli va Jon Tuki tomonidan ishlab chiqilgan. Bu algoritm 20 -asrning eng muhim algoritmlaridan biri hisoblanadi. U signalni g'alati va hatto ketma -ket qismga ajratadi, bu esa bir qancha kerakli hisoblarni kamaytiradi. Uning yordamida umumiy talab qilinadigan murakkab ko'paytirishni NlogN ga kamaytirish mumkin. bu sezilarli yaxshilanishdir.

Siz kodni yozishda FFT matematikasini batafsil tushunish uchun men aytgan manbalarga murojaat qilishingiz mumkin:

1.

2.

3.

4.

3 -qadam: Kodni tushuntirish

1. Tez sinus va kosinus:

FFT hisobi turli sinus va kosinus qiymatlarini bir necha marta oladi. Arduino -ning o'rnatilgan funktsiyasi etarlicha tez emas va kerakli qiymatni ta'minlash uchun ko'p vaqt talab etiladi. Bu kodni ancha sekinlashtiradi (64 ta namuna uchun vaqtni ikki baravar oshiradi). Sinusning 0 dan 90 gradusgacha bo'lgan qiymatiga qarshi kurashish uchun 255 ga ko'paytiriladi. Shunday qilib, raqamlarni float sifatida ishlatish zarurati yo'q qilinadi va biz uni Arduino -da 1/4 o'rinni egallaydigan bayt sifatida saqlashimiz mumkin. Sine_data kodini global o'zgaruvchi deb e'lon qilish uchun uni joylashtirish kerak.

Sine_data -dan tashqari, f_peaks deb nomlangan massiv global o'zgaruvchi sifatida e'lon qilingan. Har bir FFT funktsiyasidan keyin bu qator yangilanadi. Bu erda f_peaks [0] - eng ustun chastota va boshqa qiymatlar kamayish tartibida.

bayt 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];

Sinus qiymatini 0 dan 90 darajagacha saqlaganimiz uchun, sinus yoki kosinusning har qanday qiymatini hisoblash mumkin. Quyida raqamning birinchi turini nol kasr nuqtasi va saqlangan ma'lumotlardan qiymat qaytarish funktsiyasi bajariladi. bu usulga faqat bitta suzuvchi bo'linish kerak. Buni sinus qiymatlarini to'g'ridan -to'g'ri saqlash orqali kamaytirish mumkin (255 ko'p emas). lekin bu Arduino -da yuqori xotirani yutadi.

Yuqoridagi protseduradan foydalanish aniqlikni pasaytiradi, lekin tezlikni oshiradi. 64 ball uchun u 8ms va 128 ball uchun 20ms afzallik beradi.

4 -qadam: Kodni tushuntirish: FFT funktsiyasi

FFT faqat 2, 4, 8, 16, 32, 64 va boshqalar namunaviy o'lchamlari uchun bajarilishi mumkin. agar qiymat 2^n bo'lmasa, u qiymatning pastki qismini oladi. Misol uchun, agar biz namuna 70 ni tanlasak, u faqat birinchi 64 ta namunani ko'rib chiqadi va qolganini qoldirmaydi.

Namuna o'lchami har doim 2^n bo'lishi tavsiya etiladi. qaysi bo'lishi mumkin:

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

Out_r va out_im ikkita suzish xotirasi katta hajmga ega bo'ladi. xotira yo'qligi sababli Arduino nano 128 (va ba'zi hollarda 128) dan yuqori namunalarda ishlamaydi.

imzosiz int ma'lumotlari [13] = {1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048};

int a, c1, f, o, x; a = N; uchun (int i = 0; i <12; i ++) // darajalarni hisoblash {if (ma'lumotlar <= a) {o = i;}} int in_ps [ma'lumotlar [o] = {}; // ketma -ketlikni kiritish uchun kiritish float out_r [data [o] = {}; // transformatsiyaning haqiqiy qismi float out_im [data [o] = {}; // o'zgarishning tasavvur qismi

Keyingi oqim quyidagicha:

1. Kod berilgan namunaviy o'lcham uchun bir oz teskari tartibni hosil qiladi (ma'lumotnomalarda bitni teskari o'zgartirish haqida batafsil: 2 -qadam)

2. Yaratilgan buyurtma bo'yicha buyurtma ma'lumotlarini kiritish, 3. FFT bajarildi

4. Kompleks sonning hisoblangan amplitudasi, 5. Cho'qqilar aniqlanadi va kamayish tartibida tartiblanadi

6. natijalarga f_peaks dan kirish mumkin.

[boshqa ma'lumotlarga kirish uchun (maksimal chastotadan tashqari) kodni o'zgartirish kerak, shunda mahalliy o'zgaruvchini oldindan belgilangan global o'zgaruvchiga ko'chirish mumkin bo'ladi)

5 -qadam: Kodni sinab ko'rish

Kodni sinab ko'rish
Kodni sinab ko'rish
Kodni sinab ko'rish
Kodni sinab ko'rish

Uchburchak to'lqin namunasi kirish sifatida berilgan. bu to'lqinni tanlash chastotasi 10 Gts va to'lqinning o'zi 1,25 Gts.

Xom ashyodan ko'rinib turibdiki, qiymat Scilab tomonidan hisoblangan FFT bilan mos keladi. ammo, bu qiymatlar aniqligi past, lekin sinus to'lqinining tezligi bilan bir xil emas.

Chiqish chastotasida qator chastotasi 1,25 va 3,75. har safar aniq qiymatni olish shart emas. Odatda bu raqamlar chastota qutilari deb ataladi. shuning uchun chiqish qiymati belgilangan qutilar ichida bo'lishi mumkin.

Tezlik:

Arduino nano uchun quyidagilar kerak:

16 ball: 4ms32 ball: 10ms 64 ball: 26ms 128 ball: 53ms

6 -qadam: Xulosa

Bu FFT kodi real vaqtda ilovalarda ishlatilishi mumkin. Hisoblashni yakunlash uchun taxminan 30 ms kerak bo'ladi. Biroq, uning o'lchamlari bir qator namunalar bilan cheklangan. Namuna soni Arduino xotirasi bilan cheklangan. Arduino Mega yoki boshqa yuqori ko'rsatkichli platalar yordamida aniqlikni yaxshilash mumkin.

agar sizda biron bir so'rov, taklif yoki tuzatish bo'lsa, sharh qoldiring.

Yangilash (5.02.21)

Yangilanishlar: // ---------------------------- FFT funktsiyasi --------------- ------------------------------- // float FFT (int

Ma'lumotlar turi 255 ta namuna hajmini qo'llab -quvvatlash uchun Integer (mavjud bayt) ga o'zgartirildi. Agar namuna hajmi <= 128 bo'lsa, baytli ma'lumotlar turidan foydalanish kerak.

Tavsiya: