תוכן עניינים:
- אספקה
- שלב 1: בנה את החומרה לגלאי התווים המוזיקליים
- שלב 2: תכנת את גלאי התווים המוזיקליים
- שלב 3: הגדר את גלאי התווים המוזיקליים
וִידֵאוֹ: גלאי תו מוזיקלי: 3 שלבים
2024 מְחַבֵּר: John Day | [email protected]. שונה לאחרונה: 2024-01-30 09:12
להדהים את החברים והמשפחה שלך עם הפרויקט הזה שמזהה את הפתק שמנגן כלי. פרויקט זה יציג את התדירות המשוערת כמו גם את התו המוסיקלי המנגן על מקלדת אלקטרונית, אפליקציית פסנתר או כל כלי אחר.
פרטים
עבור פרויקט זה, הפלט האנלוגי מגלאי מודול הקול נשלח לקלט האנלוגי A0 של ה- Arduino Uno. האות האנלוגי נדגם וכמת (דיגיטציה). קוד מתאם, שקלול וכוונון משמש לאיתור תדר בסיסי באמצעות 3 התקופות הראשונות. לאחר מכן משווים את התדר הבסיסי המשוער לתדרים בטווחי האוקטבות 3, 4 ו -5 כדי לקבוע את תדירות התווים המוזיקליים הקרובים ביותר. לבסוף ההערה הניחשת לתדירות הקרובה ביותר מודפסת למסך.
הערה: הוראה זו מתמקדת רק בבניית הפרויקט. למידע נוסף אודות הפרטים והצדקות העיצוב, אנא בקר בקישור זה: מידע נוסף
אספקה
- (1) Arduino Uno (או Genuino Uno)
- (1) חיישן מיקרופון DEVMO תואם מודול זיהוי צליל ברגישות גבוהה
- (1) לוח לחם ללא הלחמה
- (1) כבל USB-A ל- B
- חוטי מגשר
- מקור מוזיקלי (פסנתר, מקלדת או אפליקציית paino עם רמקולים)
- (1) מחשב או מחשב נייד
שלב 1: בנה את החומרה לגלאי התווים המוזיקליים
שימוש ב- Arduino Uno, חוטי חיבור, לוח לחם ללא הלחמה וחיישן מיקרופון DEVMO חיישן מודול זיהוי צליל ברגישות גבוהה (או דומה) יוצרים את המעגל המוצג בתמונה זו
שלב 2: תכנת את גלאי התווים המוזיקליים
ב- IDE של Arduino, הוסף את הקוד הבא.
gistfile1.txt
/* |
שם קובץ/סקיצה: MusicalNoteDetector |
מספר גירסה: v1.0 נוצר 7 ביוני, 2020 |
המחבר המקורי: קלייד א. לטסום, PhD, PE, MEM |
תיאור: קוד/מערכון זה מציג את התדירות המשוערת כמו גם את התו המוזיקלי המנוגן במקלדת אלקטרונית או באפליקציית פסנתר. עבור פרויקט זה, הפלט האנלוגי מה |
גלאי מודול הקול נשלח לכניסה האנלוגית A0 של ה- Arduino Uno. האות האנלוגי נדגם וכמות (דיגיטציה). קוד מתאם, שקלול וכוונון משמש |
מצא תדר בסיסי באמצעות 3 התקופות הראשונות. לאחר מכן משווים את התדר היסודי המשוער לתדרים בטווחי האוקטבות 3, 4 ו -5 כדי לקבוע את המחזמר הקרוב ביותר |
תדירות הערה. לבסוף ההערה הניחשת לתדירות הקרובה ביותר מודפסת למסך. |
רישיון: תוכנית זו הינה תוכנה חינמית; אתה יכול להפיץ אותו מחדש ו/או לשנות אותו בהתאם לתנאי הרישיון הציבורי הכללי של GNU (GPL), גירסה 3, או כל גירסה מאוחרת יותר. |
גרסה לבחירתך, כפי שפורסמה על ידי קרן התוכנה החופשית. |
הערות: זכויות יוצרים (ג) 2020 מאת C. A. Lettsome Services, LLC |
למידע נוסף בקר בכתובת https://clydelettsome.com/blog 2020/06/07/my-weekend-project-musical-note-detector-using-an-arduino/ |
*/ |
#define SAMPLES 128 // Max 128 עבור Arduino Uno. |
#define SAMPLING_FREQUENCY 2048 // Fs = מבוסס על Nyquist, חייב להיות פי 2 מהתדירות הגבוהה ביותר הצפויה. |
#define OFFSETSAMPLES 40 // משמש למטרות כיוון |
#define TUNER -3 // כוונן עד ש- C3 הוא 130.50 |
float samplingPeriod; |
מיקרו שניות ארוכות ללא סימן; |
int X [דוגמאות]; // צור וקטור בגודל SAMPLES בכדי להחזיק ערכים אמיתיים |
float autoCorr [SAMPLES]; // צור וקטור בגודל SAMPLES בכדי להחזיק ערכים דמיוניים |
float storageNoteFreq [12] = {130.81, 138.59, 146.83, 155.56, 164.81, 174.61, 185, 196, 207.65, 220, 233.08, 246.94}; |
int sumOffSet = 0; |
int offSet [OFFSETSAMPLES]; // ליצור וקטור אופסט |
int avgOffSet; // ליצור וקטור אופסט |
int i, k, periodEnd, periodBegin, period, aduster, noteLocation, octaveRange; |
float maxValue, minValue; |
סכום ארוך; |
int thresh = 0; |
int numOfCycles = 0; |
float signalFrequency, signalFrequency2, signalFrequency3, signalFrequencyGuess, סה"כ; |
בייט state_machine = 0; |
int samplesPerPeriod = 0; |
הגדרת חלל () |
{ |
Serial.begin (115200); // 115200 קצב שידור עבור הצג הסידורי |
} |
לולאת חלל () |
{ |
//***************************************************************** |
// מדור כיול |
//***************************************************************** |
Serial.println ("Calabrating. נא לא לשחק כל תווים במהלך הכיול."); |
עבור (i = 0; i <OFFSETSAMPLES; i ++) |
{ |
offSet = analogRead (0); // קורא את הערך מהפין האנלוגי 0 (A0), כמת אותו ושמור אותו כמונח אמיתי. |
//Serial.println(offSet ); // השתמש בזה כדי להתאים את מודול זיהוי הקול לכמחצית או 512 כאשר לא מושמע צליל. |
sumOffSet = sumOffSet + offSet ; |
} |
samplesPerPeriod = 0; |
maxValue = 0; |
//***************************************************************** |
// התכונן לקבל קלט מ- A0 |
//***************************************************************** |
avgOffSet = round (sumOffSet / OFFSETSAMPLES); |
Serial.println ("לספור לאחור."); |
עיכוב (1000); // השהה למשך 1 שניות |
Serial.println ("3"); |
עיכוב (1000); // השהה למשך 1 שניות |
Serial.println ("2"); |
עיכוב (1000); // הפסקה למשך 1 |
Serial.println ("1"); |
עיכוב (1000); // השהה למשך 1 שניות |
Serial.println ("שחק את ההערה שלך!"); |
עיכוב (250); // הפסקה למשך 1/4 שנייה לזמן תגובה |
//***************************************************************** |
// אסוף דגימות מדגם A0 עם תקופת הדגימה של הדגימה |
//***************************************************************** |
samplingPeriod = 1.0 / SAMPLING_FREQUENCY; // נקודה במיקרו שניות |
עבור (i = 0; i <SAMPLES; i ++) |
{ |
microSeconds = micros (); // מחזירה את מספר המיקרו -שניות מאז שהלוח Arduino החל להריץ את התסריט הנוכחי. |
X = analogRead (0); // קורא את הערך מהפין האנלוגי 0 (A0), כמת אותו ושמור אותו כמונח אמיתי. |
/ *זמן ההמתנה שנותר בין הדגימות במידת הצורך תוך שניות */ |
בעוד (micros () <(microSeconds + (samplingPeriod * 1000000))) |
{ |
// אל תעשה כלום רק חכה |
} |
} |
//***************************************************************** |
// פונקציית מתאם אוטומטי |
//***************************************************************** |
עבור (i = 0; i <SAMPLES; i ++) // i = עיכוב |
{ |
סכום = 0; |
עבור (k = 0; k <SAMPLES - i; k ++) // התאמת אות עם אות מושהה |
{ |
סכום = סכום + (((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)); // X [k] הוא האות ו- X [k+i] הוא הגרסה המתעכבת |
} |
autoCorr = סכום / דוגמאות; |
// מכונת המדינה לראשונה לאתר שיא |
אם (state_machine == 0 && i == 0) |
{ |
דוש = autoCorr * 0.5; |
מכונת מצב = 1; |
} |
אחרת אם (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1, מצא תקופה אחת לשימוש במחזור הראשון |
{ |
maxValue = autoCorr ; |
} |
אחרת אם (state_machine == 1 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodBegin = i-1; |
מכונת מצב = 2; |
numOfCycles = 1; |
samplesPerPeriod = (periodBegin - 0); |
period = samplesPerPeriod; |
מתאם = TUNER+(50.04 * exp (-0.102 * samplesPerPeriod)); |
signalFrequency = ((SAMPLING_FREQUENCY) / (samplesPerPeriod))-מתאם; // f = fs/N |
} |
אחרת אם (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2, מצא 2 תקופות למחזור הראשון והשני |
{ |
maxValue = autoCorr ; |
} |
אחרת אם (state_machine == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodEnd = i-1; |
מכונת מצב = 3; |
numOfCycles = 2; |
samplesPerPeriod = (periodEnd - 0); |
signalFrequency2 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplesPerPeriod))-מתאם; // f = (2*fs)/(2*N) |
maxValue = 0; |
} |
אחרת אם (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3, מצא 3 תקופות למחזור הראשון, השני וה -3. |
{ |
maxValue = autoCorr ; |
} |
אחרת אם (state_machine == 3 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodEnd = i-1; |
state_machine = 4; |
numOfCycles = 3; |
samplesPerPeriod = (periodEnd - 0); |
signalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplesPerPeriod))-מתאם; // f = (3*fs)/(3*N) |
} |
} |
//***************************************************************** |
// ניתוח תוצאות |
//***************************************************************** |
אם (samplesPerPeriod == 0) |
{ |
Serial.println ("הממ ….. אני לא בטוח. אתה מנסה לרמות אותי?"); |
} |
אַחֵר |
{ |
// להכין את פונקציית הניפוח |
סה"כ = 0; |
אם (signalFrequency! = 0) |
{ |
סה"כ = 1; |
} |
אם (signalFrequency2! = 0) |
{ |
סה"כ = סה"כ + 2; |
} |
אם (signalFrequency3! = 0) |
{ |
סה"כ = סה"כ + 3; |
} |
// לחשב את התדירות באמצעות פונקציית הניפוח |
signalFrequencyGuess = ((1/סה"כ) * signalFrequency) + ((2/סה"כ) * signalFrequency2) + ((3/סה"כ) * signalFrequency3); // מצא תדר משוקלל |
Serial.print ("הפתק ששיחקת הוא בערך"); |
Serial.print (signalFrequencyGuess); // הדפס את ניחוש התדרים. |
Serial.println ("הרץ"); |
// מצא טווח אוקטבה על סמך הניחוש |
OctaveRange = 3; |
while (! (signalFrequencyGuess> = storedNoteFreq [0] -7 && signalFrequencyGuess <= storageNoteFreq [11] +7)) |
{ |
עבור (i = 0; i <12; i ++) |
{ |
storageNoteFreq = 2 * storageNoteFreq ; |
} |
OctaveRange ++; |
} |
// מצא את הפתק הקרוב ביותר |
minValue = 10000000; |
noteLocation = 0; |
עבור (i = 0; i <12; i ++) |
{ |
if (minValue> abs (signalFrequencyGuess-storedNoteFreq )) |
{ |
minValue = abs (signalFrequencyGuess-storedNoteFreq ); |
noteLocation = i; |
} |
} |
// הדפס את הפתק |
Serial.print ("אני חושב ששיחקת"); |
אם (noteLocation == 0) |
{ |
Serial.print ("C"); |
} |
אחרת אם (noteLocation == 1) |
{ |
Serial.print ("C#"); |
} |
אחרת אם (noteLocation == 2) |
{ |
Serial.print ("D"); |
} |
אחרת אם (noteLocation == 3) |
{ |
Serial.print ("D#"); |
} |
אחרת אם (noteLocation == 4) |
{ |
Serial.print ("E"); |
} |
אחרת אם (noteLocation == 5) |
{ |
Serial.print ("F"); |
} |
אחרת אם (noteLocation == 6) |
{ |
Serial.print ("F#"); |
} |
אחרת אם (noteLocation == 7) |
{ |
Serial.print ("G"); |
} |
אחרת אם (noteLocation == 8) |
{ |
Serial.print ("G#"); |
} |
אחרת אם (noteLocation == 9) |
{ |
Serial.print ("A"); |
} |
אחרת אם (noteLocation == 10) |
{ |
Serial.print ("A#"); |
} |
אחרת אם (noteLocation == 11) |
{ |
Serial.print ("B"); |
} |
Serial.println (octaveRange); |
} |
//***************************************************************** |
//עצור כאן. לחץ על כפתור האיפוס ב- Arduino כדי להפעיל מחדש |
//***************************************************************** |
בעוד (1); |
} |
הצג rawgistfile1.txt המתארח אצל ❤ על ידי GitHub
שלב 3: הגדר את גלאי התווים המוזיקליים
חבר את ה- Arduino Uno למחשב האישי עם הקוד שנכתב או נטען ב- Arduino IDE. הידור והעלה את הקוד ל- Arduino. מקם את המעגל קרוב למקור המוסיקה. הערה: בסרטון ההקדמה אני משתמש באפליקציה המותקנת בטאבלט יחד עם רמקולי מחשב כמקור המוסיקה שלי. לחץ על כפתור האיפוס בלוח Arduino ולאחר מכן השמע פתק על מקור המוסיקה. לאחר מספר שניות, גלאי התווים המוזיקליים יציג את התו שהושמע ותדירותו.
מוּמלָץ:
תלת מימד מוזיקלי של לאמפרה (Vúmetro LED): 6 שלבים
Lámpara Musical 3D (Vúmetro LED): L á mpara que reacciona a la m ú sica que se reproduce, compuesta por un V ú metro LED and una pantalla impresa in 3D. El vumetro se enciende a medida que el voltaje de la canci ó n se lo indica, es una representaci ó n visual
כיסא מוזיקלי: 11 שלבים (עם תמונות)
כיסא מוזיקלי: מאוכזב בשם המשחק '' כסאות מוזיקליים '', יצאתי לדרך ליצור כיסא מוזיקלי ממשי, כמו ב, כיסא שניתן לנגן ככלי נגינה, כיסא נדנדה אם תרצה. התקווה שלי היא בסופו של דבר לשחק משחק כיסא מוזיקלי אמיתי
בד ציור מוזיקלי עם מייקי מייקי: 9 שלבים (עם תמונות)
בד ציור מוזיקלי עם מייקי מייקי: היי, במדריך זה נלמד כיצד להכין בד ציור מוזיקלי, כלומר, שיר אחר נשמע בכל פעם שאנו צובעים בעזרת מכחול מכל צבע. זה מאוד מהנה ופועל לעידוד ציור בילדים צעירים או גם לתת מפרט
חידון מוזיקלי: 5 שלבים
חידון מוזיקלי: שלום, אנו קבוצה של שלושה סטודנטים במודול שנה ה 'להנדסת אלקטרוניקה מאוניברסיטת מלאגה, בית הספר לתקשורת (https://www.uma.es/etsi-de-telecomunicacion/) ואנו הולכים ל להראות לך את היכולת שלנו לשיחת הנושא
גלאי עשן IOT: עדכן גלאי עשן קיים עם IOT: 6 שלבים (עם תמונות)
גלאי עשן IOT: עדכן גלאי עשן קיים עם IOT: רשימת תורמים, ממציא: טאן סיו צ'ין, טאן ייט פנג, טאן ווי הנג מפקח: ד"ר צ'יה קים סנג המחלקה להנדסת מכונות ו רובוטיקה, הפקולטה להנדסת חשמל ואלקטרוניקה, אוניברסיטי טון חוסיין און מלזיה. הפצה