Senin, 06 Maret 2017

Tutorial Belajar Arduino Part 10: Output Music

Buatlah Rangkaian dengan speaker 8 ohm atau 16 ohm. Speaker baru atau speaker bekas radio yang masih berfungsi bisa Anda gunakan.
1.        Sambungkan kaki positif speaker pada pin 9 board arduino
2.        Sambungkan kaki negatif pada GND pada board arduino
3.        Jika nanti suara yang dihasilkan terlalu nyaring, maka Anda bisa menambahkan resistor 100 — 1 k ohm pada kaki positif atau negatif speaker.


Musik adalah kumpulan nada, sehingga jika kita ingin membuat musik, maka kita bisa merangkai nada-nada sehingga alunannya enak didengar.
Pada Arduino kita bisa menggunakan fungsi tone() untuk membuat nada. Fungsi tone() memiliki 2 parameter inputan wajib dan 1 parameter tambahan. Cara menggunakan fungsi tone() yaitu:


tonepin, frekuensi, durasi); atau tonepin, frekuensi);

Parameter pin adalah pin yang disambungkan ke speaker, frekuensi adalah frekuensi yang digunakan, sedangkan durasi adalah lama nada berbunyi pada frekuensi tersebut.

Jika tanpa menginputkan durasi, maka nada akan dibunyikan hingga nada selanjutnya dijalankan atau ketika kita memberikan perintah noTone(). Sehingga kita bisa memanfaatkan delay untuk membuat nada yang panjang atau pendek.

Parameter durasi akan berguna ketika kita ingin membunyikan nada sambil menjalankan perintah lainnya. sebab jika kita menggunakan delay, maka kita harus menunggu delay selesai dahulu untuk menjalankan perintah selanjutnya.

Perintah noTone() berguna untuk menghentikan nada pada pin tertentu, sehingga kita bisa menggunakan perintah pin dengan format
noTone(pin);

Perintah noTone() akan berguna ketika kita menggunakan banyak speaker yang dikontrol oleh banyak pin. Sekedar catatan bahwa ketika kita menjalankan fungsi tone(), maka kita tidak bisa menggunakan fungsi PWM pada pin 3 dan pin 11. Oleh sebab itu, jika ingin menggunakan PWM dan fungsi tone(), sebaiknya Anda menggunakan pin lainnya untuk PWM.

Program pada Sketch berikut berfungsi untuk membuat tangga nada Do-Re-Mi kunci C. Silakan dicoba.

// Sketch Program Doremi
// tangga nada C
#define NOTE_C4 262 // DO
#define NOTE_D4 294 // RE
#define NOTE_E4 330 // MI
#define NOTE_F4 349 // FA
#define NOTE_G4 392 // SOL
#define NOTE_A4 440 // LA
#define NOTE_B4 494 // SI
#define NOTE_C5 523 // DO
// speaker ada di pin 9
 
const int pinSpeaker = 9;
void setup() {
pinMode(pinSpeaker, OUTPUT);
}
 
void loop() {
tone(pinSpeaker, NOTE_C4, 500);
delay(500);
tone(pinSpeaker, NOTE_D4, 500);
delay(500);
tone(pinSpeaker, NOTE_E4, 500);
delay(500);
tone(pinSpeaker, NOTE_F4, 500);
delay(500);
tone(pinSpeaker, NOTE_G4, 500);
delay(500);
tone(pinSpeaker, NOTE_A4, 500);
delay(500);
tone(pinSpeaker, NOTE_B4, 500);
delay(500);
tone(pinSpeaker, NOTE_C5, 500);
delay(500);
noTone(pinSpeaker);
delay(1000);
} 
 

Pada Sketch diatas, kita sudah mempraktekkan fungsi tone() dan me(). Di awal program ada bagian #define yang berfungsi untuk ^ganti variabel tersebut dengan nilai yang dituju. Misal, variabel 7E_C4 berarti isinya adalah angka 262.
Anda bisa mendapatkan informasinya di website Arduino. Sketch diatas sebenarnya bisa kita sederhanakan lagi cara penulisannya dengan membuat satu fungsi untuk menjalankan tone().

Membuat Fungsi
Dengan membuat fungsi, kita bisa mengurangi jumlah kode yang berulang-ulang. Dengan demikian, bisa mengurangi jumlah baris kode dan mempercepat pembuatan program. Sebelumnya kita sudah sering menggunakan fungsi bawaan Arduino, misal fungsi delay(), tone(), noToneQ, danpinMode(), digitalWrite(), analogWriteQ, dan analogRead().

