جدول المحتويات:
- الخطوة 1: مقدمة في تحويل التردد
- الخطوة الثانية: تحويل فورييه السريع
- الخطوة الثالثة: شرح الكود
- الخطوة 4: شرح الكود: وظيفة FFT
- الخطوة الخامسة: اختبار الكود
- الخطوة السادسة: الخاتمة
فيديو: EasyFFT: تحويل فورييه السريع (FFT) لأردوينو: 6 خطوات
2024 مؤلف: John Day | [email protected]. آخر تعديل: 2024-01-30 07:36
يمكن أن يكون قياس التردد من الإشارة الملتقطة مهمة صعبة ، خاصة على Arduino حيث أن لديها طاقة حسابية أقل. هناك طرق متاحة لالتقاط عبور الصفر حيث يتم التقاط التردد عن طريق التحقق من عدد المرات التي تعبر فيها الإشارة خطوط الصفر خلال الوقت المحدد. قد لا تعمل مثل هذه الطريقة عندما تكون الإشارة عبارة عن مجموعة من الترددات المختلفة.
هذا أمر صعب إلى حد ما إذا لم تكن من هذه الخلفية. ولكن كونه أداة ترقيع ، قد يكون هذا الرمز مفيدًا للغاية للعديد من المشاريع المتعلقة بالموسيقى وتحليل الإشارة. كان الدافع من هذا المشروع هو إعداد رمز يسهل تنفيذه على 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 الضرب المعقد.
الخطوة الثانية: تحويل فورييه السريع
لجعل حساب DFT أسرع ، تم تطوير خوارزمية FFT بواسطة James Cooley و John Tukey. تعتبر هذه الخوارزمية أيضًا واحدة من أهم الخوارزميات في القرن العشرين. يقسم الإشارة إلى جزء فردي وزوجي متسلسل مما يجعل عدد الحسابات المطلوبة أقل. باستخدامه يمكن تقليل إجمالي الضرب المعقد المطلوب إلى NlogN. وهو تحسن كبير.
يمكنك الرجوع أدناه إلى المراجع التي أشرت إليها أثناء كتابة الكود للحصول على فهم مفصل للرياضيات وراء FFT:
1.
2.
3.
4.
الخطوة الثالثة: شرح الكود
1. سرعة الجيب وجيب التمام:
يأخذ حساب FFT قيمة مختلف الجيب وجيب التمام عدة مرات. وظيفة Arduino المدمجة ليست سريعة بما يكفي وتستغرق وقتًا طويلاً لتوفير القيمة المطلوبة. مما يجعل الكود أبطأ بشكل ملحوظ (يضاعف الوقت لـ 64 عينة). لمواجهة هذه المشكلة ، يتم تخزين قيمة الجيب لـ 0 إلى 90 درجة كمضاعفات 255. سيؤدي القيام بذلك إلى التخلص من الحاجة إلى استخدام تخزين الأرقام كعائمة ويمكننا تخزينها على أنها بايت والتي تأخذ 1/4 مساحة على Arduino. يحتاج 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} ؛ تعويم 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 nano لن يعمل مع عينات أعلى من 128 (وفي بعض الحالات 128) بسبب نقص الذاكرة المتاحة.
بيانات int غير موقعة [13] = {1، 2، 4، 8، 16، 32، 64، 128، 256، 512، 1024، 2048} ؛
int a ، c1 ، f ، o ، x ؛ أ = ن ؛ لـ (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.
[للوصول إلى البيانات الأخرى (بصرف النظر عن تردد الذروة) يجب تعديل الشفرة ، بحيث يمكن نسخ المتغير المحلي إلى متغير عالمي محدد مسبقًا]
الخطوة الخامسة: اختبار الكود
يتم إعطاء عينة من موجة المثلث كمدخلات. لأن تردد أخذ العينات من الموجة هو 10 هرتز وتردد الموجة نفسها هو 1.25 هرتز.
كما يتضح من الناتج الخام ، تتطابق القيمة مع FFT المحسوبة بواسطة Scilab. ومع ذلك ، فإن هذه القيم ليست بالضبط نفس الدقة المنخفضة ولكن موجة جيبية أسرع.
في تردد مجموعة تردد الخرج هي 1.25 و 3.75. ليس من الضروري الحصول على القيمة الدقيقة في كل مرة. عادةً ما تسمى هذه الأرقام صناديق التردد. لذلك قد تكون قيمة الإخراج في أي مكان داخل الحاويات المحددة.
سرعة:
بالنسبة إلى Arduino nano ، يستغرق الأمر:
16 نقطة: 4 مللي ثانية 32 نقطة: 10 مللي ثانية 64 نقطة: 26 مللي ثانية 128 نقطة: 53 مللي ثانية
الخطوة السادسة: الخاتمة
يمكن استخدام رمز FFT هذا في تطبيقات الوقت الفعلي. حيث يستغرق إكمال الحساب حوالي 30 مللي ثانية. ومع ذلك ، فإن قراره محدود بعدد من العينات. عدد العينة محدود بذاكرة Arduino. باستخدام Arduino Mega أو لوحة أداء أعلى يمكن تحسينها.
إذا كان لديك أي استفسارات أو اقتراحات أو تصحيحات فلا تتردد في التعليق.
تحديث (2/5/21)
التحديثات: // ----------------------------- دالة FFT --------------- ------------------------------- // float FFT (int in ، int N، float Frequency)
تم تغيير نوع بيانات N إلى عدد صحيح (بايت موجود) لدعم> 255 حجم عينة. إذا كان حجم العينة <= 128 ، فيجب استخدام نوع بيانات البايت.
موصى به:
اصنع أدواتك الخاصة بسهولة - عداد BPM السريع: 6 خطوات
اصنع أدواتك الخاصة بسهولة - عداد BPM السريع: تطبيقات الويب هي مكان شائع ، لكن تطبيقات الويب التي لا تتطلب الوصول إلى الإنترنت ليست كذلك. في هذه المقالة ، أوضح لك كيف صنعت عداد BPM في صفحة HTML بسيطة مقترنة بجافا سكريبت الفانيليا ( انظر هنا). في حالة التنزيل ، يمكن استخدام هذه الأداة في وضع عدم الاتصال
إضافة ميزة الشحن السريع إلى Powerbank: 5 خطوات (بالصور)
إضافة ميزة الشحن السريع إلى Powerbank: سأوضح لك في هذا المشروع كيف قمت بتعديل powerbank مشترك من أجل تقليل وقت الشحن الطويل للغاية. على طول الطريق سأتحدث عن دائرة powerbank ولماذا تعتبر حزمة بطارية powerbank الخاصة بي مميزة بعض الشيء. هيا بنا
هل حصلت على Neopixel جديد؟ هنا دليل البدء السريع!: 5 خطوات
هل حصلت على Neopixel جديد؟ هنا هو دليل البدء السريع!: أعلم أنه في آخر تعليمات لي قلت إنني سأكون منتظمًا ، لكنني لم أفعل. حسنًا ، لقد حاولت بالفعل ، لكن لم يكن لدي أي أفكار جيدة: مباراة مغطاة بالشمع: KABOOM! * شمعة تلوين: Fissssssss … KABOOOM! ** فن رياضيات خيالي: فهمت الزوايا بشكل خاطئ! على أي حال لقد عدت
الدليل السريع لعمل فيديو باستخدام iPhone الخاص بك وتحميله على Facebook أو YouTube: 9 خطوات
الدليل السريع لعمل فيديو باستخدام IPhone الخاص بك وتحميله على Facebook أو YouTube: استخدم هذه العملية البسيطة المكونة من 5 خطوات (تجعل التعليمات تبدو وكأنها خطوات أكثر مما هي عليه في الواقع) لإنشاء وتحميل أول فيديو على YouTube أو Facebook - باستخدام فقط iPhone الخاص بك
إنذار الباب السريع لملعب الدائرة: 5 خطوات
إنذار الباب السريع لملعب الدائرة: هل تساءلت يومًا ما إذا كان أفراد العائلة يبحثون في غرفتك أثناء عدم وجودك؟ هل تريد إخافتهم؟ إذا كنت مثلي ، فأنت بحاجة إلى إنذار الباب السريع في Circuit Playground. لقد أنشأت منبه الباب الخاص بي لأنني دائمًا ما أتحلى بالفضول