DFPlayer MP3 Çalar (kütüphanesiz)

Arduino Uno ile kontrol edilen 2x16 LCD ekranlı, tamamen uzaktan kumandalı  DFPlayer modüllü MP3 çalar çalışmamızla karşınızdayız. Bu çalışmamızın özelliği  DFPlayer için kütüphane kullanmıyoruz. <SoftwareSerial.h>, <IRremote.h>, <LiquidCrystal_I2C.h> kütüphanelerini kullanıyoruz.
İnternette kütüphane kullanmayan, doğrudan komutlarla düzenlenmiş, çok fonksiyonlu bir  DFPlayer uygulaması bulamadım, araştırıp uğraşıp aşağıdaki çalışmayı hazırladım. Yararlı bir örnek olması dileğiyle...

Malzemeler:

  • Arduino Uno, 
  • DFPlayer Modülü, 
  • IR alıcı (ben ex838 kullandım)
  • I2C modüllü 
  • 1602A LCD  ekran (16X2)
  • Herhangi bir uzaktan kumanda
  • 1 adet 1K direnç
  • 2  adet 4u7 elektrolitik kondansatör
Bağlantı Pinleri:
  • IRreceive             ==> Arduino pin A0
  • DFPlayer_BUSY ==> Arduino pin A1
  • I2C LCD data      ==> Arduino pin A4
  • I2C LCD clock    ==> Arduino pin A5 
  • DFPlayer TX       ==> Arduino pin 10 
  • DFPlayer RX       ==> Arduino pin 11
  • btnDene               ==> Arduino pin 9
Notlar:
  • DFPlayer mp3 ve wav dosyalarını çalabiliyor. 
  • 1411 kb/sn bit hızındaki müzik parçalarını rahatlıkla çalıyor
  • DAC çıkışları stereo çıkış veriyor.
  • Ayrı bir program ile kumanda kodlarını öğrenip programımızda kullanıyoruz. Bu programın kodlarını da alt tarafta verdim. Bununla piyasadaki hemen hemen her kumanda kodunu öğrenebilirsiniz.
  • Ben kumanda olarak Next UK-660 uydu alıcısı (Next Minix Punto Plus) kumandasını kullandım.
  • Siz de kodlarını öğrenebildiğiniz her kumandayı kullanabilirsiniz.Te
  • miz bir ses için DFPlayer modülünün bütün GND lerini, ve sd kart yuvasının metal kısmını da mutlaka birleştirin, şaselemeyi güzelce yapın. Yani bütün sistemi bir güzel şaseleyin.
  • Güzel bir 5v regüle kullanın.Örneğin LM7805'li devreleri kullanabilirsiniz. İnternette pek çok şema bulacaksınız.
  • Bağlantı kablolarını kısa tutun, uzun bağlantılar parazit kapabiliyor 
  • Uzaktan kumanda (IR) kod kullanımını butonlarla değiştirebilirsiniz. Bunun için örnek bir buton kontrolünü kodlar içinde görebilirsiniz. Bu kontrol butonlarını programda yalnızca tanımladım, program boyunca kullanmadım.
  • Programı hazırlarken yararlandığım internet kaynaklarını program kodları başına ekledim, özellikle DFplayer MP3 player modül kullanımı için  mikrobotik.com'daki Data Sheet'in Türkçe açıklaması çok yararlı oldu.
  • Saat fonksiyonu bu sürüme eklemedim, onu ayrı bir proje olarak gerçekleştireceğim. 
  • Alttaki kodlar içinde gerekli açıklamaları yaptım.


DEVRE ŞEMASI:


DEVREDEN GÖRÜNTÜLER:








Aşağıdaki program kodları ile Seri Port Ekranında hemen her türlü uzaktan kumanda kodlarını öğrenebilirsiniz:

IRkod_ino dosyası içeriği:

/*
 * IRremote: IRrecvDemo - demonstrates receiving IR codes with IRrecv
 * An IR detector/demodulator must be connected to the input RECV_PIN.
 * Version 0.1 July, 2009
 * Copyright 2009 Ken Shirriff
 * http://arcfn.com
 */
// Seri Port Ekranında hemen her türlü uzaktan kumanda kodlarını öğrenebilirsiniz

#include <IRremote.h> 