Ketika membuat fungsi, kita harus menentukan tipe dari fungsi tersebut. Tipe fingsi bisa mengacu pada tipe-tipe data yang sudah ada, misal int, float, long, char, dst. Setiap fungsi harus memiliki nilai yang dikembalikan ke fungsi tersebut. maksudnya begini, jika kita membuat fungsi dengan tipe int (integer), artinya fungsi tersebut memiliki angka, fungsi tersebut harus memiliki value berupa integer. Jika tidak, maka akan error. Sama halnya ketika kita membuat satu variabel, maka variabel tersebut harus ada isinya (valuenya). Jika tidak ada valuenya, ya akan error juga. Fungsi juga sama dengan variabel, kecuali fungsi yang bertipe void.

Fungsi yang bertipe void tidak memiliki nilai kembalian, artinya fungsi tersebut hanya mejalankan perintah-perintah saja tanpa memiliki value sebagaimana fungsi dengan tipe char, int, float, dst. Untuk memberikan nilai kembalian untuk seuatu fungsi, maka bisa menambahkan perintah return. Perhatikan kedua fungsi berikut:

// fungsi bertipe integer
int customDelay(int x1, int x2){
 int myDelay = x1 * x2;
 return myDelay;
}
 
// fungsi bertipe void
void nyalakan_LED(int pin, int DELAY){
 digitalWrite(pin, HIGH);
 int timeDelay = customDelay(2, DELAY);
 delay(timeDelay);
}
 
Fungsi customDelay() bertipe integer dan mempunyai 2 buah parameter integer sebagai masukan. Value dari customDelay adalah hasil perkalian dari kedua parameter tersebut yang diambil dari variabel myDelay (return myDelay). Variabel yang di-return menjadi value fungsi haras memiliki tipe data yang sama dengan tipe fungsi tersebut. Dalam contoh di atas, fungsi customDelay adalah integer dan myDelay juga integer.

Fungsi nyalakan_LED() merupakan fungsi bertipe void sehingga fungsi itu tidak memiliki value, fungsi ini hanya mengeksekusi perintah di dalamnya. Fungsi ini memiliki 2 parameter, yaitu pin dan DELAY yang sama-sama integer. Dalam fungsi tersebut ada perintah untuk menyalakan led pada pin pin, kemudian nilai timeDelay diambil dari hasil perkalian di dalam fungsi customDelayQ. Perhatikan, value dari timeDelay diambil dari fungsi customDelay(). Yang paling penting, fungsi void tidak butuh return.

Mari kita mengubah Sketch sebelumnya agar lebih singkat.

// Sketch Program Doremi dengan fungsi
// tangga nada C
#define NOTE_C4 262 // DO
#define NOTE_D4 294 // RE
#define NOTE_E4 330 // MI
#define NOTE_F4 349 // FA
#define NOTE_G4 392 // SOL
#define NOTE_A4 440 // LA
#define NOTE_B4 494 // SI
#define NOTE_C5 523 // DO
// speaker ada di pin 9
const int pinSpeaker = 9;
void setup() {
 pinMode(pinSpeaker, OUTPUT);
}
 
void loop() {
 nada(NOTE_C4, 500);
 nada(NOTE_D4, 500);
 nada(NOTE_E4, 500);
 nada(NOTE_F4, 500);
 nada(NOTE_G4, 500);
 nada(NOTE_A4, 500);
 nada(NOTE_B4, 500);
 nada(NOTE_C5, 500);
 noTone(pinSpeaker);
 delay(1000);
}
 
void nada(int frek, int durasi){
 tone(pinSpeaker, frek, durasi);
 delay(durasi);
}
 
Pada Sketch ini, kode program lebih kita sederhanakan dengan membuat fungsi nada(). Sehingga kita tidak perlu memanggil fungsi delay berulang kali. Mungkin awalnya akan agak lebih kesulitan untuk memahami sebab kodenya tidak sekuensial.
Sketch Sketch Program Doremi dengan fungsi memiliki jumlah variasi hanya 8 nada, bisa Anda bayangkan jika musik yang akan Anda buat memiliki jumlah nada puluhan atau ratusa, kira-kira akan sepanjang apa program Anda?

Oleh sebab itu, Sketch Sketch Program Doremi dengan fungsi harus dibuat lebih fleksibel lagi. Caranya? Kita bisa memanfaatkan array sebagaimana pernah kita pelajari ketika membuat LED, apakah Anda masih ingat? Ada 2 contoh potongan lagu yang bisa menjadi gambaran bahwa ketika nadanya bertambah banyak, maka kerumitan akan semakin menantang.

Catatan untuk Sketch Program Twinke-twinkle dan Sketch Program Garuda Pancasila, Anda harus membuat file pitches.h atau mendownloadnya dulu dari di sini. Perhatikan pada Sketch Sketch Program Twinke-twinkle pada baris kedua, di sana ada perintah #include <pitches.h>, jadi Anda harus punya file pitches.h untuk menjalankan aplikasi tersebut.
 
