İzmir Marşı

UYARI! Bu yapılması zor bir projedir.

Sizde buzzer ile İzmir Marşı çalmak isterseniz işte kodlar, gerekenler ve şema!

  • Arduino Uno
  • Küçük Breadboard
  • 16×2 I2C LCD Ekran
  • 7x LED (2x Mavi, 2x Yeşil, 2x Sarı, 1x Kırmızı*)
  • 7x 220 Ohm Direnç
  • 1x Pasif Buzzer
  • Jumper Kablolar
İzmir marşı

ve kodlar… (UYARI! Bu kodun kullanılabilmesi için Türkçe LCD kütüphanesi kurulmalıdır.)

#include <Wire.h>
#include <LiquidCrystal_I2C.h> // Standart resmi kütüphane

// Standart nesne tanımı
LiquidCrystal_I2C lcd(0x27, 16, 2);

const int buzzerPin = 10;
const int potPin = A0;

// LED pinleri
const int ledD2 = 2;
const int ledD3 = 3;
const int ledD4 = 4;
const int ledD5 = 5;
const int ledD6 = 6;
const int ledD7 = 7;
const int ledD8 = 8;

// --------- FREKANSLAR ---------
#define NOTE_DO5 523
#define NOTE_RE5 587
#define NOTE_MI5 659
#define NOTE_FA5 698
#define NOTE_SOL5 784
#define NOTE_LA4 440
#define NOTE_LA5 880
#define NOTE_SI4 494
#define REST 0

// Özel Türkçe Karakter Çizimleri (LCD Hafızası İçin)
byte g_kucuk[] = { 0b01110, 0b00000, 0b01111, 0b10001, 0b10001, 0b01111, 0b00001, 0b01110 }; // ğ (\x00)
byte s_kucuk[] = { 0b01111, 0b10000, 0b10000, 0b01110, 0b00001, 0b01111, 0b00100, 0b00000 }; // ş (\x01)
byte i_buyuk[] = { 0b00100, 0b00000, 0b01110, 0b00100, 0b00100, 0b00100, 0b01110, 0b00000 }; // İ (\x02)
byte i_kucuk[] = { 0b00000, 0b00000, 0b01100, 0b00100, 0b00100, 0b00100, 0b01110, 0b00000 }; // ı (\x03)
byte c_kucuk[] = { 0b00000, 0b00000, 0b01110, 0b10000, 0b10000, 0b01110, 0b00100, 0b00000 }; // ç (\x04)
byte s_buyuk[] = { 0b01111, 0b10000, 0b10000, 0b01110, 0b00001, 0b01111, 0b00100, 0b00000 }; // Ş (\x05)
byte u_kucuk[] = { 0b01010, 0b00000, 0b10001, 0b10001, 0b10001, 0b10001, 0b01111, 0b00000 }; // ü (\x06)

// LED kontrol fonksiyonu
void ledControl(int freq) {
  digitalWrite(ledD2, LOW); digitalWrite(ledD3, LOW); digitalWrite(ledD4, LOW);
  digitalWrite(ledD5, LOW); digitalWrite(ledD6, LOW); digitalWrite(ledD7, LOW); digitalWrite(ledD8, LOW);

  if (freq == NOTE_DO5) digitalWrite(ledD2, HIGH);
  else if (freq == NOTE_RE5) digitalWrite(ledD3, HIGH);
  else if (freq == NOTE_MI5) digitalWrite(ledD4, HIGH);
  else if (freq == NOTE_FA5) digitalWrite(ledD5, HIGH);
  else if (freq == NOTE_SOL5) digitalWrite(ledD6, HIGH);
  else if (freq == NOTE_LA4 || freq == NOTE_LA5) digitalWrite(ledD7, HIGH);
  else if (freq == NOTE_SI4) digitalWrite(ledD8, HIGH);
}