int RECV_PIN = A0;   // başka bir pin de tanımlayabilirsiniz

IRrecv irrecv(RECV_PIN);
decode_results results;

void setup()
{
  pinMode(13, OUTPUT);
  Serial.begin(9600);
  irrecv.enableIRIn(); // Alıcıyı başlat
}

void loop() {
  if (irrecv.decode(&results)) {
           dump(&results); 
     }
   irrecv.resume(); // Bir sonraki değeri almak için devam et
     delay(1000);
}

void dump(decode_results *results) {
  int count = results->rawlen;
  if (results->decode_type == UNKNOWN) {
    Serial.println("Mesajın kodu çözülemedi");
  }
  else {
    if (results->decode_type == NEC) {
      Serial.print("Decoded NEC: ");
    }
    else if (results->decode_type == SONY) {
      Serial.print("Decoded SONY: ");
    }
    else if (results->decode_type == RC5) {
      Serial.print("Decoded RC5: ");
    }
    else if (results->decode_type == RC6) {
      Serial.print("Decoded RC6: ");
    }
    Serial.print(results->value, HEX);
    Serial.print(" (");
    Serial.print(results->bits, DEC);
    Serial.println(" bits)");
  }
  Serial.println("");

}


MP3 Player  kodlarımız:
IR_DFPlayer.ino  dosyası kodları:


/* KODLA GİTSİN  KODLA  GİTSİN KODLA  GİTSİN

   -------Developed by Kodla Gitsin-----

   DFPlayer MP3 PLAYER UYGULAMASI
   Malzemeler:
   Arduino Uno, DFPlayer Modülü, IR alıcı,
   I2C modüllü 16X2 LCD
   Herhangi bir uzaktan kumanda // ayrı bir program ile kumanda kodlarını öğreniyoruz ve burada kullanıyoruz
   Ben Next UK-660 uydu alıcısı (Next Minix Punto Plus) kumandasını kullandım
   (kodlarını öğrenebildiğiniz herkumandayı kullanabilirsiniz)
 
   https://kodlagitsin.blogspot.com/
 
   Yararlanılan Kaynaklar:
   Programın iskelet yapısı için                  ==>  https://www.homemade-circuits.com/mp3-player-using-arduino-and-dfplayer/
   DFplayer MP3 player modül kullanımı için       ==>  http://mikrobotik.com/wp2/2019/08/19/dfplayer-mp3-player-modul-kullanimi/
   Serial.read() fonksiyonu için                  ==>  https://www.arduino.cc/reference/en/language/functions/communication/serial/read/
   Arduino Seri Port Nesnesi Detaylı Anlatım için ==>  https://koddefteri.net/arduino/ileri-arduino-dersleri/arduino-seri-port-nesnesi.html
   DFPlayer modülünün bütün GND lerini, ve sd kart yuvasının metaliyle topraklayın sesteki parazit çözülüyor.
   Bir de güzel bir regüle gerekli temiz bir ses için.
   Bağlantı kablolarını kısa tutun, uzun bağlantılar parazit kapabiliyor
   uzaktan kumanda (IR) kod kullanımını butonlarla değiştireblirsiniz 
*/
//-------------------------------------------------------------------------------------

#include <IRremote.h>   // IR alıcılariçin kütüphane
#include <LiquidCrystal_I2C.h>  // I2C LCD kütüphanesi
                                //I2C modül kullanmadığınızda çokfazla pin meşgul ediliyor
LiquidCrystal_I2C  lcd(0x27,2,1,0,4,5,6,7); // LCD bacakları tanımlanıyor
                                            // I2C LCD clock ==>Arduino pin A5, data==>Arduino pin A4
#include <SoftwareSerial.h>  // seri haberleşme kütüphanesi
SoftwareSerial mySerial(10, 11);   // DFPlayer TX ==>Arduino pin 10, RX==>Arduino pin 11

