في هذه المقالة ،
سأستمر في تجسيد إلهامي في العمل المختبري رقم 3 الموجود بالفعل في الغدة. نحن نتحدث عن اكتشاف رقم عن طريق الصوت في وضع الاتصال بالألوان على Arduino باستخدام خوارزمية Goertzel.
لتنفيذ ذلك ، استخدمت Arduino UNO ، وميكروفون
electret (
adafruit ) وشاشة 8 × 8 مع برنامج التشغيل MAX7219.
خطة العمل
- تخليص عدد كاف من العينات (باستخدام البرنامج من المادة السابقة كنت مقتنعا أن 256 بما فيه الكفاية).
- ابحث عن سعة استجابة التردد المقابلة للترددات المرغوبة التي تشفر الحروف.
- ستعطي قيمتا الحد الأقصى للسعة مؤشرات للصف والعمود للحرف المرغوبة ، على سبيل المثال ، يبدو الشكل 3.

التنفيذ
قبل الشروع في التنفيذ ، نجيب على السؤال - هل سيكون لدى Arduino UNO أداء كاف لنا؟
تردد الساعة: 16 ميجا هرتز
تستغرق دورة أخذ العينات 13 دورة على مدار الساعة
قيمة Prescaler توفير أكبر قدر من الدقة: 128
اتضح 16 ميغاهيرتز / 13/128 ~ 9615 هرتز - تردد أخذ العينات المطلوب ، مما يعني أنه يمكنك العمل مع ترددات تصل إلى 4.8 كيلو هرتز.
ضبط ADC
هناك العديد من أوضاع تشغيل ADC ، والأكثر إثارة للاهتمام هي المذكورة أدناه (قائمة كاملة في
ورقة البيانات للكلمة الرئيسية ADCSRB)
- قراءة واحدة - باستخدام طريقة analogRead () ، ولكن هذه مكالمة حظر تتطلب 100 ثانية ، واستخدامها يستحيل توفير معدل ثابت لأخذ العينات
- وضع التشغيل الحر - في هذا الوضع ، تبدأ دورة أخذ العينات التالية مباشرة بعد نهاية الدورة السابقة ويتم توفير الحد الأقصى لتردد أخذ العينات
- تجاوز الموقت - تبدأ عملية أخذ العينات بتجاوز سعة الموقت ، مما يتيح لك ضبط وتيرة أخذ العينات
رمز إعداد ADC ، من أجل البساطة استخدمت وضع التشغيل المجاني.
ADMUX = 0;
معالجة الإشارات
بمجرد كتابة المجموعة الكاملة من العينات ، نقوم بإيقاف المقاطعة بواسطة ADC ونحسب سعة الطيف باستخدام خوارزمية Goertzel. لن أتنافس في وصف الخوارزمية مع هذا
المورد الشامل ، لكنني سأقدم عملي:
void goertzel(uint8_t *samples, float *spectrum) { float v_0, v_1, v_2; float re, im, amp; for (uint8_t k = 0; k < IX_LEN; k++) { float cos = pgm_read_float(&(cos_t[k])); float sin = pgm_read_float(&(sin_t[k])); float a = 2. * cos; v_0 = v_1 = v_2 = 0; for (uint16_t i = 0; i < N; i++) { v_0 = v_1; v_1 = v_2; v_2 = (float)(samples[i]) + a * v_1 - v_0; } re = cos * v_2 - v_1; im = sin * v_2; amp = sqrt(re * re + im * im); spectrum[k] = amp; } }
تم حساب الجيوب وجيب التمام مسبقًا للعينات المقابلة للترددات المطلوبة. النسخة الكاملة من الكود
هنا .
الاستنتاجات
الأهم من ذلك ، اتضح أن موارد Arduino UNO كافية لمعالجة الصوت البسيطة.
الدرس الرئيسي الذي تعلمته أن ADC شيء حساس ، بعد التعرف على الشخصية وإرسالها بنجاح إلى وحدة التحكم ، قضيت أسبوعًا في تصحيحه للعمل مع الشاشة ، لأنني قمت بتوصيل الأرض بالميكروفون و max7219 وتحولت جميع العينات إلى ضوضاء على الفور.
يمكن أن يكون أفضل؟ نعم ، سيكون من الأصح اختيار تردد أخذ العينات وعدد العينات بحيث تتزامن الترددات المطلوبة مع شعرية أخذ العينات ، وهذا سيمنع انتشار الطيف. هذه المعلمات هي بالفعل f = 8 كيلو هرتز ، N = 205 ، وفي هذه الحالة تحتاج إلى تشغيل ADC ليس في وضع التشغيل المجاني ، ولكن تجاوز سعة المؤقت ، وسيكون الفرق واضحًا.

تقترب
الدورة من نهايتها ، ولكن لا تزال هناك العديد من الأفكار.
شكرا لاهتمامكم