Ana içeriğe geç

Proje 05 - Buzzer

Giriş

Bu projede Arduino'nun nasıl ses çıkarabileceğini öğreneceksin. Tabii ki profesyonel bir müzik aleti kadar kaliteli olmayacak ama... internetin en ünlü şarkısını çalmaya yetecek kadar iyi! 🎵

Yeni Kavramlar

Constantlar (const)

const, değeri değişmeyecek sabitler tanımlamak için kullanılır. const int DO_3 = 262; şeklinde tanımlandıktan sonra DO_3'ün değeri program boyunca 262 olarak kalır. Nota frekansları gibi sabit değerler için idealdir.

Niye değişken olarak tanımlamak yerine bunu yapayım diye merak ediyorsan, arduino'da RAM, yani programın çalışırken kullandığı hafıza çok sınırlıdır. Bu şekilde tanımlanan değerler RAM'de hiç yer kaplamaz.

Diziler (array)

Diziler, aynı tipte birden fazla değeri tek bir değişken altında saklar. int melodi[] şeklinde tanımlanır. İlk eleman 0. sırada, ikinci eleman 1. sırada... şeklinde numaralanır, yani diziler söz konusu olduğunda saymaya alıştığın gibi 1'den değil, 0'dan başlarsın.

Burada melodi[] dizisi, çalmak istediğimiz notaların frekanslarını sırayla tutuyor.

Dizi İndeksleme