Sketch Program Twinke-twinkle
// Sketch Program Twinke-twinkle
// referensi tangga nada
#include <pitches.h>
// speaker ada di pin 9
const int pinSpeaker = 9;
#define JUMLAH_NADA 15
const int daftar_nada[JUMLAH_NADA] = {
 NOTE_C4, NOTE_C4, NOTE_G4, NOTE_G4,
 NOTE_A4, NOTE_A4, NOTE_G4, NOTE_F4,
 NOTE_F4, NOTE_E4, NOTE_E4, NOTE_D4,
 NOTE_D4, NOTE_C4, 0
};
const int lama_beat = 300;
const int beats[JUMLAH_NADA] = {
 1, 1, 1, 1,
 1, 1, 2, 1,
 1, 1, 1, 1,
 1, 2, 4
};
void setup() {
 pinMode(pinSpeaker, OUTPUT);
}
void loop() {
 for(int i=0; i<JUMLAH_NADA; i++){
 if(nada[i] == 0){
 delay(beats[i] * lama_beat);
 }else{
 nada(daftar_nada[i], beats[i] * lama_beat);
 }
 // jeda antar nada
 noTone(pinSpeaker);
 delay(lama_beat / 2);
 }
}
void nada(int frek, int durasi){
 tone(pinSpeaker, frek, durasi);
 delay(durasi);
}
 

Sketch Program Garuda Pancasila
// Sketch Program Garuda Pancasila
// referensi tangga nada
#include <pitches.h>
// speaker ada di pin 9
const int pinSpeaker = 9;
#define JUMLAH_NADA 85
const int daftar_nada[JUMLAH_NADA] = {
 NOTE_G4, NOTE_G4, NOTE_C5, NOTE_C5, NOTE_D5, NOTE_D5, NOTE_E5, 0,
 NOTE_E5, NOTE_F5, NOTE_G5, NOTE_C5, NOTE_D5, NOTE_E5, NOTE_F5, NOTE_D5, 0,
 NOTE_G4, NOTE_G4, NOTE_D5, NOTE_D5, NOTE_E5, NOTE_E5, NOTE_F5, 0,
 NOTE_E5, NOTE_D5, NOTE_C5, NOTE_G4, NOTE_G4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_C5, 0,
 NOTE_C5, NOTE_C5, NOTE_C5, NOTE_A4, NOTE_C5, NOTE_F5, NOTE_G5, NOTE_A5, NOTE_G5, 0,
 NOTE_C5, NOTE_C5, NOTE_C5, NOTE_A4, NOTE_C5, NOTE_F5, NOTE_G5, NOTE_A5, NOTE_G5, 0,
 NOTE_G5, NOTE_A5, NOTE_G5, NOTE_F5, NOTE_E5, NOTE_D5, 0,
 NOTE_C5, NOTE_C5, NOTE_C5, NOTE_C5, NOTE_A4, NOTE_G4, 0,
 NOTE_C5, NOTE_C5, NOTE_C5, NOTE_C5, NOTE_D5, NOTE_E5, 0,
 NOTE_C5, NOTE_C5, NOTE_A5, NOTE_G5, NOTE_B4, NOTE_C5, 0
};
const int lama_beat = 300;
const int beats[JUMLAH_NADA] = {
 1, 1, 2, 2, 2, 2, 3, 1,
 1, 1, 2, 1, 1, 2, 2, 3, 1,
 1, 1, 2, 2, 2, 2, 3, 1,
 1, 1, 2, 1, 1, 2, 1, 1, 3, 1,
 1, 1, 2, 1, 1, 2, 1, 1, 3, 1,
 1, 1, 2, 1, 1, 2, 1, 1, 3, 1,
 2, 3, 1, 2, 2, 3, 1,
 1, 1, 1, 3, 1, 1, 1,
 1, 1, 1, 3, 1, 1, 1,
 2, 2, 2, 3, 1, 3, 0
};
void setup() {
 pinMode(pinSpeaker, OUTPUT);
}
void loop() {
 for(int i=0; i<JUMLAH_NADA; i++){
 if(nada[i] == 0){
 delay(beats[i] * lama_beat);
 }else{
 nada(daftar_nada[i], beats[i] * lama_beat);
 }
 // jeda antar nada
 noTone(pinSpeaker);
 delay(lama_beat / 2);
 }
}
void nada(int frek, int durasi){
 tone(pinSpeaker, frek, durasi);
 delay(durasi);
}


 Perhatikan, antara Sketch Program
Twinke-twinkle dan Program Garuda Pancasila hanya berbeda jumlah
nada, nada, dan beats-nya. Jadi program utama di dalam fungsi loop tidak ada
yang berubah. Kenapa? Karena program tersebut sudah fleksibel dengan adanya
fungsi dan bantuan array. Coba bayangkan jika kedua program tersebut dibuat secara
manual. Lumayan ribet tentunya.

Tidak ada komentar:

Posting Komentar