//---------DFPLAYER Başlangıç Kodları---------------------------------------------------
# define Start_Byte 0x7E
# define Version_Byte 0xFF
# define Command_Length 0x06
# define End_Byte 0xEF
# define Acknowledge 0x00
//--------NEXT KUMANDA KODLARI-----------------------------------------------------
# define play_song 0x80BF1BE4       // play
# define pause_song 0x80BFE31C      // pause
# define next_song 0x80BFAB54       // next
# define next_ileri  0x80BF53AC     // p+   //next
# define prev_song 0x80BF639C       // prev
# define prev_geri 0x80BF4BB4       // p-   //prev
# define ses_kes 0x80BF39C6         // mute
# define vol_inc 0x80BF837C         // vol +
# define vol_dec 0x80BF9966         // vol -
# define sound_equalizer 0x80BF6B94 // equaliser
# define reset_dfp 0x80BF738C       // ok   // reset
#define info  0x80BF0BF4            // info  // örneğin: saat/player geçiş
#define stop_dfp 0x80BF2BD4         // stop
#define usb_dfp 0x80BF4AB5          // USB      // USB GİRİŞ
#define sd_dfp 0x80BF8B74           // SHIFT    // SD KART
#define xx_dfp 0x80BF817E           // APPs    // kullanmadım
#define xxx_dfp 0x80BFC13E          // PICTURE // kullanmadım

//0x80BFE11E // 0
//0x80BF49B6 // 1
//0x80BFC936 // 2
//0x80BF33CC // 3
//0x80BF718E // 4
//0x80BFF10E // 5
//0x80BF13EC // 6
//0x80BF51AE // 7
//0x80BFD12E // 8
//0x80BF23DC // 9

//-------------------------------------------------------------------------------------
const int receive = A0;         // IR pini tanımlıyoruz(IR output çıkışı ==> A0'a)
const int btnDene = 9;          // deneme butonu tanımlıyoruz (9.nolu pin/deneysel amaçlı) //kullanmadım
int      DFPlayer_BUSY_PIN=A1;  // DFPlayer BUSY portu bağlantısı
IRrecv irrecv(receive);
decode_results dec;

int bayrak1=0;            // kontrol için  (equalizer modlarını değiştirirken...)
int bayrak2=0;            // ekran üst satır bilgi modu
int bayrak3=0;            // stop kontrol
int i=1;                  // equalizer seçimlerinde...
int volume = 10;          // başlangıç volüm seviyesi
int giris_sec=0;          // usb tf seçimi kontrol

boolean Playing = false;
//--------------------------------------------------------------------------------------
// LCD ekranda kullandığım özel karakterler
// "LCD KarakterMatik - DC" programı ile veya benzeribir programla hazırlayabilirsiniz
byte logo0[8] = {0x0,0xE,0xE,0x1F,0x15,0x15,0x11,0x1F};     // USB
byte logo1[8] = {0x0,0x1C,0x1E,0x1F,0x11,0x1B,0x1B,0x1F};   // TF (SD)
byte logo2[8] = {0x0,0x4,0xE,0x1B,0xE,0x4,0x0,0x0};         // rasgele giriş (ilk açılışta)
byte logo3[8]=  {0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B,0x1B};  // pause
byte logo4[8]=  {0x8,0xC,0xE,0xF,0xF,0xE,0xC,0x8} ;         // play
byte logo5[8]=  {0x8,0x14,0xA,0x5,0xA,0x14,0x8,0x0} ;       // next
byte logo6[8]=  {0x2,0x5,0xA,0x14,0xA,0x5,0x2,0x1} ;        // prev
byte logo7[8]=  {0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F,0x1F} ; // dolu
//--------------------------------------------------------------------------------------

void setup ()                // ilk ayarlarımız...
{ mySerial.begin(9600);      // DFPlayer modülü haberleşmesi başlatılıyor
  Serial.begin(9600);        // seri port ekranı haberleşmesi başlatılıyor
  delay(1000);

  irrecv.enableIRIn();  // IR alıcı...

  //LCD ekran başlatılıyor 
  lcd.begin(16, 2);
  lcd.setBacklightPin(3,POSITIVE);
  lcd.setBacklight(HIGH);

  //LCD özel karakterleri oluşturuluyor
  lcd.createChar(0, logo0);
  lcd.createChar(1, logo1);
  lcd.createChar(2, logo2);
  lcd.createChar(3, logo3);
  lcd.createChar(4, logo4);
  lcd.createChar(5, logo5);
  lcd.createChar(6, logo6);
  lcd.createChar(7, logo7);   

  pinMode(btnDene, INPUT);     // kullanmadım
  digitalWrite(btnDene, HIGH); // kullanmadım

 // ilk başlangıç ayarları (playFirst() fonksiyonuna gidip 1.şarkıdan çalmaya başlıyor...)
 playFirst();
 Playing = true;
 yaz1();
 lcd.setCursor(13, 1);
    lcd.write(byte(2));
 exe_cmd(0x07,0,0);  // equalizer ayarı için normal (flat/düz) komutu gönderiliyor
 lcd.setCursor(7, 1);
 lcd.print("Flat  "); // ilk açılış equalizer ayarını ekrana yazdırıyor
 }
