در آموزش های قبلی به راهاندازی استپر موتور با آردوینو با استفاده از EasyDriver و ULN2003A پرداختیم. در این قسمت قصد داریم در مورد تولید صدا با آردوینو، تولید تن و پخش ملودی صحبت کنیم.
میلیونها نتیجه در Google برای عبارت «Arduino music project» وجود دارد و در این فصل نظر داریم که تکنیکهای صوتی Arduino و چند نمونه پروژه را معرفی کنیم. Arduino برای این ساخته نشده که یک synthesizer audio پیشرفته باشد، اما قطعاً میتواند از طریق یک وسیله خروجی مانند بلندگو، صدا تولید کند.
این فصل نشان میدهد چگونه نویز ایجاد کنید، صداهای از قبل ضبط شده را پخش کنید، چند خروجی ساده بسازید و حتی با synthesis sound پروژه هایی انجام دهید.
در ادامه دو پروژه معرفی شده است که با Arduino، مقداری کمی قطعه و خلاقیت زیاد میتوان ساخت:
اگر میخواهید از طریق یک بلندگو یا مبدل صوتی دیگر، تنهای صوتی تولید کنید، فرکانس و مدتزمان تن را مشخص کنید می بایست از تابع tone آردوینو استفاده کنید. اسکچ زیر تنی را پخش میکند که فرکانس آن توسط یک مقاومت متغیر (یا سنسور دیگر) که به ورودی آنالوگ 0 متصل است تنظیم میشود شکل ( 1 ) را ببینید:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
/* * Tone sketch * * Plays tones through a speaker on digital pin 9 * Frequency determined by values read from analog pin */ const int speakerPin = 9; // connect speaker to pin 9 const int pitchPin = A0; // pot that will determine the frequency of the tone void setup() { } void loop() { int sensor0Reading = analogRead(pitchPin); // read input to set frequency // map the analog readings to a meaningful range int frequency = map(sensor0Reading, 0, 1023, 100, 5000); // 100 Hz to 5 kHz int duration = 250; // how long the tone lasts tone(speakerPin, frequency, duration); // play the tone delay(1000); // pause one second } |