Köşeli parantezlerle bir dizinin elemanlarına erişebilirsin. melodi[0] ilk elemanı, melodi[i] i. sıradaki elemanı verir. (Unutma ki, dizilerde saymaya hep 0'dan başlıyoruz). Dizinin istediğimiz elemanını seçmek için kullanılır.

for Döngüsü

For döngüsü, belirli sayıda tekrar yapılacak işlemler için kullanılır. Üç bölümden oluşur ve parantez içinde noktalı virgülle ayrılır:

1
2
3
for (int i = 0; i < notaSayisi; i++) {
  ...
}
  1. Başlangıç (int i = 0): Döngü başlarken bir kez çalışır. Burada sayaç değişkeni i'ye sıfır değerini atıyoruz.
  2. Koşul (i < notaSayisi): Her döngüde kontrol edilir. Koşul doğru olduğu sürece döngü devam eder. Bu örnekte i, notaSayısı değişkeninin değerinden küçük olduğu sürece döngü devam eder.
  3. Artış (i++): Her döngü tamamlandıktan sonra çalışır. Burada i değişkenini 1 artırarak bir sonraki elemana geçmemizi sağlar.

Bu sayede melodi dizisindeki tüm notaları (0'dan notaSayisi-1'e kadar) için küme parantezleri {} arasındaki kod bloğu çalışıyor.

tone() Fonksiyonu

tone() fonksiyonu, buzzerdan belirtilen frekansta ses çıkarır. tone(pin, frekans, süre) şeklinde kullanılır.

noTone() Fonksiyonu

noTone() fonksiyonu, buzzerdaki sesi durdurur.

Matematik İşlemleri

Çarpma (*) operatörü, sayısal değerleri çarpmak için kullanılır. sureler[i] * 0.3 gibi ifadelerle notalar arası boşluklar hesaplanır.

Elektronik

Buzzer devresi

Devrede Q103 olarak işaretlenmiş eleman bir NPN transistör. LED devresinde gördüğün transistörle aynı çalışma prensibi var - elektrikle açılıp kapanabilen bir anahtar gibi düşünebilirsin.

Arduino'nun 3 numaralı dijital pini, R284 direnci (2KΩ) üzerinden transistörün baz bacağına bağlı. R302 direnci (10KΩ) ise bir "pull-down" direnci olarak görev yapıyor - Arduino pini aktif olmadığında transistörün bazını sıfır volta çekerek transistörün tamamen kapalı kalmasını sağlıyor.

Arduino'nun 3 numaralı pininden HIGH (5V) sinyal geldiğinde, R284 üzerinden transistörün bazına akım gider ve transistör iletime geçer. Bu durumda R303 direnci ve buzzer üzerinden akım akmaya başlar. Buzzer'ın içindeki piezoelektrik kristal bu akımla titreşerek ses çıkarır.

D004 olarak işaretlenmiş 1N4148 diyodu, buzzer'ın bacakları arasına ters olarak bağlanmış bir koruma diyodu. Buzzer gibi bobinli elemanlar aniden kapatıldığında ters yönde yüksek gerilim üretebilir. Bu diyot o zararlı gerilimi sönümleyerek transistörü korur.

C19 kondansatörü (100nF) güç kaynağındaki elektrriksel gürültüleri filtreleyerek daha temiz bir ses elde edilmesini sağlar.

Buzzer'dan çıkacak sesin frekansı, Arduino'nun tone() fonksiyonuyla belirlenir. Bu fonksiyon pin 3'e belirlenen frekansta HIGH-LOW sinyalleri göndererek buzzer'ı o frekansla titreştirir ve böylece istenen notayı çalar.

Kod

  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
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
// Nota frekanslarını constant olarak tanımlayalım
const int NOTE_GS3 = 208;
const int NOTE_AS3 = 233;
const int NOTE_B3 = 247;
const int NOTE_C4 = 262;
const int NOTE_CS4 = 277;
const int NOTE_DS4 = 311;   
const int NOTE_F4 = 349;
const int NOTE_GS4 = 415;  
const int NOTE_AS4 = 466; 
const int NOTE_B4 = 494;
const int NOTE_C5 = 523; 
const int NOTE_CS5 = 554;
const int NOTE_DS5 = 622; 
const int NOTE_F5 = 698;
const int NOTE_FS5 = 740;
const int NOTE_GS5 = 831; 

// Es (sessizlik)
const int ES = -1;

/*
Diziler (arrays), aynı tipte birden fazla değeri bir arada saklamamızı sağlar.
Burada melodi[] dizisi, çalmak istediğimiz notaların frekanslarını sırayla tutuyor.
Her bir nota, dizinin bir elemanı olarak saklanıyor. Dizideki ilk eleman 0. sırada,
ikinci eleman 1. sırada... şeklinde devam eder.
*/

int melodi[] =
{ NOTE_AS4, NOTE_AS4, NOTE_GS4, NOTE_GS4,
  NOTE_F5, NOTE_F5, NOTE_DS5, NOTE_AS4, NOTE_AS4, NOTE_GS4, NOTE_GS4, NOTE_DS5, NOTE_DS5, NOTE_CS5, NOTE_C5, NOTE_AS4,
  NOTE_CS5, NOTE_CS5, NOTE_CS5, NOTE_CS5,
  NOTE_CS5, NOTE_DS5, NOTE_C5, NOTE_AS4, NOTE_GS4, NOTE_GS4, NOTE_GS4, NOTE_DS5, NOTE_CS5,
  NOTE_AS4, NOTE_AS4, NOTE_GS4, NOTE_GS4,
  NOTE_F5,  NOTE_F5, NOTE_DS5, NOTE_AS4, NOTE_AS4, NOTE_GS4, NOTE_GS4, NOTE_GS5, NOTE_C5, NOTE_CS5, NOTE_C5, NOTE_AS4,
  NOTE_CS5, NOTE_CS5, NOTE_CS5, NOTE_CS5,
  NOTE_CS5, NOTE_DS5, NOTE_C5, NOTE_AS4, NOTE_GS4, ES, NOTE_GS4, NOTE_DS5, NOTE_CS5, ES
};

/*
sureler[] dizisi, her notanın ne kadar süre çalınacağını milisaniye cinsinden tutuyor.
melodi[] dizisindeki her nota ile aynı sıradaki süre birbirine karşılık gelir.
Örneğin: melodi[0] notası, sureler[0] süre kadar çalınır.
*/
int sureler[] =
{ 100, 100, 100, 100,
  300, 300, 600, 100, 100, 100, 100, 300, 300, 300, 100, 200,
  100, 100, 100, 100,
  300, 300, 300, 100, 200, 200, 200, 400, 800,
  100, 100, 100, 100,
  300, 300, 600, 100, 100, 100, 100, 300, 300, 300, 100, 200,
  100, 100, 100, 100,
  300, 300, 300, 100, 200, 200, 200, 400, 800, 400
};

int buzzerPin = 3;
int notaSayisi = 59; // Toplam nota sayısı

void setup() {
  /*
  pinMode() fonksiyonunu kullanarak, Arduino'nun pinlerini giriş veya 
  çıkış olarak ayarlayabilirsin. Buzzer için pin 3'ü çıkış olarak ayarlıyoruz.
  */
  pinMode(buzzerPin, OUTPUT);
}

void loop() {
  /*
  for döngüsü, aynı işlemi tekrar tekrar yapmamızı sağlar.
  Bu döngü 3 kısımdan oluşur:
  1. Başlangıç: int i = 0 (i değişkenini 0'dan başlat)
  2. Koşul: i < notaSayisi (i, toplam nota sayısından küçük olduğu sürece devam et)
  3. Artış: i++ (her döngüde i'yi 1 artır)

  Bu sayede melodi dizisindeki tüm notaları sırayla çalmış oluyoruz.
  */
  for (int i = 0; i < notaSayisi; i++) {
    if (melodi[i] > 0) {
      /*
      tone() fonksiyonu buzzer'dan ses çıkartmamızı sağlar.
      3 parametre alır:
      1. buzzerPin: Ses çıkacak pin numarası
      2. melodi[i]: Çalınacak notanın frekansı (Hz cinsinden)
      3. sureler[i]: Notanın çalınma süresi (milisaniye)

      Frekans ne kadar yüksekse, ses o kadar tiz olur.
      Örneğin: DO_3 (262 Hz) → RE_3 (294 Hz) daha tizdir.
      */
      tone(buzzerPin, melodi[i], sureler[i]);
    } else {
      /*
      Eğer melodi[i] negatif bir değerse (ES = -1), bu sessizlik demektir.
      noTone() fonksiyonu buzzer'ı susturur.
      */
      noTone(buzzerPin);
    }

    /*
    ÖNEMLİ: tone() fonksiyonu ses çalmaya başlar ama kodun devam etmesini beklemez!
    Eğer delay() koymazsak, kod hemen bir sonraki notaya geçer ve her nota sadece 
    çok kısa bir süre (mikrosaniye) çalar. Bu durumda melodi çok hızlı geçer ve 
    tanınmaz hale gelir. delay(sureler[i]) ile her notanın belirlenen süre kadar 
    çalmasını sağlıyoruz.
    */
    delay(sureler[i]);

    /*
    Notayı temiz bir şekilde bitirmek için noTone() çağırıyoruz.
    Sonra kısa bir ara (delay(sureler[i] * 0.3)) vererek notalar 
    arasında boşluk bırakıyoruz. Bu, gerçek müzikte olduğu gibi 
    notaların birbirinden ayrılmasını sağlar.
    */
    noTone(buzzerPin);
    delay(sureler[i] * 0.3);
  }

  /*
  Melodi bittiğinde 2 saniye (2000 milisaniye) bekleriz.
  Bu sayede melodi tekrar çalmadan önce bir duraklama olur.
  */
  delay(2000);
}

Kodu nasıl Arduino'ya yüklerim?

Kiti USB kablosuyla bilgisayarına bağlayıp, Arduino IDE penceresinde bulunan Upload butonuna basarak kodu yükleyip çalıştırabilirsin.

Kod çalıştığında buzzer'dan çalan tanıdık bir melodi duyacaksın.

Olmadı mı?

Eğer bu süreçte bir problemle karşılaşırsan Sorun giderme kısmına bir göz at.

Böylece buzzer'dan ses çıkartmayı ve for döngülerini kullanmayı öğrenmiş oldun. Bu projede öğrendiklerinle aşağıdakileri yapabilir misin?

  1. Butonla beraber kullanarak butona basıldığında bu melodiyi çalan bir kapı zili yapabilir misin?
  2. Potansiyometre ile melodimin çalma hızını kontrol edebilir misin?1

  1. delay() değerlerini birşeyle çarpman gerekecek.