//-------------------------------------------------------------------------------------
 void loop ()
 { 
  checkPlayState() ;          // DFPlayer modülünün BUSY portunu kontrol ediyoruz
 if(irrecv.decode(&dec))      // IR alıcıdan sinyal alırsa-----------------------------
   {
if (dec.value==usb_dfp){      // USB seçimi
  usb_giris(); 
  }

  if (dec.value==sd_dfp){    // TF (SD) seçimi
  sd_giris();

  }
 
if (dec.value==stop_dfp){   // STOP
  stop_player();

  }

 
  if(dec.value==info)        // info (LCD 1.satır)
    {
    bilgi();
    }

 if (dec.value==ses_kes)              // ses kısma  (mute)
    {
    sustur();
    }

 if (dec.value==play_song || dec.value==pause_song )       // pause-play
   {
   if(Playing)  // ==>pause
   {
    yaz1();
    lcd.setCursor(15, 1);
    lcd.write(byte(3));
    pause();
    Playing = false;
   }
 else
   {
    yaz1();     // ==>play
    lcd.setCursor(15, 1);
    lcd.write(byte(4));
    Playing = true;
    play();
   }
   }
 
 if (dec.value==next_song ||dec.value==next_ileri)   // next (sonraki) komutunu alırsa
   {
 if(Playing)
  {
    lcd.setCursor(15, 1);
    lcd.write(byte(5));
    next();
    delay(1000);
    yaz1();

  }
  }
if (dec.value==prev_song || dec.value==prev_geri)   // previus (önceki) komutunu alırsa
  {
if(Playing)
   {
    lcd.setCursor(15, 1);
    lcd.write(byte(6)); 
    previous();
    delay(1000);
    yaz1();
 
  }
  }
if(dec.value==vol_inc)        //volüm +  komutunu alırsa
  {
  volumeINC();
  }
if(dec.value==vol_dec)       // volum -  komutunu alırsa
  {
  volumeDEC();
  }
if(dec.value==sound_equalizer)
  {
  eqAyarla();
  }
if(dec.value==reset_dfp)         // reset_dfp  komutunu alırsa
  {
  reset_player();
  }
  irrecv.resume();  // IR alıcıdan komut almaya devam et...:)
}
  if (digitalRead(btnDene) == LOW)    // burası deneysel alan....:)
 {
  lcd.setCursor(0, 0);
lcd.print("deneme butonu");
delay(2000);
logo();
  }
}
//-------------------------------------------------------------------------------------
void reset_player()                          //reset fonksiyonu
{lcd.clear();
lcd.setCursor(0, 0);
lcd.print("RESET");
delay(1000);

  volume=10;
  //exe_cmd(0x0C, 0, 0);   // reset komutu
  //exe_cmd(0x10, 0, 10);  // Ses ayar seçimi,DH=1 ise ses arttır azalt özelliği açılır. DL=ses kazancı 0-30 seçilir.
                           // [DH]=highByte(NUM), [DL]=lowByte(NUM)
  exe_cmd(0x06, 0, 10);    // ses seviyesi desimal 0-30 arası
  playFirst();
  Playing = true;
//-------------------------------------------------------------------------------------
yaz1();
exe_cmd(0x07,0,0);
lcd.setCursor(7, 1);
lcd.print("Flat  ");
//delay(1000);
  }