شکل(1) اتصالات اسکچ Tone
تابع tone میتواند تا سه پارامتر بگیرد: پایهای که بلندگو به آن متصل است، فرکانسی که باید پخش شود (بر حسب هرتز) و مدتزمانی (بر حسب میلیثانیه) که نت باید نواخته شود. پارامتر سوم اختیاری است. اگر آن را حذف کنید، نت ادامه پیدا میکند تا زمانی که فراخوانی tone جدید دیگری انجام شود و یا تابع noTone اجرا شود. مقدار فرکانس در خط زیر به مقادیر معقول برای فرکانسهای صوتی نگاشت (map) میشود:
|
1 |
int frequency = map(sensor0Reading, 0, 1023, 100, 5000); //100 Hz to 5 kHz |
این تغییر، از یک مقاومت متغیر دوم (پتانسیومتر پایین-راست در شکل ( 1 )) برای تعیین مدتزمان تن استفاده میکند:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
const int speakerPin = 9; // connect speaker to pin 9 const int pitchPin = A0; // input that determines frequency of the tone const int durationPin = A1; // input to determine the duration of the tone void setup() { } void loop() { int sensor0Reading = analogRead(pitchPin); // read input for frequency int sensor1Reading = analogRead(durationPin); // read input for duration // map the analog readings to a meaningful range int frequency = map(sensor0Reading, 0, 1023, 100, 5000); // 100Hz to 5kHz int duration = map(sensor1Reading, 0, 1023, 100, 1000); // dur 0.1-1 second tone(speakerPin, frequency, duration); // play the tone delay(duration); // wait for the tone to finish } |
تغییر دیگر این است که یک کلید (Switch) اضافه کنید تا تنها فقط زمانی تولید شوند که کلید فشرده شود. در setup زیر یک ورودی را با مقاومتهای Pull-up فعال کنید. همچنین باید inputPin را تعریف کنید تا پایهی موردنظرتان را مشخص کند:
|
1 |
pinMode(inputPin, INPUT_PULLUP); |
کد loop را طوری تغییر دهید که توابع tone و delay فقط زمانی فراخوانی شوند که کلید فشرده شده باشد:
|
1 2 3 4 5 |
if (digitalRead(inputPin) == LOW) // read input value { tone(speakerPin, frequency, duration); // play the tone delay(duration); //wait for the tone to finish } |
تقریباً از هر مبدل صوتی میتوان برای تولید صدا با آردوینو استفاده کرد. بلندگوهای کوچک و مبدلهای Piezo بسیار خوب کار میکنند. Piezoها جریان بسیار کمی میکشند (به دلیل مقاومت بسیار بالا )، بنابراین میتوان آنها را مستقیماً به پایه آردوینو وصل کرد. بلندگوها معمولاً مقاومت بسیار کمتری دارند و برای محدود کردن جریان به یک مقاومت نیاز دارند. قطعات لازم برای ساخت مداری که در شکل ( 3 ) نشان داده شده است باید بهراحتی قابل تهیه باشند.
فرض کنید میخواهید با آردوینو یک ملودی ساده بنوازد.
میتوانید از تابع tone که در بخش قبلی توضیح داده شد برای پخش صداهای متناظر با نتهای یک ساز موسیقی استفاده کنید. اسکچ زیر از tone برای نواختن رشتهای از نتها استفاده میکند همان قطعهی «Hello world» یادگیری پیانو، یعنی «Twinkle, Twinkle Little Star»:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
/* * Twinkle sketch * Plays "Twinkle, Twinkle Little Star" * Speaker is connected to digital pin 9 */ const int speakerPin = 9; // connect speaker to pin 9 char noteNames[] = {'C','D','E','F','G','a','b'}; unsigned int frequencies[] = {262,294,330,349,392,440,494}; const byte noteCount = sizeof(noteNames); // number of notes (7 here) //notes, a space represents a rest char score[] = "CCGGaaGFFEEDDC GGFFEEDGGFFEED CCGGaaGFFEEDDC "; const byte scoreLen = sizeof(score); // the number of notes in the score void setup() { } void loop() { for (int i = 0; i < scoreLen; i++) { int duration = 333; // each note lasts for a third of a second playNote(score[i], duration); // play the note delay(duration/10); // slight pause to separate the notes } delay(4000); // wait four seconds before repeating the song } void playNote(char note, int duration) { // play the tone corresponding to the note name for (int i = 0; i < noteCount; i++) { // try and find a match for the noteName to get the index to the note if (noteNames[i] == note) // find a matching note name in the array tone(speakerPin, frequencies[i], duration); // play the note } // if there is no match then the note is a rest, so just do the delay delay(duration); } |
noteNames آرایهای از کاراکترها برای شناسایی نتها در یک پارتیتور (Score) است. هر درایهی این آرایه با فرکانسی که در آرایهی frequencies تعریف شده مرتبط است. برای مثال، نت C (اولین درایه در آرایهی noteNames) فرکانس ۲۶۲ هرتز دارد (اولین درایه در آرایهی frequencies).
score آرایهای از نتهاست که نام نتهایی را که میخواهید بنوازید نمایش میدهد (نتهای با حروف کوچک یک اکتاو بالاتر از نتهای با حروف بزرگ هستند):
|
1 2 |
// a space represents a rest char score[] = "CCGGaaGFFEEDDC GGFFEEDGGFFEED CCGGaaGFFEEDDC "; |
هر کاراکتری در score که با کاراکتری در آرایهی noteNames تطابق داشته باشد، باعث نواختهشدن آن نت میشود. کاراکتر فاصله (Space) بهعنوان سکوت (Rest) استفاده میشود، اما هر کاراکتری که در noteNames تعریف نشده باشد نیز یک سکوت تولید میکند (هیچ نتی نواخته نمیشود).
اسکچ، تابع playNote را با هر کاراکتر در score و یک مدتزمان یکسومِ ثانیه برای نتها فراخوانی میکند. تابع playNote در آرایهی noteNames جستوجو میکند تا یک تطابق پیدا کند و از درایهی متناظر در آرایهی frequencies برای بهدستآوردن فرکانسی که باید نواخته شود استفاده میکند.
هر نت مدتزمان یکسانی دارد. اگر میخواهید طول هر نت را مشخص کنید، میتوانید کد زیر را به اسکچ اضافه کنید:
|
1 2 3 4 5 |
byte beats[scoreLen] = {1,1,1,1,1,1,2, 1,1,1,1,1,1,2,1, 1,1,1,1,1,1,2, 1,1,1,1,1,1,2,1, 1,1,1,1,1,1,2, 1,1,1,1,1,1,2}; byte beat = 180; // beats per minute for eighth notes unsigned int speed = 60000 / beat; // the time in ms for one beat |
beats آرایهای است که طول هر نت را نشان میدهد: ۱ یک نت چنگ (Eighth note)، ۲ یک نت سیاه (Quarter note) و همینطور تا آخر است. beat تعداد ضربها در دقیقه است. speed محاسبهای است که تعداد ضرب در دقیقه را به مدتزمانی بر حسب میلیثانیه تبدیل میکند.
تنها تغییر در کد loop این است که مدتزمان را طوری تنظیم کنید که از مقدار موجود در آرایهی beats استفاده کند. خط زیر:
|
1 |
int duration = 333; // each note lasts for a third of a second |
را به این تغییر دهید:
|
1 |
int duration = beats[i] * speed; // use beats array to determine duration |
آموزش راهاندازی استپر موتور با آردوینو: استفاده از...
من کاپیتان آردوینو، اسمم میلاده و اینجا هستم تا تجربیاتم در رابطه با آردوینو رو با شما به اشتراک بزارم!
سیسوگ با افتخار فضایی برای اشتراک گذاری دانش شماست. برای ما مقاله بنویسید.