תוכן עניינים:
- שלב 1: התקנת הספרייה
- שלב 2: קונספט טרנספורמציה של פורייה ו- FFT
- שלב 3: הדמיית אות
- שלב 4: ניתוח אות מדומה - קידוד
- שלב 5: ניתוח אות מדומה - תוצאות
- שלב 6: ניתוח אות אמיתי - חיווט ה- ADC
- שלב 7: ניתוח אות אמיתי - קידוד
- שלב 8: ניתוח אות אמיתי - תוצאות
- שלב 9: מה לגבי אות סינוסואידי קצוץ?
וִידֵאוֹ: 1024 דוגמאות מנתח ספקטרום FFT באמצעות Atmega1284: 9 שלבים
2024 מְחַבֵּר: John Day | [email protected]. שונה לאחרונה: 2024-01-30 09:13
הדרכה קלה יחסית (בהתחשב במורכבות של נושא זה) תראה לך כיצד תוכל להכין מנתח ספקטרום פשוט של דוגמאות 1024 באמצעות לוח מסוג Arduino (1284 צר) והפלוטר הטורי. כל סוג של לוח תואם Arduino יעשה, אבל ככל שיש לו יותר זיכרון RAM, רזולוציית התדר הטובה ביותר שתקבלו. הוא ידרוש יותר מ- 8 KB של זיכרון RAM כדי לחשב את ה- FFT עם 1024 דוגמאות.
ניתוח ספקטרום משמש לקביעת מרכיבי התדר העיקריים של אות. צלילים רבים (כמו צלילים המופקים על ידי כלי נגינה) מורכבים מתדר יסודי וכמה הרמוניות בעלות תדר המהווה מספר רב שלם של התדר הבסיסי. מנתח הספקטרום יראה לך את כל המרכיבים הספקטרליים האלה.
ייתכן שתרצה להשתמש בהתקנה זו כמודד תדרים או כדי לבדוק כל סוג של אותות שאתה חושד שמביא רעש במעגל האלקטרוני שלך.
נתמקד כאן בחלק התוכנה. אם תרצה ליצור מעגל קבוע ליישום ספציפי, יהיה עליך להגביר ולסנן את האות. התניה מוקדמת זו תלויה לחלוטין באות שברצונך ללמוד, בהתאם לאמפליטודה, עכבה, תדירות מרבית וכו '… תוכל לבדוק
שלב 1: התקנת הספרייה
אנו נשתמש בספריית ArduinoFFT שנכתבה על ידי אנריקה קונדס. מכיוון שאנו רוצים לחסוך כמה שיותר זיכרון RAM, נשתמש בענף הפיתוח של מאגר זה המאפשר להשתמש בסוג נתוני הצוף (במקום כפול) לאחסון הנתונים שנדגמו ומחושבים. אז עלינו להתקין אותו ידנית. אל דאגה, פשוט הורד את הארכיון ופרק אותו בתיקיית ספריית ה- Arduino שלך (למשל בתצורת ברירת המחדל של Windows 10: C: / Users / _your_user_name_ / Documents / Arduino / libraries)
אתה יכול לבדוק שהספרייה מותקנת כראוי על ידי חיבור אחת הדוגמאות שסופקו, כמו "FFT_01.ino".
שלב 2: קונספט טרנספורמציה של פורייה ו- FFT
אזהרה: אם אינך יכול לסבול סימון מתמטי כלשהו, ייתכן שתרצה לדלג לשלב 3. בכל מקרה, אם אינך מבין הכל, שקול את המסקנה בסוף הקטע.
ספקטרום התדרים מתקבל באמצעות אלגוריתם טרנספורמציה מהירה של פורייה. FFT הוא יישום דיגיטלי המתקרב לקונספט המתמטי של טרנספורמציה פורייה. תחת מושג זה ברגע שתקבל את התפתחות האות בעקבות ציר זמן, תוכל לדעת את ייצוגו בתחום תדרים, המורכב מערכים מורכבים (אמיתיים + דמיוניים). הרעיון הוא הדדי, כך שכאשר אתה מכיר את ייצוג תחום התדרים אתה יכול להפוך אותו חזרה לתחום הזמן ולקבל את האות בחזרה בדיוק כמו לפני השינוי.
אבל מה אנחנו הולכים לעשות עם קבוצת הערכים המורכבים המחושבים בתחום הזמן? ובכן, רובו יותיר למהנדסים. עבורנו נקרא אלגוריתם נוסף שיהפוך את הערכים המורכבים הללו לנתוני צפיפות ספקטרלית: כלומר ערך גודל (= עוצמה) המשויך לכל רצועת תדרים. מספר פס התדרים יהיה זהה למספר הדגימות.
אתה בהחלט מכיר את הרעיון של אקולייזר, כמו זה חזרה לשנות השמונים עם ה- EQ הגרפי. ובכן, נשיג את אותו סוג של תוצאות אך עם 1024 רצועות במקום 16 ורזולוציית עוצמה הרבה יותר. כאשר האקולייזר נותן מבט עולמי על המוסיקה, ניתוח הספקטרלים העדינים מאפשר לחשב במדויק את עוצמת כל אחת מ -1024 הלהקות.
רעיון מושלם, אבל:
- מכיוון ש- FFT היא גרסה דיגיטלית של טרנספורמציה פורייה, היא מקרבת את האות הדיגיטלי ומאבדת מידע. אז, באופן קפדני, התוצאה של ה- FFT אם תוחזר לאחור עם אלגוריתם FFT הפוך לא תיתן בדיוק את האות המקורי.
- כמו כן התיאוריה מתייחסת לאות שאינו סופי, אך זהו אות קבוע המתמשך. מכיוון שנעשה את זה לדיגיטלי רק לפרק זמן מסוים (כלומר דוגמאות), יציגו עוד כמה שגיאות.
- לבסוף הרזולוציה של ההמרה האנלוגית לדיגיטלית תשפיע על איכות הערכים המחושבים.
בפועל
1) תדירות הדגימה (ציינו fs)
נדגום אות, כלומר נמדוד את המשרעת שלו, כל 1/fs שניות. fs היא תדירות הדגימה. לדוגמה, אם נדגום ב- 8 KHz, ה- ADC (ממיר אנלוגי לדיגיטלי) שנמצא על גבי השבב יספק מדידה כל 1/8000 שניות.
2) מספר הדגימות (ציין N או דוגמאות בקוד)
מכיוון שאנו צריכים לקבל את כל הערכים לפני הפעלת ה- FFT נצטרך לאחסן אותם ולכן נגביל את מספר הדגימות. אלגוריתם ה- FFT זקוק למספר דגימות בעל עוצמה של 2. ככל שיש לנו יותר דוגמאות כך טוב יותר אך הוא דורש הרבה זיכרון, על אחת כמה וכמה שנצטרך לאחסן את הנתונים שהופכו, שהם ערכים מורכבים. ספריית ה- Arduino FFT חוסכת מעט מקום על ידי שימוש
- מערך אחד בשם "vReal" לאחסון הנתונים שנדגמו ולאחר מכן החלק האמיתי של הנתונים שהשתנו
- מערך אחד בשם "vImag" לאחסון החלק הדמיוני של הנתונים שהשתנו
כמות הנדרשת של זיכרון RAM שווה ל -2 (מערכים) * 32 (סיביות) * N (דוגמאות).
אז ב- Atmega1284 שלנו בעל 16 קילו -בייט של זיכרון RAM נשמור מקסימום N = 16000*8 /64 = 2000 ערכים. מכיוון שמספר הערכים חייב להיות כוח של 2, נשמור לכל היותר 1024 ערכים.
3) רזולוציית התדר
ה- FFT יחשב ערכים למספר תדרים כמו מספר הדגימות. להקות אלה ינועו בין 0 HZ לתדר הדגימה (fs). מכאן שרזולוציית התדרים היא:
פתרון מחדש = fs / N
הרזולוציה טובה יותר כשהיא נמוכה יותר. אז בשביל רזולוציה טובה יותר (נמוכה יותר) אנחנו רוצים:
- דוגמאות נוספות, ו/או
- fs נמוך יותר
אבל…
4) מינימום fs
מכיוון שאנו רוצים לראות הרבה תדרים, חלקם גבוהים בהרבה מ"תדר היסוד ", איננו יכולים להגדיר את ה- FS נמוך מדי. למעשה יש את משפט הדגימה Nyquist – Shannon שמאלץ אותנו להיות בעלי תדר דגימה הרבה מעל פי שניים מהתדירות המקסימלית שהיינו רוצים לבדוק.
לדוגמה, אם נרצה לנתח את כל הספקטרום מ- 0 הרץ כדי לומר 15 קילוהרץ, שזה בערך התדר המרבי שרוב בני האדם יכולים לשמוע באופן מובהק, עלינו להגדיר את תדר הדגימה על 30 קילוהרץ. למעשה האלקטרוניקים קובעים אותו לעתים קרובות על 2.5 (או אפילו 2.52) * התדירות המקסימלית. בדוגמה זו זה יהיה 2.5 * 15 KHz = 37.5 KHz. תדרי הדגימה הרגילים באודיו המקצועי הם 44.1 KHz (הקלטת תקליטורי שמע), 48 KHz ועוד.
סיכום:
נקודות 1 עד 4 מובילות ל: אנו רוצים להשתמש בכמה דוגמאות ככל האפשר. במקרה שלנו עם מכשיר זיכרון RAM של 16 KB נשקול 1024 דוגמאות. אנו רוצים לדגום בתדירות הדגימה הנמוכה ביותר האפשרית, כל עוד הוא גבוה מספיק כדי לנתח את התדר הגבוה ביותר שאנו מצפים לאות שלנו (2.5 * תדר זה, לפחות).
שלב 3: הדמיית אות
בניסיון הראשון שלנו, נשנה מעט את הדוגמה TFT_01.ino שניתנה בספרייה, כדי לנתח אות המורכב
- התדר הבסיסי, מוגדר ל- 440 הרץ (מוזיקלי A)
- הרמוניה שלישית בחצי מעוצמת היסוד ("-3 dB")
- הרמונית חמישית ב 1/4 מהעוצמה של היסוד ("-6 dB)
אתה יכול לראות בתמונה מעל האות המתקבל. זה אכן נראה מאוד כמו אות אמיתי שאפשר לפעמים לראות באוסילוסקופ (הייתי קורא לזה "באטמן") במצב שיש חיתוך של אות סינוסי.
שלב 4: ניתוח אות מדומה - קידוד
0) כלול את הספרייה
#כלול "arduinoFFT.h"
1) הגדרות
בסעיפי ההצהרות יש לנו
const byte adcPin = 0; // A0
const uint16_t דוגמאות = 1024; // ערך זה חייב להיות תמיד כוח של 2 const uint16_t samplingFrequency = 8000; // ישפיע על הערך המקסימלי של הטיימר ב- timer_setup () SYSCLOCK/8/sampling התדירות צריכה להיות מספר שלם
מכיוון שלאות יש הרמוניה חמישית (תדירות הרמונית זו = 5 * 440 = 2200 הרץ) עלינו להגדיר את תדר הדגימה מעל 2.5 * 2200 = 5500 הרץ. כאן בחרתי 8000 הרץ.
אנו מצהירים גם על המערכים שבהם נשמור את הנתונים הגולמיים והמחושבים
float vReal [דוגמאות];
float vImag [דוגמאות];
2) אינסטנטציה
אנו יוצרים אובייקט ArduinoFFT. גרסת ה- dev של ArduinoFFT משתמשת בתבנית כדי שנוכל להשתמש בצוף או בסוג הנתונים הכפול. Float (32 סיביות) מספיק ביחס לדיוק הכללי של התוכנית שלנו.
ArduinoFFT FFT = ArduinoFFT (vReal, vImag, samples, samplingFrequency);
3) הדמיה של האות על ידי אכלוס מערך vReal, במקום לאכלס אותו בערכי ADC.
בתחילת הלולאה אנו מאכלסים את מערך vReal עם:
מחזורי צף = (((samples) * signalFrequency) / samplingFrequency); // מספר מחזורי האות שהדגימה תקרא
for (uint16_t i = 0; i <samples; 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:: קדימה); / * Compute FFT */ FFT.complexToMagnitude (); / * חישוב גודל */
פעולת FFT.windowing (…) משנה את הנתונים הגולמיים מכיוון שאנו מריצים את ה- FFT במספר דגימות מוגבל. הדגימות הראשונות והאחרונות מציגות אי רציפות (אין שום דבר בצד אחד שלהן). זהו מקור לשגיאה. פעולת "החלון" נוטה לצמצם שגיאה זו.
FFT.compute (…) עם הכיוון "קדימה" מחשב את השינוי מתחום הזמן לתחום התדרים.
לאחר מכן אנו מחשבים את ערכי הגודל (כלומר עוצמה) עבור כל אחת מרצועות התדרים. מערך vReal מלא כעת בערכי גודל.
5) ציור פלוטר סדרתי
בואו להדפיס את הערכים במגרש הטורי על ידי קריאה לפונקציה printVector (…)
PrintVector (vReal, (דוגמאות >> 1), SCL_FREQUENCY);
זוהי פונקציה כללית המאפשרת להדפיס נתונים עם ציר זמן או ציר תדר.
אנו מדפיסים גם את תדירות הלהקה בעלת ערך העוצמה הגבוה ביותר
float x = FFT.majorPeak ();
Serial.print ("f0 ="); הדפסה סידורית (x, 6); Serial.println ("הרץ");
שלב 5: ניתוח אות מדומה - תוצאות
אנו רואים 3 קוצים המתאימים לתדר הבסיסי (f0), ההרמוניות השלישית והחמישית, עם חצי ו -1/4 מגודל f0, כצפוי. אנו יכולים לקרוא בחלק העליון של החלון f0 = 440.430114 הרץ. ערך זה אינו בדיוק 440 הרץ, בגלל כל הסיבות שהוסברו למעלה, אך הוא קרוב מאוד לערך האמיתי. לא ממש היה צורך להציג כל כך הרבה עשרונים חסרי משמעות.
שלב 6: ניתוח אות אמיתי - חיווט ה- ADC
מכיוון שאנו יודעים כיצד להמשיך בתיאוריה, נרצה לנתח אות אמיתי.
החיווט פשוט מאוד. חבר את הקרקע יחד ואת קו האות לסיכה A0 של הלוח שלך באמצעות נגד סדרה בערך 1 קאוהם עד 10 קאוהם.
נגד סדרה זו יגן על הקלט האנלוגי וימנע מצלצולים. הוא חייב להיות גבוה ככל האפשר כדי להימנע מצלצולים, וכמה שיותר נמוך כדי לספק מספיק זרם כדי לטעון את ה- ADC במהירות. עיין בגיליון הנתונים של MCU כדי לדעת את העכבה הצפויה של האות המחובר בכניסת ה- ADC.
עבור הדגמה זו השתמשתי בגנרטור פונקציות כדי להזין אות סינוסי של תדר 440 הרץ ומשרעת סביב 5 וולט (עדיף אם המשרעת היא בין 3 ל -5 וולט כך שה- ADC משמש כמעט בקנה מידה מלא), באמצעות נגד 1.2 קאוהם.
שלב 7: ניתוח אות אמיתי - קידוד
0) כלול את הספרייה
#כלול "arduinoFFT.h"
1) הצהרות והסתה
בחלק ההצהרה אנו מגדירים את קלט ה- ADC (A0), מספר הדגימות ותדירות הדגימה, כמו בדוגמה הקודמת.
const byte adcPin = 0; // A0
const uint16_t דוגמאות = 1024; // ערך זה חייב להיות תמיד כוח של 2 const uint16_t samplingFrequency = 8000; // ישפיע על הערך המקסימלי של הטיימר ב- timer_setup () SYSCLOCK/8/sampling התדירות צריכה להיות מספר שלם
אנו יוצרים את האובייקט ArduinoFFT
ArduinoFFT FFT = ArduinoFFT (vReal, vImag, samples, samplingFrequency);
2) טיימר והתקנת ADC
הגדרנו את טיימר 1 כך שהוא יסתובב בתדר הדגימה (8 קילוהרץ) ויעלה הפרעה בהשוואה לפלט.
void timer_setup () {
// איפוס טיימר 1 TCCR1A = 0; TCCR1B = 0; TCNT1 = 0; TCCR1B = bit (CS11) | ביט (WGM12); // CTC, מכשיר טרום של 8 TIMSK1 = bit (OCIE1B); OCR1A = ((16000000 /8) / samplingFrequency) -1; }
והגדר את ה- ADC כך
- משתמש ב- A0 כקלט
- מפעילה אוטומטית בכל פלט טיימר 1 השווה התאמה ב '
- יוצר הפרעה עם השלמת ההמרה
שעון ה- ADC מוגדר על 1 מגה -הרץ, על -ידי שינוי גודל מוקדם של שעון המערכת (16 מגה -הרץ) ב -16. מכיוון שכל המרה לוקחת כ -13 שעונים בקנה מידה מלא, ניתן להשיג המרות בתדר של 1/13 = 0.076 מגהרץ = 76 קילוהרץ. תדירות הדגימה צריכה להיות נמוכה משמעותית מ- 76 KHz כדי לאפשר ל- ADC זמן לדגום את הנתונים. (בחרנו fs = 8 KHz).
void adc_setup () {
ADCSRA = bit (ADEN) | bit (ADIE) | bit (ADIF); // הפעל את ADC, רוצה הפרעה בסיום ADCSRA | = bit (ADPS2); // מכשיר טעינה מראש של 16 ADMUX = bit (REFS0) | (adcPin & 7); // הגדרת קלט ADC ADCSRB = bit (ADTS0) | bit (ADTS2); // טיימר/מונה 1 השווה את מקור ההדק של התאמה B ADCSRA | = bit (ADATE); // הפעל את ההפעלה האוטומטית}
אנו מצהירים על מטפל הפרעות שייקרא לאחר כל המרת ADC לאחסן את הנתונים המומרים במערך vReal, ולסלק את ההפרעה
// ADR השלם ISR
ISR (ADC_vect) {vReal [resultNumber ++] = ADC; אם (resultNumber == דוגמאות) {ADCSRA = 0; // לכבות את ADC}} EMPTY_INTERRUPT (TIMER1_COMPB_vect);
תוכל לקבל הסבר ממצה על המרת ADC ב- Arduino (analogRead).
3) התקנה
בפונקציית ההתקנה אנו מנקים את טבלת הנתונים הדמיונית וקוראים לפונקציות הגדרת הטיימר וה- ADC
zeroI (); // פונקציה שהגדירה ל- 0 את כל הנתונים הדמיוניים - מוסברת בחלק הקודם
timer_setup (); adc_setup ();
3) לולאה
FFT.dcRemoval (); // הסר את רכיב ה- DC של האות הזה מכיוון שה- ADC מופנה לקרקע
FFT.windowing (FFTWindow:: Hamming, FFTDirection:: Forward); // שקול נתונים FFT.compute (FFTDirection:: קדימה); // מחשב FFT FFT.complexToMagnitude (); // חישוב גודל // הדפסת הספקטרום והתדר הבסיסי f0 PrintVector (vReal, (דוגמאות >> 1), SCL_FREQUENCY); float x = FFT.majorPeak (); Serial.print ("f0 ="); הדפסה סידורית (x, 6); Serial.println ("הרץ");
אנו מסירים את רכיב ה- DC מכיוון שה- ADC מופנה לקרקע והאות מתרכז סביב 2.5 וולט בערך.
לאחר מכן אנו מחשבים את הנתונים כפי שהוסבר בדוגמה הקודמת.
שלב 8: ניתוח אות אמיתי - תוצאות
אכן אנו רואים רק תדר אחד באות הפשוט הזה. התדר הבסיסי המחושב הוא 440.118194 הרץ. גם כאן הערך הוא קירוב קרוב מאוד של התדר האמיתי.
שלב 9: מה לגבי אות סינוסואידי קצוץ?
עכשיו מאפשר להגביר מעט את ה- ADC על ידי הגדלת משרעת האות מעל 5 וולט, כך שהוא נחתך. אל תלחץ יותר מדי כדי לא להרוס את קלט ה- ADC!
אנו יכולים לראות כמה הרמוניות מופיעות. חיתוך האות יוצר רכיבים בתדירות גבוהה.
ראית את יסודות ניתוח FFT על לוח Arduino. כעת תוכל לנסות לשנות את תדירות הדגימה, מספר הדגימות ופרמטר החלון. הספרייה מוסיפה גם פרמטר כלשהו לחישוב ה- FFT מהר יותר עם פחות דיוק. תבחין שאם תגדיר את תדירות הדגימה נמוכה מדי, הגדלים המחושבים יראו שגויים לחלוטין בגלל קיפול ספקטרלי.
מוּמלָץ:
כיצד להכין מנתח ספקטרום אודיו LED: 7 שלבים (עם תמונות)
כיצד להכין מנתח ספקטרום אודיו LED: מנתח אודיו ספקטרום LED יוצר את תבנית התאורה היפה בהתאם לעוצמת המוסיקה. יש הרבה ערכות ספקטרום LED של מוסיקה LED זמינות בשוק, אך כאן אנו הולכים להכין ספקטרום אודיו LED. מנתח באמצעות NeoPixe
כיצד לבצע DIY 32 Band LED אודיו מוסיקה ספקטרום מנתח באמצעות Arduino Nano בבית #arduinoproject: 8 שלבים
כיצד לבצע DIY 32 Band LED אודיו מוסיקה ספקטרום מנתח באמצעות Arduino Nano בבית #arduinoproject: היום נכין מנתח מוזיקת ספקטרום LED של אודיו 32 להבים בבית באמצעות Arduino, הוא יכול להראות ספקטרום תדרים ולשחק מוזיקה בו זמנית. הערה max7219LED חייב להיות מחובר מול הנגד של 100k, אחרת רעש הדיבורים
מנתח ספקטרום אקרילי גדול במיוחד: 7 שלבים (עם תמונות)
מנתח ספקטרום אקרילי גדול במיוחד: מדוע שתרצה להסתכל על תצוגות הלד הזעירות או על מסכי ה- LCD הקטנים האלה אם תוכל לעשות זאת בגדול? זהו תיאור שלב אחר שלב כיצד לבנות מנתח ספקטרום בגודל ענק משלך. שימוש באריחי אקריליק ו רצועות לד לבניית חדר מילוי בחדר
מנתח ספקטרום אודיו DIY FFT: 3 שלבים
מנתח ספקטרום אודיו DIY FFT: מנתח ספקטרום FFT הוא ציוד בדיקה המשתמש בניתוח פורייה וטכניקות עיבוד אותות דיגיטליים כדי לספק ניתוח ספקטרום. באמצעות ניתוח פורייה אפשר שערך אחד, למשל, בתחום הזמן הרציף יהיה מתכנס
מנתח ספקטרום 10 Band Led: 11 שלבים
מנתח ספקטרום 10 Band Led: אחר צהריים טובים, צופים וקוראים יקרים. היום אני רוצה להראות לך את מדריך ההרכבה המלא של מנתח הספקטרום LED בעל 10 פס