فهرست مطالب:
- تدارکات
- مرحله 1: سخت افزار را برای آشکارساز یادداشت موسیقی بسازید
- مرحله 2: برنامه آشکارساز موسیقی را برنامه ریزی کنید
- مرحله 3: آشکارساز یادداشت موسیقی را راه اندازی کنید
تصویری: آشکارساز نت موسیقی: 3 مرحله
2024 نویسنده: John Day | [email protected]. آخرین اصلاح شده: 2024-01-30 08:52
با این پروژه که نت های نواخته شده توسط یک ساز را تشخیص می دهد ، دوستان و خانواده خود را شگفت زده کنید. این پروژه فرکانس تقریبی و همچنین نت موسیقی را که روی صفحه کلید الکترونیکی ، برنامه پیانو یا هر ساز دیگر پخش می شود نشان می دهد.
جزئیات
برای این پروژه ، خروجی آنالوگ از آشکارساز ماژول صدا به ورودی آنالوگ A0 Arduino Uno ارسال می شود. سیگنال آنالوگ نمونه برداری و کمی سازی (دیجیتالی) می شود. برای یافتن فرکانس اساسی با استفاده از 3 دوره اول ، از کد خود همبستگی ، وزن و تنظیم استفاده می شود. فرکانس اصلی تقریبی سپس با فرکانس های محدوده اکتاو 3 ، 4 و 5 مقایسه می شود تا نزدیکترین فرکانس نت موسیقی مشخص شود. در نهایت یادداشت حدس زده شده برای نزدیکترین فرکانس روی صفحه چاپ می شود.
توجه: این دستورالعمل فقط بر نحوه ساخت پروژه تمرکز دارد. برای اطلاعات بیشتر در مورد جزئیات و توجیهات طراحی ، لطفاً از این پیوند دیدن کنید: اطلاعات بیشتر
تدارکات
- (1) Arduino Uno (یا Genuino Uno)
- (1) سنسور میکروفن DEVMO ماژول تشخیص صدا با حساسیت بالا سازگار است
- (1) تخته نان بدون جوش
- (1) کابل USB-A تا B
- سیم های بلوز
- منبع موسیقی (پیانو ، صفحه کلید یا برنامه درد با بلندگوها)
- (1) کامپیوتر یا لپ تاپ
مرحله 1: سخت افزار را برای آشکارساز یادداشت موسیقی بسازید
با استفاده از Arduino Uno ، سیم های اتصال ، یک تخته نان بدون لحیم و یک ماژول تشخیص صدا با حساسیت میکروفون DEVMO (یا مشابه) مدار نشان داده شده در این تصویر را ایجاد کنید
مرحله 2: برنامه آشکارساز موسیقی را برنامه ریزی کنید
در Arduino IDE کد زیر را اضافه کنید.
gistfile1.txt
/* |
نام فایل/طرح: MusicalNoteDetector |
نسخه شماره: v1.0 ایجاد شده در 7 ژوئن 2020 |
نویسنده اصلی: Clyde A. Lettsome ، PhD ، PE ، MEM |
توضیحات: این کد/طرح فرکانس تقریبی و همچنین نت موسیقی پخش شده بر روی صفحه کلید الکترونیکی یا برنامه پیانو را نشان می دهد. برای این پروژه ، خروجی آنالوگ از |
آشکارساز ماژول صدا به ورودی آنالوگ A0 آردوینو 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/ مراجعه کنید |
*/ |
#تعریف نمونه 128 /حداکثر 128 برای Arduino Uno. |
#تعریف SAMPLING_FREQUENCY 2048 // Fs = بر اساس Nyquist ، باید 2 برابر بیشترین فرکانس مورد انتظار باشد. |
#تعریف OFFSETSAMPLES 40 // برای مقاصد مورد استفاده قرار می گیرد |
#define TUNER -3 // تنظیم کنید تا C3 130.50 شود |
نمونه برداری شناور دوره |
میکرو ثانیه های طولانی بدون علامت ؛ |
int X [نمونه] ؛ // ایجاد بردار اندازه SAMPLES برای نگه داشتن مقادیر واقعی |
floot 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، تنظیم کننده، noteLocation، octaveRange؛ |
float maxValue ، minValue ؛ |
مبلغ طولانی ؛ |
int thresh = 0؛ |
int numOfCycles = 0 ؛ |
سیگنال شناور فرکانس ، سیگنال فرکانس 2 ، سیگنال فرکانس 3 ، سیگنال فرکانس حدس زدن ، مجموع ؛ |
بایت state_machine = 0؛ |
نمونه intPerPeriod = 0 ؛ |
void setup () |
{ |
Serial.begin (115200) ؛ // 115200 نرخ Baud برای سریال مانیتور |
} |
حلقه خالی () |
{ |
//***************************************************************** |
// بخش Calabration |
//***************************************************************** |
Serial.println ("Calabrating. لطفاً در هنگام calabration هیچ نت را پخش نکنید.")؛ |
برای (i = 0 ؛ i <OFFSETSAMPLES ؛ i ++) |
{ |
offSet = analogRead (0) ؛ // مقدار را از پین آنالوگ 0 (A0) می خواند ، آن را کمی می کند و به عنوان یک عبارت واقعی ذخیره می کند. |
//Serial.println(offSet ) ؛ // از این مورد برای تنظیم ماژول تشخیص صدا در تقریباً نصف یا 512 هنگامی که هیچ صدایی پخش نمی شود ، استفاده کنید. |
sumOffSet = sumOffSet + offSet ؛ |
} |
samplePerPeriod = 0 ؛ |
maxValue = 0؛ |
//***************************************************************** |
// برای پذیرش ورودی A0 آماده شوید |
//***************************************************************** |
avgOffSet = دور (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 ثانیه مکث کنید |
//***************************************************************** |
// نمونه SAMPLES از A0 را با دوره نمونه گیری SamplingPeriod جمع آوری کنید |
//***************************************************************** |
samplingPeriod = 1.0 / SAMPLING_FREQUENCY ؛ // دوره بر حسب میکروثانیه |
برای (i = 0 ؛ i <SAMPLES ؛ i ++) |
{ |
microSeconds = micros ()؛ // تعداد میکرو ثانیه ها را از زمانی که برد آردوینو شروع به اجرای اسکریپت فعلی می کند ، برمی گرداند. |
X = analogRead (0) ؛ // مقدار را از پین آنالوگ 0 (A0) می خواند ، آن را کمی می کند و به عنوان یک عبارت واقعی ذخیره می کند. |
/ *زمان انتظار بین نمونه ها در صورت لزوم در ثانیه */ |
در حالی که (micros () <(microSeconds + (samplingPeriod * 1000000))) |
{ |
// هیچ کاری نکن فقط صبر کن |
} |
} |
//***************************************************************** |
// تابع خود همبستگی |
//***************************************************************** |
برای (i = 0 ؛ i <SAMPLES ؛ i ++) // i = تأخیر |
{ |
جمع = 0 ؛ |
برای (k = 0 ؛ k <SAMPLES - i ؛ k ++) // سیگنال را با سیگنال تأخیری مطابقت دهید |
{ |
sum = sum + ((((X [k]) - avgOffSet) * ((X [k + i]) - avgOffSet)) ؛ // X [k] سیگنال و X [k+i] نسخه تاخیری است |
} |
autoCorr = sum / SAMPLES؛ |
// First Peak Detect Machine State |
if (state_machine == 0 && i == 0) |
{ |
thresh = autoCorr * 0.5 ؛ |
state_machine = 1؛ |
} |
در غیر این صورت (state_machine == 1 && i> 0 && thresh 0) // state_machine = 1 ، 1 دوره برای استفاده از چرخه اول پیدا کنید |
{ |
maxValue = autoCorr ؛ |
} |
else if (state_machine == 1 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodBegin = i-1؛ |
state_machine = 2؛ |
numOfCycles = 1 ؛ |
samplePerPeriod = (periodBegin - 0)؛ |
period = samplePerPeriod؛ |
تنظیم کننده = TUNER+(50.04 * exp (-0.102 * samplePerPeriod)) ؛ |
signalFrequency = ((SAMPLING_FREQUENCY) / (samplePerPeriod))-تنظیم کننده ؛ // f = fs/N |
} |
در غیر این صورت (state_machine == 2 && i> 0 && thresh 0) // state_machine = 2 ، 2 دوره برای چرخه 1 و 2 پیدا کنید |
{ |
maxValue = autoCorr ؛ |
} |
else if (state_machine == 2 && i> 0 && thresh <autoCorr [i-1] && maxValue == autoCorr [i-1] && (autoCorr -autoCorr [i-1]) <= 0) |
{ |
periodEnd = i-1؛ |
state_machine = 3؛ |
numOfCycles = 2 ؛ |
samplePerPeriod = (periodEnd - 0)؛ |
signalFrequency2 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-تنظیم کننده ؛ // f = (2*fs)/(2*N) |
maxValue = 0؛ |
} |
در غیر این صورت (state_machine == 3 && i> 0 && thresh 0) // state_machine = 3 ، 3 دوره برای چرخه 1 ، 2 و 3 پیدا کنید |
{ |
maxValue = autoCorr ؛ |
} |
else if (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 ؛ |
samplePerPeriod = (periodEnd - 0)؛ |
signalFrequency3 = ((numOfCycles*SAMPLING_FREQUENCY) / (samplePerPeriod))-تنظیم کننده ؛ // f = (3*fs)/(3*N) |
} |
} |
//***************************************************************** |
// تجزیه و تحلیل نتایج |
//***************************************************************** |
if (samplePerPeriod == 0) |
{ |
Serial.println ("هوم ….. من مطمئن نیستم. آیا سعی می کنید مرا فریب دهید؟")؛ |
} |
دیگری |
{ |
// تابع وزنه را آماده کنید |
مجموع = 0 ؛ |
if (signalFrequency! = 0) |
{ |
مجموع = 1 ؛ |
} |
if (signalFrequency2! = 0) |
{ |
مجموع = مجموع + 2؛ |
} |
if (signalFrequency3! = 0) |
{ |
مجموع = مجموع + 3؛ |
} |
// فرکانس را با استفاده از تابع وزنی محاسبه کنید |
signalFrequencyGuess = ((1/مجموع) * signalFrequency) + ((2/مجموع) * signalFrequency2) + ((3/مجموع) * signalFrequency3)؛ // فرکانس وزنی را بیابید |
Serial.print ("یادداشتی که بازی کرده اید تقریبا") ؛ |
Serial.print (signalFrequencyGuess) ؛ // حدس فرکانس را چاپ کنید. |
Serial.println ("هرتز") ؛ |
// بر اساس حدس محدوده اکتاو را پیدا کنید |
octaveRange = 3 ؛ |
while (! (signalFrequencyGuess> = storageNoteFreq [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-storageNoteFreq ))) |
{ |
minValue = abs (signalFrequencyGuess-storageNoteFreq ) ؛ |
noteLocation = i؛ |
} |
} |
// چاپ یادداشت |
Serial.print ("فکر کنم بازی کردی")؛ |
if (noteLocation == 0) |
{ |
Serial.print ("C") ؛ |
} |
else if (noteLocation == 1) |
{ |
Serial.print ("C#")؛ |
} |
else if (noteLocation == 2) |
{ |
Serial.print ("D") ؛ |
} |
else if (noteLocation == 3) |
{ |
Serial.print ("D#")؛ |
} |
else if (noteLocation == 4) |
{ |
Serial.print ("E") ؛ |
} |
else if (noteLocation == 5) |
{ |
Serial.print ("F") ؛ |
} |
else if (noteLocation == 6) |
{ |
Serial.print ("F#")؛ |
} |
else if (noteLocation == 7) |
{ |
Serial.print ("G") ؛ |
} |
else if (noteLocation == 8) |
{ |
Serial.print ("G#") ؛ |
} |
else if (noteLocation == 9) |
{ |
Serial.print ("A") ؛ |
} |
else if (noteLocation == 10) |
{ |
Serial.print ("A#")؛ |
} |
else if (noteLocation == 11) |
{ |
Serial.print ("B") ؛ |
} |
Serial.println (octaveRange) ؛ |
} |
//***************************************************************** |
// اینجا متوقف شوید. برای راه اندازی مجدد ، دکمه تنظیم مجدد را در Arduino فشار دهید |
//***************************************************************** |
در حالی که (1) ؛ |
} |
view rawgistfile1.txt با ❤ توسط GitHub میزبانی شده است
مرحله 3: آشکارساز یادداشت موسیقی را راه اندازی کنید
Arduino Uno را با کد نوشته شده یا بارگذاری شده در Arduino IDE به رایانه وصل کنید. کد را در آردوینو کامپایل و بارگذاری کنید. مدار را نزدیک منبع موسیقی قرار دهید. توجه: در ویدئوی مقدماتی ، من از یک برنامه نصب شده روی رایانه لوحی همراه با بلندگوهای رایانه به عنوان منبع موسیقی خود استفاده می کنم. دکمه تنظیم مجدد در برد آردوینو را فشار دهید و سپس یک یادداشت را در منبع موسیقی پخش کنید. پس از چند ثانیه ، Musical Note Detector نت پخش شده و فرکانس آن را نمایش می دهد.
توصیه شده:
آشکارساز سطح آب: 7 مرحله
آشکارساز سطح آب: سنسور اولتراسونیک بر اساس اصول یک سیستم راداری کار می کند. سنسور اولتراسونیک می تواند انرژی الکتریکی را به امواج صوتی و بالعکس تبدیل کند. سنسور اولتراسونیک HC SR04 امواج فراصوت را با فرکانس 40 کیلوهرتز تولید می کند
آشکارساز حضور تخت زیگبی: 8 مرحله
آشکارساز حضور تخت زیگبی: مدتی است که بدنبال راهی برای تشخیص زمان خوابیدن در رختخواب بودم. این برای استفاده از این اطلاعات در Homeassistant است. با استفاده از این اطلاعات می توانم برای خاموش کردن چراغ ها در شب اتوماسیون انجام دهم یا به عنوان مثال یک سیستم هشدار را در خانه من فعال کنم
آشکارساز یادداشت های موسیقی آردوینو: 3 مرحله
آشکارساز یادداشت های موسیقی آردوینو: تشخیص نت های موسیقی از سیگنال صوتی به دلیل محدودیت حافظه و قدرت پردازشی به ویژه در آردوینو دشوار است. به طور کلی ، نت یک موج سینوسی خالص نیست که تشخیص را دشوار کند. اگر تبدیل فرکانسی va را در نظر بگیریم
آشکارساز دود IOT: آشکارساز دود موجود را با IOT به روز کنید: 6 مرحله (همراه با تصاویر)
آشکارساز دود IOT: آشکارساز دود موجود را با IOT به روز کنید: فهرست مشارکت کنندگان ، مخترع: Tan Siew Chin ، Tan Yit Peng ، Tan Wee Heng ناظر: دکتر Chia Kim Seng گروه مهندسی مکاترونیک و رباتیک ، دانشکده مهندسی برق و الکترونیک ، Universiti Tun حسین اونن مالزی. توزیع
نمایش موسیقی ساده موسیقی (lpt Led): 6 مرحله (همراه با تصاویر)
موسیقی ساده نمایش ساده (lpt Led): واقعاً ساده & amp؛ میله سبک ارزان ، تغذیه و کنترل از طریق کامپیوتر (از طریق پورت lpt). ساخت این دستگاه چیزی در حدود 10 تا 20 دلار برای شما هزینه خواهد داشت (من کابل plexi و lpt را رایگان داشتم ، بنابراین فقط 3 دلار برای چراغ مشعل و 3 دلار برای مهره و پیچ و مهره پرداخت کردم) = کشتن