//-------------------------------------------------------------------------------------
void playFirst()                     // ilk parçayı çal fonksiyonu
{
  logo();
//exe_cmd(0x3F, 0, 0);
delay(500);
exe_cmd(0x06, 0, volume);
delay(100);
exe_cmd(0x11,0,1);
delay(100);
}
//-------------------------------------------------------------------------------------
void pause()                        // pause  (bekletme) fonksiyonu
{
exe_cmd(0x0E,0,0);
delay(100);
}
//-------------------------------------------------------------------------------------
void play()                        // play (çalma) fonksiyonu
{
exe_cmd(0x0D,0,1);
delay(100);
}
//-------------------------------------------------------------------------------------
void next()                        // next (sonraki) fonksiyonu
{
exe_cmd(0x01,0,1);
delay(100);
}
//-------------------------------------------------------------------------------------
void previous()                   // prev (önceki) fonksiyonu
{
exe_cmd(0x02,0,1);
delay(100);
}
//-------------------------------------------------------------------------------------
void volumeINC()                 // volüm +   fonksiyonu
{
volume = volume+1;
if(volume==31)
{
volume=30;
}
exe_cmd(0x06, 0, volume);
yaz1();
delay(100);
}
//-------------------------------------------------------------------------------------
void volumeDEC()                 // volüm -   fonksiyonu
{
volume = volume-1;
if(volume==-1)
{
volume=0;
}
exe_cmd(0x06, 0, volume);
yaz1();
delay(100);
}
//--------------------------------------------------------------------------------------------------
void exe_cmd(byte CMD, byte Par1, byte Par2)      // komutları modüle gönderme fonksiyonu
{
word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);      // checksum hesaplama satırı
// 10 byte lık komut satırı hazırlanıyor,Command_line  değikenine aktarılıyor
byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge, Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte};
for (byte x=0; x<10; x++)          // for döngüsüyle  komutu göndermeye başlıyoruz.
{
mySerial.write(Command_line[x]);   // komutu modüle gönderiyoruz.
}
}
//-------------------------------------------------------------------------------------------------

void eqAyarla()                 
                  // equalizer modları fonksiyonu  switch  case ile seçiyoruz.
{
switch (i) {

case 1: 
exe_cmd(0x07,0,0);
lcd.setCursor(7, 1);
lcd.print("Flat  ");
yaz1();
delay(250);
i=2;
break;

case 2:
exe_cmd(0x07,0,1);
lcd.setCursor(7, 1);
lcd.print("Pop   ");
yaz1();
delay(250);
i=3;
break;

case 3:
exe_cmd(0x07,0,2);
lcd.setCursor(7, 1);
lcd.print("Rock  ");
yaz1();
delay(250);
i=4;
break;

case 4:
exe_cmd(0x07,0,3);
lcd.setCursor(7, 1);
lcd.print("Jazz  ");
yaz1();
delay(250);
i=5;
break;

case 5:
exe_cmd(0x07,0,4);
lcd.setCursor(7, 1);
lcd.print("Classi");
yaz1();
delay(250);
i=6;
break;

case 6: 
exe_cmd(0x07,0,5);
lcd.setCursor(7, 1);
lcd.print("Bass  ");
yaz1();

delay(250);
i=1;
break;
}   
}
//-------------------------------------------------------------------------------------
void yaz1()                          // LCD ekrana bilgi yazma  fonksiyonu
{
  lcd.setCursor(15, 1);
  lcd.write(byte(4));
  lcd.setCursor(0, 1);
  lcd.print("Ses:");
  if (volume<10) {lcd.print("0");}
  lcd.print(volume);
  }

  void logo(){                      // buda LCD 1.satırda göstereceğimiz logolar için
   lcd.setCursor(0, 0);
  lcd.print("MP3 PLAYER      "); //logo
  }
//-------------------------------------------------------------------------------------
 void sustur()                       //ses kesme (mute) fonksiyonu
 {
if (bayrak1==0){
//lcd.setCursor(14, 1);
//lcd.print("X");
lcd.setCursor(4, 1);
lcd.print("00");             // 1 seviyesini elle yazdırıyoruz.......
exe_cmd(0x06, 0, 0);         //sesi 0 seviyesine düşür
delay(500);
bayrak1=1;                    // bayrak değişkenine 1 değerini atıyoruz. 1 ==> ses 1 seviyesinde
}
else
 {  lcd.setCursor(14, 1);
lcd.print(" ");
lcd.setCursor(4, 1);
lcd.print(volume);          // hafızadaki eski volum degerine dönüyoruz, ekrana yazdırıp
exe_cmd(0x06, 0, volume);   // sesi eski volüm seviyesine getiriyoruz
delay(500);
bayrak1=0;                     // bayrak değişkenine 0 değerini atıyoruz. 0 ==> ses normal seviyede
 }
delay(100);
}
 void bilgi(){                    // logo ile değişimli olarak LCD 1.satıra saat göndermeyi düşünüyorum
  if (bayrak2==0){
     lcd.setCursor(0, 0);lcd.print("    00:00:00    ");
     delay(500);
     bayrak2=1;
    }
  else
  {
     logo();
   delay(500);
     bayrak2=0;
    }
  }