// Özel kodları ve normal harfleri tek tek sayarak uzunluk bulan fonksiyon
int turkceKarakterUzunlugu(String metin) {
  int uzunluk = 0;
  for (unsigned int i = 0; i < metin.length(); i++) {
    if ((byte)metin[i] == 0xC4 || (byte)metin[i] == 0xC5 || (byte)metin[i] == 0xC3) {
      i++; // UTF-8 çoklu bayt karakterini tek say
    }
    uzunluk++;
  }
  return uzunluk;
}

// Türkçe Kelimeleri Ekrana Basan Fonksiyon
void lcdYaz(String metin) {
  for (unsigned int i = 0; i < metin.length(); i++) {
    byte ilkBayt = (byte)metin[i];
    if (ilkBayt == 0xC4 || ilkBayt == 0xC5 || ilkBayt == 0xC3) {
      byte sonraki = (byte)metin[i + 1];
      
      if (ilkBayt == 0xC4 && sonraki == 0x90) lcd.write(2);      // İ
      else if (ilkBayt == 0xC4 && sonraki == 0x9F) lcd.write(0); // ğ
      else if (ilkBayt == 0xC4 && sonraki == 0xB1) lcd.write(3); // ı
      else if (ilkBayt == 0xC5 && sonraki == 0x91) lcd.write(1); // ş
      else if (ilkBayt == 0xC5 && sonraki == 0x90) lcd.write(5); // Ş
      else if (ilkBayt == 0xC3 && sonraki == 0xA7) lcd.write(4); // ç
      else if (ilkBayt == 0xC3 && sonraki == 0xBC) lcd.write(6); // ü
      
      i++; 
    } else {
      lcd.print(metin[i]);
    }
  }
}

void setup() {
  pinMode(buzzerPin, OUTPUT);
  pinMode(ledD2, OUTPUT); pinMode(ledD3, OUTPUT); pinMode(ledD4, OUTPUT);
  pinMode(ledD5, OUTPUT); pinMode(ledD6, OUTPUT); pinMode(ledD7, OUTPUT); pinMode(ledD8, OUTPUT);
  pinMode(potPin, INPUT);

  ledControl(REST);

  lcd.init();
  lcd.backlight();

  // Karakter çizimlerini LCD hafıza slotlarına (0-6) yükle
  lcd.createChar(0, g_kucuk);
  lcd.createChar(1, s_kucuk);
  lcd.createChar(2, i_buyuk);
  lcd.createChar(3, i_kucuk);
  lcd.createChar(4, c_kucuk);
  lcd.createChar(5, s_buyuk);
  lcd.createChar(6, u_kucuk);

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.write(2); // İ
  lcdYaz("zmir Mar");
  lcd.write(1); // ş
  lcdYaz("ı");
  delay(1000);
  lcd.clear();
}

