Hayatımızdaki birçok olgu dijitalleştirilmiştir. Bunlardan biri de seslerdir. Sesin tonu ve şiddeti elektriksel olarak işlenebilmektedir. Yani notaları elektronik olarak çıkarabiliriz. Müziği oluşturan seslerin en küçük birimine nota denir. Her notanın bir frekansı ve şiddeti vardır. Yazacağımız kodlarla frekans ve şiddet uygulayarak hangi notanın çalınmasını ve ne kadar sürmesi gerektiğini ayarlayabiliriz.
Bu projede Picobricks ile bir şarkının melodisini buzzer modülünü kullanarak çalacak, potansiyometre modülü ile ritmi ayarlayabilecek bir müzik sistemi hazırlayacağız. Programlama terminolojisinde önemli bir yere sahip değişken kullanımını da bu projede öğreneceksin.
Proje Detayları ve Algoritma
Notalarını bildiğimiz her şarkıyı Picobricks ile çalabilirsin. Şarkıyı başlatmak için buton-LED modülünü, şarkının hızını ayarlayabilmek için potansiyometre modülünü notaları çalabilmek için buzzer modülünü kullanacağız.
Potansiyometre analog giriş modülüdür. Değişken dirençtir. Üzerinden geçen akım miktarı çevrildikçe bir musluğun açılıp kapatılması gibi artar ve azalır. Bu akım miktarını kodlarla kontrol ederek şarkının hızını ayarlayacağız. Buzzer’lar üzerlerinden geçen akımın şiddetine göre ses seviyelerini, gerilim frekansına göre ses tonlarını değiştirmektedirler. Microblocks ile kolayca buzzer modülünden istediğimiz notaları, tonlarını ve sürelerini ayarlayarak kodlayabiliriz.
Projede butona basılma durumunu kontrol edeceğiz. Butona basıldığında melodinin çalmaya başlamasını sağlayacağız. Melodinin çalması sırasında notaların çalınma sürelerini aynı oranda artırıp azaltabilmek için rithm adında bir değişken kullanacağız. Picobricks başladıktan sonra kullanıcının potansiyometre ile ister melodi çalarken ister çalmadan önce rithm değişkenini ayarlayabilmesini sağlayacağız. Picobricks açık olduğu sürece potansiyometre değerini (0-1023) 128’e bölüp rithm değişkene atayacağız. Değişkenler, kullanıcı tarafından ya da sensörler tarafından değiştirilebilecek değerleri kodlarımızda kullanmak istediğimizde kullandığımız veri yapılarıdır. Kullanıcı şarkıyı başlatmak için butona bastığında ise notaların süreleri rithm değişkenine göre hesaplanan süre boyunca çalmasını sağlayacak nota kodlarını hazırlayacağız.
Bağlantı Şeması
Projenin MicroBlocks ile Kodlanması
Picobricks’in başlar başlamaz kodları sürekli olarak çalıştırması için Control kategorisinden “When started” , altına “forever” bloğunu sürükle. Kullanıcının hız ayarını ekranda gösterebilmek için OLED ekran kütüphanesini ekle ve ekranı başlatan kodu forever bloğunun öncesine yerleştir. Variables kategorisinde Add a variable butonuna tıkla. Açılan diyalog penceresine rithm yazıp onayladığında rithm değişkeni oluşturulur.
Variables kategorisindeki set OledReady to 0 bloğunun içindeki siyah üçgene tıklayarak değişken adını rithm olarak seç. Ardından forever bloğunun içine yerleştir. Potansiyometreden okunacak değeri 128’e bölerek nota süresinin hesaplanmasında kullanacağız. Operators kategorisindeki 10/2 bloğunu değişken bloğuna yerleştirip paydayı 128 yap. Potansiyometreyi okuyabilmek için PicoBricks kategorisindeki PicoBricks potentiometer bloğunu bölme işlemi bloğundaki 10 alanına sürükle. OLED kategorisindeki write bloğunu al. Hello alanına Data kategorisinden Join bloğun yerleştirip rithm değişkenini yerleştir.
Picobricks üzerindeki butona basılma durumunun sürekli denetlenmesi için Control kategorisinden when bloğunu sürükle. İçine Picobricks button bloğunu yerleştir.
Tone kütüphanesini çalışma alanına ekle.
when bloğunun altına bloğunu ekle. C nota adı, 0 nota tonunu, 500 ise çalınma süresini ayarlamanızı sağlar. Notaların çalınma sürelerini rithm değişkenine bölerek belirleyeceğiz. play note bloğunun 500 alanına operators kategorisinden 10/2 bloğunu sürükle.
rithm değişkeni en düşük 0 değeri almaktadır. Bir sayının 0’a bölümü sonsuz olacağı için rithm değerine bir ekleyeceğiz. Bölme işlemindeki payda(2) alanına operators kategorisindeki “10+2” toplam bloğunu sürükle. 10 alanına rithm değişkenini yerleştir ve 2 rakamını 1 olarak değiştir. play note bloğunun üzerinde sağ tıklayıp duplicate ve duplicate all seçenekleriyle şarkındaki nota sayısınca blokları çoğalt.
Notaların adlarını sırasıyla yaz. Her notanın varsayılan vuruş sürelerini de bölme operatörünün 10 alanına yaz 1000 değeri tam vuruş, 500 değeri yarım vuruş 250 değer ise çeyrek vuruş süresini ifade eder. when bloğundan hemen sonra OLED kategorisinden write bloğunu ekleyerek kullanıcıya Now Playing ifadesini gösteriyoruz. Melodi bittiğinde ise ekranı temizleyeceğiz.
Bu notlar melodinin nakarat kısmıdır. O yüzden iki defa tekrar etmesini ve ardından ekranı temizlemesini kodlamalıyız. Sadece notların olduğu kısmı control kategorisinden repeat 10 bloğunu alarak içine yerleştir. Tekrar sayısını 2 olarak ayarla. Döngüden sonraya ise OLED kategorisinden clear kodunu ekle.
Kodları çalıştırdığında Picobricks üzerindeki potansiyometre ile melodi hızını belirle. Melodiniz çalarken ya da çalmadan önce potansiyometreyi çevirerek melodinin hızına hükmet.
Projenin MicroBlocks kodlarına erişmek içintıkla.
Proje Görseli
Proje Önerisi
Projeni daha görsel hale getirmek için çalınan notaya göre farklı renkte LED yakabilir, nota isimlerini ve çalma hızını OLED ekranda gösterebilirsin.
Projenin Micropython Kodları
from machine import Pin,PWM,ADC
from utime import sleep
button= Pin(10,Pin.IN,Pin.PULL_DOWN)
pot=ADC(Pin(26))
buzzer= PWM(Pin(20))
global rithm
pressed = False
tones = {
"A3": 220,
"D4": 294,
"E4": 330,
"F4": 349
}
mysong = ["A3","E4","E4","E4","E4","E4","E4","F4","E4","D4","F4","E4"]
noteTime = [1,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,0.5,1]
def playtone(frequency):
buzzer.duty_u16(6000)
buzzer.freq(frequency)
def playsong(pin):
global pressed
if not pressed:
pressed = True
for i in range(len(mysong)):
playtone(tones[mysong[i]])
sleep(noteTime[i]/rithm+1)
buzzer.duty_u16(0)
button.irq(trigger=Pin.IRQ_RISING, handler=playsong)
while True:
rithm= pot.read_u16()
rithm= int(rithm/6400)+1
Projenin Arduino C kodları
#include <Wire.h>
#include "ACROBOTIC_SSD1306.h"
int buzzer = 20;
int button = 10;
int led = 7;
int La = 440;
int old_time = 0;
int now_time = 0;
int score = 0;
String string_score ;
void setup()
{
Wire.begin();
oled.init();
oled.clearDisplay();
pinMode(led,OUTPUT);
pinMode(buzzer,OUTPUT);
pinMode(button,INPUT);
Serial.begin(9600);
}
void loop()
{
oled.setTextXY(3,0);
oled.putString("Press the button");
oled.setTextXY(5,4);
oled.putString("TO START");
if (digitalRead(button) == 1){
for (int i=3;i>0;i--){
String string_i = String(i);
oled.clearDisplay();
oled.setTextXY(4,8);
oled.putString(string_i);
delay(1000);
}
oled.clearDisplay();
oled.setTextXY(4,6);
oled.putString("GO!!!");
int random_wait = random(1000, 5000);
delay(random_wait);
digitalWrite(led, HIGH);
old_time=millis();
while(!(digitalRead(button) == 1)){
now_time=millis();
score = now_time-old_time;
string_score = String(score);
}
digitalWrite(led, HIGH);
tone(buzzer, La);
delay (200);
noTone(buzzer);
oled.clearDisplay();
oled.setTextXY(1,4);
oled.putString("Press the");
oled.setTextXY(2,3);
oled.putString("RESET BUTON");
oled.setTextXY(3,3);
oled.putString("to Repeat!");
oled.setTextXY(6,3);
oled.putString("Score: ");
oled.setTextXY(6,9);
oled.putString(string_score);
oled.setTextXY(6,13);
oled.putString(" ms");
Serial.println(score);
delay(10000);
oled.clearDisplay();
}
}