/* checkPlayState() fonksiyonu ile BUSY portunu kontrol ediyoruz
   bu fonksiyonu kullanmazsak next veya prev komutları çalıştırılınca
   bir sonraki veya bir önceki şarkıyı çalıp duruyor
   bu fonksiyon bunu önleyip çalmaya devam etmeyi sağlıyor
*/
void checkPlayState() {
if(Playing) {
delay(20);
int playState = digitalRead(DFPlayer_BUSY_PIN);
if(playState == 1) {
next();
delay(200);
}
}
}

void stop_player(){
 // bu foksiyon devreye girip-çıkarken dac çıkışlarından hoparlöre -pat- sesi gönderiyor
 // dac ve spk çıkışlarını direk-elektrolitik-bipolar kondansatörlerle denedim -pat- sesi var
 // durdurmak için pause kullanmak daha mantıklı gibi görünüyor
   if (bayrak3==0){
      exe_cmd(0x1A, 0, 1);//tüm sistemi geçici olarak durdurur.
      // Başka hiçbir komut sistemi tekrar başlatmaz.
      // RESET atınca yeniden başlar.
      // veya modülün enerjisini keser yeniden enerji verirseniz yeniden başlar.
     delay(100);
     bayrak3=1;
    }
  else
  {
     exe_cmd(0x1A, 0, 0); //tüm sistemi tekrar başlatır, kaldığı yerden devam eder
   delay(100);
     bayrak3=0;
    }
  }

 void usb_giris(){
  lcd.setCursor(13, 1);
    lcd.write(byte(0));
    exe_cmd(0x3F, 0, 1);
     delay(30);
     exe_cmd(0x09,0,1);  // USB
     giris_sec=1;
     delay(30);
     playFirst();
   
    }
 void sd_giris(){
    lcd.setCursor(13, 1);
    lcd.write(byte(1));
    exe_cmd(0x3F, 0, 0);
     delay(30);
     exe_cmd(0x09,0,0);  // SD (TF)
     giris_sec=1;
     delay(30);
     playFirst();   
 
  }


/* ---------Developed by Kodla Gitsin------
 KODLA GİTSİN  KODLA  GİTSİN KODLA  GİTSİN   KODLA GİTSİN
*/



PROGRAM DOSYALARINI İNDİR

KULLANILAN PROGRAMLAYICI: Arduino 1.8.10

Yorumlar

  1. Projem de bir kaç ses kaydı var onları nasıl calarim

    YanıtlaSil
  2. http://mikrobotik.com/wp2/2019/08/19/dfplayer-mp3-player-modul-kullanimi/ sitesinden dfplayer hakkında türkçe bir inceleme var. Ondan yararlanın. Ses dosyalarınızı 001 (mp3 veya wav) gibi adlandırdığınızda, programdan ilgili komutu ilgili ses dosyasına yönlendirirseniz olur diye düşünüyorum.

    YanıtlaSil
    Yanıtlar
    1. hocam kütüphane ile istediğim sesleri çalabiliyorum kütüphanesiz 5. sarkı kodu nasıl yazılır mesela bunu kütüphanesiz yapabilirmiyim

      Sil
    2. hocam tesekkür ederim projemle mp3 birlestirdim istediğim sesi çalar hale getirdim verdiğiniz bilgiler doğrultusunda.

      Sil
    3. exe_cmd(0x0D,0,1);
      komutundaki 1 ilk
      sarki demek onu 2,3,4 gibi kendinize gore ayarlayin. 5 parrca icin bu komuttan 5 tane herbiri icin ayri ayri yazmalisiniz. programi kendinize gore duzenleyin.

      Sil

Yorum Gönder