void loop() {
  // İlk kelimenin "Yaşa" olarak tam görünmesi için hece basamakları nota vuruşlarına göre kusursuzlaştırıldı
  const char* heceler[] = {
    "", "iz", "mir'", "in ", "dağ", "la", "rın", "da ", "çi", "çek", "ler ", "açar ", // 1. blok (12 nota)
    "", "iz", "mir'", "in ", "dağ", "la", "rın", "da ", "çi", "çek", "ler ", "açar ", // 2. blok (12 nota)
    "Al", "tın ", "g\x06", "ne\x01 ", "or", "da ", "sır", "ma", "lar ", "sa", "çar ",   // 3. blok (11 nota)
    "Al", "tın ", "g\x06", "ne\x01 ", "or", "da ", "sır", "ma", "lar ", "sa", "çar ",   // 4. blok (11 nota)
    "Bo", "zul", "mu\x01 ", "d\x06\x01", "man", "lar ", "yel ", "gi", "bi ", "ka", "çar ", // 5. blok (11 nota)
    "Ya", "\x01""a ", "MUS", "TA", "FA ", "KE", "MAL ", "PA", "\x05""A ", "ya", "\x01""a!" // 6. blok (11 nota) -> Toplam: 67 eleman
  };

  // Melodi notası hesaplama
  int melody[] = {
    REST,  50,  NOTE_LA4,150, NOTE_MI5,150, NOTE_MI5,150, NOTE_MI5,150, NOTE_MI5,150, NOTE_MI5,150,
    NOTE_FA5,150, NOTE_MI5,150, NOTE_RE5,150, NOTE_FA5,300, NOTE_MI5,400,
    REST,  50,  NOTE_LA4,150, NOTE_MI5,150, NOTE_MI5,150, NOTE_MI5,150, NOTE_MI5,150, NOTE_MI5,150,
    NOTE_FA5,150, NOTE_MI5,150, NOTE_RE5,150, NOTE_FA5,300, NOTE_MI5,400,
    NOTE_MI5,150, NOTE_LA5,150, NOTE_SOL5,150, NOTE_FA5,150, NOTE_MI5,150, NOTE_RE5,150,
    NOTE_MI5,150, NOTE_RE5,150, NOTE_DO5,150, NOTE_SI4,150, NOTE_DO5,400,
    NOTE_DO5,150, NOTE_MI5,150, NOTE_RE5,150, NOTE_DO5,150, NOTE_SI4,150, NOTE_LA4,150,
    NOTE_DO5,150, NOTE_SI4,150, NOTE_LA4,150, NOTE_SOL5,150, NOTE_LA4,400,
    NOTE_MI5,150, NOTE_LA5,150, NOTE_SOL5,150, NOTE_FA5,150, NOTE_MI5,150, NOTE_RE5,150,
    NOTE_MI5,150, NOTE_RE5,150, NOTE_DO5,150, NOTE_SI4,150, NOTE_DO5,400,
    NOTE_DO5,150, NOTE_MI5,150, NOTE_RE5,150, NOTE_DO5,150, NOTE_SI4,150, NOTE_LA4,150,
    NOTE_DO5,150, NOTE_SI4,150, NOTE_LA4,150, NOTE_SOL5,150, NOTE_LA4,400
  };
  
  // Tam dinamik hesaplama
  int notes = sizeof(melody) / sizeof(melody[0]) / 2; 

  int satir = 0;       
  int sutun = 0;       

  for (int i = 0; i < notes; i++) {
    int potValue = analogRead(potPin);
    float hizCarpani = map(potValue, 0, 1023, 50, 250) / 100.0;

    int freq = melody[i * 2];  
    int dur  = melody[i * 2 + 1];  
      
    int calmaSuresi = dur * hizCarpani;  
    int beklemeSuresi = calmaSuresi * 1.3;  

    String eklenecekHece = heceler[i];
    int heceUzunluk = turkceKarakterUzunlugu(eklenecekHece);

    // Her blok (satır) geçişinde ekranı yenile
    if (i == 12 || i == 24 || i == 35 || i == 46 || i == 57) {
      lcd.clear();
      satir = 0;
      sutun = 0;
    }

    // Satır sonu taşma kontrolü
    if (sutun + heceUzunluk > 16) {
      if (satir == 0) {
        satir = 1;
        sutun = 0;
      } else {
        lcd.clear();
        satir = 0;
        sutun = 0;
      }
    }

    lcd.setCursor(sutun, satir);
    lcdYaz(eklenecekHece);
    sutun += heceUzunluk; 
      
    ledControl(freq);  
      
    if (freq == REST) {  
      noTone(buzzerPin);  
    } else {  
      tone(buzzerPin, freq, calmaSuresi);  
    }  
      
    delay(beklemeSuresi);  
    noTone(buzzerPin);  
    ledControl(REST);
  }

  lcd.clear();
  lcd.setCursor(0, 0);
  lcdYaz("Bitti!");
  lcd.setCursor(0,1);
  lcdYaz("Vireon Studio...");
  delay(10000);
  lcd.clear();
}

* = DEĞİŞKEN