DFplayer MP3 player modül kullanımı. (Arduino_PIC_Kablosuz (android),Raspberry pi, PC, STM)

Bu yazımda DFPLAYER mini MP3 çalar modülüne yer verdim. Bu modül seri port üzerinden komut aldığı için Arduino, PIC, PC, hatta kablosuz olarak Bluetooth ve ESP8266-01 modülüyle bile telefonunuzdan ya da uzaktan kontrol edilebilir.
Ayrıca hiç bir ek donanıma ihtiyaç duymadan kendi üzerindeki buton girişlerini kullanarak da modülü kontrol edebilirsiniz.

Videolarda, Arduino ile çalışması, Android ile kablosuz çalışma, SPK çıkışı ile kendi başına minimal çalışması, PIC 16F1827 ile Konuşan saat yapımı ( Bunu diğer mikrokontrolcüler ve arduino ile de yapabilirsiniz. ) gösterilmiştir.

Modül 3.3V – 5V arası çalışıyor. ( Her ne kadar çizimlerde arduino üzerinden 5V alınmış olsa da akım harcaması yüksek olduğunda sorun olabilir. Bilginiz olsun. Uzun süreli çalışacaksa  ayrı beslenmesi iyi olacaktır. )
Fakat SPK çıkışına hoparlör bağlamayı düşünüyorsanız 5V ile çalıştırmanızı öneririm. Hoparlör kullanacaksanız bir çok şemada SPK-1 ve SPK-2 uçlarına birlikte bağlayın deniyor. Bu şekilde çalışıyor. Fakat bende 0.5W lık hoparlör var, belki de bundan dolayı akım fazla çekiyor gibi geldi. devrede sorun yarattı. Ben de SPK1 – GND olarak bağlayarak ve araya da 470uF kondansatör bağlayarak sorunsuz şekilde çalışmasını sağladım.
Ayrıca internette SPK bağlantılarına hoparlör bağlandığında gürültü olabildiği yazıyor. Gerçekten öyle. Fakat bunu gidermek için bazı yollar bulunmuş.
1-) 2 adet GND ucunun birbirine bağlanmış olması,
2-) dfplayer ile arduinoyu farklı kaynaklardan beslemek (Tabii ki GND leri birleştirmek)
3-) SPK çıkışının birine 470uF kondansatör bağlamak.
4-) Ses giriş ve çıkışlarında ses kablolarının kullanılması,
5-) Ses giriş çıkışlarının birbirine yakın olarak monte edilip kablo gürültüsünün azaltılması.
( Ben protoboard üzerinde deneme yaptığımdan, bağlantı kabloları uzun olduğundan, gürültüyü arttırdı. )

Not: DFplayer modülünün üstündeki LED enerji verildiğinde değil sd kartı okumaya başladığı anda yanıyor. Enerji verdiğinizde neden LED yanmadı problem mi var demeyin. 

Arduino kullananlar hemen kütüphane arayacaklardır. Bol miktarda kütüphane bulacaklardır. Fakat şunu söylemeliyim ki, bu kütüphanelerin bazıları basit komutlara yer verdiğinden sadece deneme olarak kullanılabilir. Bundan dolayı KÜTÜPHANESİZ olarak çalışmasını anlatacağım. Bu şekilde kendiniz tüm komutları kullanabileceksiniz.
Arduino kütüphanesini kullanarak yapacağım diyenler aşağıdaki linklere bakabilirler. Fakat unutmayın modül geliştikçe kütüphaneniz yeni komutları kullanamayabilir. Ya da bazı komutlar 2 ye bölünmüş, siz komutu yollarsınız hata verebilir veya komut çalışmaz. Mesela Random all komutu benim modülde yer değiştirmiş .
Kütüphanesiz çalışmayı öğrenip kendi komut sisteminizi kullanmanızı öneririm.

1. link : arduino kütüphaneli çalışma.
2. link : Arduino kütüphaneli çalışma.

Ayrıca vereceğim datasheet dosyasından sonra versiyonlara göre komut seti değişmiş fakat datasheet eski kalmış. Bir çok yerden topladığım verilerle aşağıdaki tabloları oluşturdum. Sizler tablodaki verilere bakarak, kendi modülünüzün komut setini algılayabilirsiniz.
Datasheet dosyası burada.

Bu modül kendi başına çalışacak şekilde anons sistemlerinde kullanılabilir. Mesela bir sensör koyduğunuzda, sensör bir kişiyi hissettiğinde, mp3 dosyasını çalmaya başlar ve bulunduğu yeri anlatmaya başlar. (Bunu sağlamak için Modülün IO1-2  uçlarından birini sensör kontrolü ile şase yapması yeterli. )
Ya da mikrokontrolcü kullanarak görme engelliler için saat gibi nümerik değerleri okuyabilir.
Ya da anons sistemleri gibi kullanılarak makine de hata varsa çevredeki kişileri sesle ikaz edebilir.
Daha pek çok projede bu modülü rahatlıkla kullanabilirsiniz.
AUX girişini de kablo çekerek hallederseniz, Bluetooth ses alıcısı  ya da radyo sistemi bağlayabilirsiniz. Bluetooth ile telefondan da ses dosyalarını çalabilirsiniz.
Tek eksiği MP3 dosyalarının isimlerini ekranda yazdıramamak.

Modül ilk enerji verildiğinde hiç bir ses oynatmaz. Bu pozisyonunu bozmak için Play komutu, Repeat komutu  gibi komutların gelmesini bekler. Şayet kendi başına çalışacaksa butona basmanızı bekler. Otomatik çalışsın derseniz, IO portlarından birini GND ye bağlamanız yeter.
Belki de Busy monostable şeklinde çalıştırarak da,( kısa süreliğine LOW yapmak için) IO-1 pimine bağlayabilirsiniz. ( Kısa süreliğine IO-1 pimi gnd ye bağlandığında NEXT komutu işlevi görür. Uzun süreli GND ye bağlı olursa Ses düşürücü görevi görür. )
Şarkı başladığında busy pimi, HIGH olur. Bittiğinde, LOW olarak diğer şarkıya geçmesini sağlayabilirsiniz. Tabii ki denenmediğinden tüm şarkılar bitince başa döner mi bilemiyorum. Belki de bir de Reset butonu konulabilir.

Modül Repeat komutuyla devamlı tekrarlar. Bunu yaparken Random All komutu gönderirseniz, karışık çalma durumunda, tekrar modunda çalışır.
Ancak CMD 0x0D komutu kullanırsanız, mp3 dosyasını oynatma işlemi bitince durur. Ya da dizin ve şarkı ismi seçerseniz bu şarkıyı oynatır ve durur. 
Bu şekilde çalışması durumunda arka arkaya istediğiniz ses dosyalarını oynatabilirsiniz. Bununla birlikte mp3 dosyasını okuması biraz gecikmeli başladığı için, arka arkaya tekrar edilen dosyaların uzun boşluk vermesini istemiyorsanız, dosyanızı WAV olarak kaydedin. Daha çabuk tepki verdiğinden arada boşluk hissedilmeyecektir.
Bununla birlikte sesin bittiğini nasıl anlayacağım derseniz. Modül sesin bittiğini 2 yolla bildiriyor.
1-) Seri port üzerinden 0x3C, 0x3D, 0x3E gönderir. Neden 3 adet kod. Sebebi U-disk, SD kart, Flash için 3 ayrı geri bildirimdir. Hangisi çalıyorsa ona göre cevap verir. Ayrıca biten ses dosyasının numarasını da gösterir.
2-) BUSY pini. Bu pin LOW ise hala ses dosyası oynatılıyor. HIGH ise ses dosyası duruyor demektir. ( Pause komutunda denemedim sizler pause komutunda da kontrol edersiniz. )

Dosya sistemi:
Bu modül SDHC kart kullanıyor 2GB-32GB ye kadar.
Bu kartı FAT veya FAT32 sistemi ile formatlayarak işe başlayabilirsiniz. Ya da SDformatter programını kullanabilirsiniz. Dizin yapısı ve dosya isimlendirmesi belli şartlara bağlanmıştır.
Öncelikle dizin ismi ne olursa olsun modül mp3 dosyası varsa bunları track numarası olarak isimlendiriyor. Bundan dolayı sadece  repeat komutu verildiğinde 1. şarkıdan başlar ve hangi dizinde olursa olsun mp3 dosyalarını çalabiliyor. Tabii ki belli bir sınırı var.
Fakat sizin hazırlamanız gereken kısım şudur.
Ana dizinde 1-99 arası dizin yaratabilirsiniz. Bu dizinler mutlaka 2 karakterlik olmalı. Yani 1 diye dizin ismi olmayacak. 01 olarak yazılacak.
Dizin içindeki dosyalar ise 1-255 arası olacak. Tabii ki burada 3 karakterlik kodlama olacağından 1.mp3 yerine 001.mp3 ,  255.mp3 yazılacak.

Bunların dışında mp3 adlı bir dizin yaratılabilir. Bu dizin özel bir dizindir ve içine ulaşmak için dizin numarasını byte olarak veremeyeceğiniz için, buna ayrı bir komut koymuşlar. Bu dizinden bir parça çalmak isterseniz. 0x12 komutunu kullanmalısınız. mp3 dizini içerisindeki dosyalar ise 4 karakterlik dosya ismi olmalı. mesela 0001.mp3 2999.mp3 olarak yazılır. bu dizinin limiti 2999.mp3 tür. bundan daha fazla dosya çalınamaz.

Peki hangi numaralı dosya hangi şarkıyı temsil ediyor nereden bileceğiz. DFplayer bunu bize gösteremiyor. yani mp3 dosyası içerisindeki TITLE bölümünü okuyup bize gösteremiyor. Biz bunu dosya sisteminde görebiliriz. Çünkü tüm dosya isimlerinde baştaki numaraya bakıyor. yani bizler 001.mp3 yazmak yerine 001_sescalmasistemi1.mp3 olarak isimlendirebiliriz. Modül sadece baştaki 001 kısmına bakıyor ve çalmaya başlıyor. Aşağıdaki SD kartımın içeriğinde bunu görebilirsiniz.

Benim SD kartımdaki dizin yapısı :

Not :
Tüm müzik listenizi dizin yapısına uygun olarak sd karta kopyaladınız, sonrasında dizin yapısına göre 1-255 arası müzik dosyalarına isim eklemeniz gerekiyor. Bunu yapabilmek için file renamer programları var. Bu programları kullanarak dosya ismini koruyup, başına otomatik olarak 1-255 arası sayıyı verebiliyorsunuz. Bunu yaparken 1 yerine 001 yazması için formatı ayarlamanız gerekir.

Modül USB disk , SD kart (TF card) , AUX, ve Flash  sistemlerini kullanabiliyor. Fakat AUX girişleri pim olarak çıkarılmadığı için direkt kullanamazsınız. USB disk kısmını hiç denemedim. Tüm komutlar aynı fakat bazı komutlarda U-disk seçmeniz gerektiği belirtilmiştir.

Önce komut setini görelim. 
Komut seti 10 byte tan oluşur. Açıklamaları tablodadır. Örnek: 7E FF 6 3F 1 0 0 FE BB EF gibi

Bu modülün basit bir komut yapısı var. Fakat komut içerisinde doğrulama kodunu (checksum) sizin hesaplamanız gerekiyor. Bunun için aşağıdaki tablo yardımcı olacaktır. Checksum, 2 byte tan oluşur. Bundan dolayı HIGHBYTE ve LOWBYTE olarak adlandırılmıştır.  Bunun yanı sıra ilk hesaplamada 65535 değeri hex olarak 0xFFFF sayısına karşılık geliyor. Aslında 0-65535 adet rakam vardır. Bundan dolayı 16 bitlik sayı 65536 ediyor. 1. yöntemde +1 bunu temsil ediyor. Bir çok yerde sıfırdan çıkarma yani 2. yöntem kullanılmıştır. Çıkan sonucun, sağdaki 2 byte olanı checksum değeridir. . Hangisi kolayınıza gelirse.

BYTE 3 ile belirtilen sıradaki CMD komutları aşağıdaki tabloda yer almaktadır. Komutların hepsini denemedim. Bazılarını deneyerek sistemi anlamaya çalıştım. Dokümanlardaki bilgilerden komut setini oluşturdum. Bu arada datasheetteki komut setinden farklılıklar vardır buna dikkat edin.
Aşağıdaki komut sistemleri ilk etapta karışık gelebilir fakat incelediğinizde çok kolay adapte olabileceğinizi görebileceksiniz.

CMD komutları ve açıklamaları

0x01 NEXT sonraki şarkıya geç
0x02 PREVIOUS önceki şarkıya geç
0x03 Specify tracking(NUM) 0-2999 özel şarkı seçimi 0-2999
0x04 Increase volume ses arttır. (Bak CMD  0x10)
0x05 Decrease volume ses azalt. (Bak CMD  0x10)
0x06 Specify volume 0-30 ses seviyesi desimal 0-30 arası ayarla
0x07 Specify EQ(0/1/2/3/4/5)
Normal/Pop/Rock/Jazz/Classic/Base
Ekolayzır seçimi
0x08 Specify playback mode
(0/1) Repeat/folder repeat
Tekrar seçimi yapılır. Tüm parçalar
veya sadece belirtilen dizin içindeki parçalar. Dizin numarası 0-15 arası parametre low byte olarak yazılır.
Datasheet 0/1/2/3 yazsa da sonradan değişikliğe uğramış ve sadece 0/1 çalışıyor diğer ikisi başka komut olarak yapılmış.  Benim modülümde.
0x09 Specify playback source(0/1/2/3/4)
U/TF/AUX/SLEEP/FLASH
kaynak seçimi. USB/TF/AUX/SLEEP/FLASH
0x0A Enter into standby – low power standby durumuna geçer düşük enerji modu
0x0B Normal working Normal çalışma. ne olduğu anlaşılmadı
0x0C RESET Module reset modül. Tüm değerler sıfırlanır.
En baştaki şarkıdan başlar . Ses değeri 30 olur.
0x0D Playback Çalmaya başla. Bu şekilde çalıştırılırsa şarkı sonunda durur. Şayet repeat komutu önceden kullanıldıysa durmadan bir sonraki parçaya başlar.
0x0E Pause Geçici durdurma.
0x0F Specify folder and file to playback * [DH]=Folder, [DL]=File
Important: Folders must be named 01~99, files must be named 001~255
Dizin ve şarkı seçimi. Dizin adı olarak 01-99 arası ve şarkı için ise 1-255 arası seçim yapılır.
Ayrıca DH parametre1 =dizin numarası  DL parametre2 =şarkı numarası olacak. Şarkılar 001-255 arası yazılmış olmalı dizin içerisinde. Dikkat: 1 nolu şarkı için dosya ismi 001.mp3 olmalı. 1 nolu dizin için dizin numarası 01 olacak.
0x10  Volume adjust set
{DH=1:Open volume adjust }{DL: set volume gain 0~31}
Ses ayar seçimi
DH=1 ise ses arttır azalt özelliği açılır. DL=ses kazancı 0-30 seçilir. 0x04 ve 0x05 özelliği için 1 olmalı diye düşündürüyor. Fakat denenmedi.
0x11 Loop play * [DH]=X, [DL]=(0x01:play, 0x00:stop play) tekrar modu açılır Veya kapatılır.
0x12 Play mp3 file [NUM] in mp3 folder *
[DH]=highByte(NUM), [DL]=lowByte(NUM)
Play mp3 file in folder named mp3 in your TF-card. File format exact 4-digit number (0001~2999) e.g. 0235.mp3
Root dizininde mp3 dizini içerisindeki dosyaları 0001-2999 arası isimlendirin. Ve çağırmak istediğinizde sadece mp3 dizini içindekileri DH ve DL ye yazarak çağırın. örnek: 2999 hex olarak 0x0BB7 dir. DH=0x0B  DL=0xB7 olacak.
0x13 Unknown ? Unknown: Returns error code 0x07 bilinmeyen komut hata kodu 7 bildirir
0x14  Unknown ? Unknown: Returns error code 0x06 bilinmeyen komut hata kodu 6 bildirir
0x15  Unknown ? Unknown: Returns no error code, but no function found bilinmeyen komut hiç hata döndürmez.
0x16 Stop * [DH]=X, [DL]=X, Stop playing current track şarkıyı durdurur.
0x17  Loop Folder “01” * [DH]=x, [DL]=1~255, Loops all files in folder named “01” dizin tekrarı. Belirtilen Dizin içerisindeki 001-255 şarkıyı tekrar eder. DL =dizin numarası.
0x18  Random play * [DH]=X, [DL]=X Random all tracks, always starts at track 1 Karışık tekrar etme moduna girer. 1. şarkıdan başlar.
0x19 Single loop * [DH]=0, [DL]=0 Loops the track that is playing tek bir şarkıyı tekrar eder. Şarkı çalarken bu komut gönderilir. Çalan şarkı tekrar eder. Durdurulasıya kadar.
0x1A  Pause * [DH]=X, [DL]=(0x01:pause, 0x00:stop pause) Bu tüm sistemi geçici olarak durdurur. DL=1 durdurur. DL=0 tekrar başlatır.
Bu önemlidir. Başka hiçbir komut sistemi tekrar başlatmaz. RESET atsanız bile aynı durumda kalır.

CMD fonksiyon ve açıklamaları

0x3A Medium inserted * [DH]=0, [DL]=(1:U-disk, 2:TF-card) ortam takıldı ortam: U-disk , TF kart
0x3B  Medium ejected * [DH]=0, [DL]=(1:U-disk, 2:TF-card) ortam çıkarıldı ortam: U-disk , TF kart
0x3C Finished track on U-disk * [DH]=highByte(NUM), [DL]=lowByte(NUM)
Not validated. Returns track number when song is finished on U-Disk
USB disk şarkı bitti
0x3D  Finished track on TF-card * [DH]=highByte(NUM), [DL]=lowByte(NUM)
Returns track number when song is finished on TF
TF kart şarkı bitti
0x3E Finished track on Flash * [DH]=highByte(NUM), [DL]=lowByte(NUM)
Not validated. Returns track number when song is finished on Flash
Flash şarkı bitti
0x3F  Initialization parameters * [DH]=0, [DL]= 0 ~ 0x0F. Returned code when Reset (0x12) is used. (each bit represent one device of the low-four bits)
See Datasheet. 0x02 is TF-card. Error 0x01 when no medium is inserted.
Sıfırlama komutu.
7E FF 06 3F 00 00 01 xx xx EF  U-disk
7E FF 06 3F 00 00 02 xx xx EF  TF kart
7E FF 06 3F 00 00 04 xx xx EF  PC
7E FF 06 3F 00 00 08 xx xx EF  FLASH
7E FF 06 3F 00 00 03 xx xx EF TF kart U-disk
0x40 Error ? [DH]=0, [DL]= 0~7 Error code(Returned codes not yet analyzed)
Error-1 : Card not found
Error-2 : Sleeping
Error-3 : Get Wrong Stack
Error-4 : Check Sum Not Match
Error-5 : File Index Out of Bound
Error-6 : Cannot Find File
Error-7 : In Advertise
Bu error kodlarından tam emin değilim bazı kodlar ile karşılaşınca internetten araştırıp bunu buldum. Datasheet içerisinde sadece 3 adet error  kodu var fakat modul error code 6 diyor. sanırım o da zaman içerisinde gelişti.
0x41  Reply ? [DH]=0, [DL]= 0~? Return code when command feedback is high
ACK byte is high =feedback ON
ACK byte 0x01 ise şarkı çalarken verilen komuttan sonra bilgi verir.
Şayet ACK byte 0x00 ise bilgi vermez. Repeat yaptığında.
0x42 The current status * [DH] = Device number [DL] = 0 no play, 1 play Anlık durum öğrenilir. DH ve DL bilgileri gösterir.
0x43 The current volume * [DH]=0, [DL]= Volume (0x00-0x30) anlık ses durumunu gösterir.  Gelen sayı HEX olarak gelir.
0x44 The current EQ * [DH]=0, [DL]= EQ(0/1/2/3/4/5) [Normal/Pop/Rock/Jazz/Classic/Base] Ekolayzır durumunu öğren
0x45 The current playback mode * [DH]=0, [DL]= (0x00: no CMD 0x08 used, 0x02: CMD 0x08 used, not usefull) Çalma durumunu öğren.
0x46  The current software version * [DH]=0, [DL]= Software version. (My version is 5) yazılım versiyonunu öğren.
0x47 The total number of U-disk files * [DH]=highByte(NUM), [DL]=lowByte(NUM). Not validated toplam şarkı sayısını gösterir. U-disk için
0x48 The total number of TF-card files * [DH]=highByte(NUM), [DL]=lowByte(NUM) toplam şarkı sayısını gösterir. TF kart için
0x49  The total number of flash files * [DH]=highByte(NUM), [DL]=lowByte(NUM). Not validated toplam şarkı sayısını gösterir. Flash için
0x4A Keep on (Datasheet) ? Unknown. No returned parameter Bilinmiyor. Datasheet açıklama yapmıyor.
0x4B The current track of U-Disk * [DH]=highByte(NUM), [DL]=lowByte(NUM), Current track on all media Kaçıncı şarkı çaldığını gösterir.  U-disk ( benim modülde TF karta karşılık geliyor.) sizler diğer kodları deneyebilirsiniz.
0x4C The current track of TF card * [DH]=highByte(NUM), [DL]=lowByte(NUM), Current track on all media Kaçıncı şarkı çaldığını gösterir.  TF kart
0x4D  The current track of Flash * [DH]=highByte(NUM), [DL]=lowByte(NUM), Current track on all media Kaçıncı şarkı çaldığını gösterir.  FLASH
0x4E Folder “01” [DH]=x, [DL]=1 * [DH]=0, [DL]=(NUM) Change to first track in folder “01”  Returns number of files in folder “01” Dizin seçilir. Dizin numarası DL ye yazılır. Ve 01.mp3 ten başlar.
0x4F The total number of folders * [DH]=0, [DL]=(NUM), Total number of folders, including root directory Toplam dizin sayısını gösterir. Root dizini dahil. DL dizin sayısını gösterir. 255 adetten fazla olamaz

 

Modülün hiç bir işlemci yada başka modül kullanılmadan çalışabildiğini söyledik.
Üzerindeki Analog giriş ve IO giriş uçları 2 farklı şekilde çalışmasını sağlayacaklardır.
Şunu hatırlatmalıyım. Analog girişler çevre etkilerinden etkilenebilirlermiş.
Birinci devre sadece analog girişler kullanılarak yapılmış olan devredir.
İkinci devre ise IO butonlarıyla yapılmış devredir. Burada butonlara uzun ve kısa basılmasına göre ikili fonksiyon olarak kullanılmıştır.  segment 1 ve segment 5 = 1. ve 5. şarkı için direkt çalıştırma butonları içindir.

Öncelikle nasıl çalıştığını anlamak için videoda gösterilen arduino devresiyle başlayalım.  Arduino seri monitörde giden komutları ve gelen cevapları görebiliriz. KÜTÜPHANESİZ olduğundan daha küçük bir yere de sığabileceği için atmega168 işlemcili nano ile kontrol ettim. Çizimlerde ise UNO gösterilmiştir bacak sistemleri aynı olduğundan sorun yaratmayacaktır.


Aşağıdaki devre ise Bluetooth üzerinden çalışmasını göstermektedir.
Burada dikkat edilecek kısım 3.3V ile çalışan bluetooth modülü için sinyal seviye dönüşüm yapılmalı. 2 dirençle burada yapılmıştır. Bluetooth Rx girişine 5V luk gelen sinyalin 3.3V seviyesine düşürülerek verilmesi amaçlanmıştır. dirençler 1K ve 2K dır.

Bu devre ise DAC çıkışlarını kullanarak kulaklık veya amfiye bağlanmasını göstermektedir.

Not: Devreler Fritzing de çizilmiştir. DFplayer modülü kütüphanesi yoktu. Bu kütüphaneyi ekledim. Eklediğim kütüphaneyi ise Tüm dosyaların paylaşıldığı yerden alabilirsiniz. 

Bluetooth üzerinden kontrol edilen devre için basitçe Android program yazdım. Tüm fonksiyonlar olmasa da örnek olması açısından kullanabilirsiniz. Bu programın dosyaları da tüm dosyalar arasında yer almaktadır. MIT app inventor 2 ile yapılmıştır.

///              MP3 PLAYER PROJECT
/// http://educ8s.tv/arduino-mp3-player/
/// softserialden gelirse serial kısma aktar. 
//////////////////////////////////////////
#include "SoftwareSerial.h"
SoftwareSerial mySerial(10, 11);
# define Start_Byte 0x7E
# define Version_Byte 0xFF
# define Command_Length 0x06
# define End_Byte 0xEF
# define Acknowledge 0x00 //Returns info with command 0x41 [0x01: info, 0x00: no info]
# define ACTIVATED LOW
int say=0;
int buttonNext = 2;
int buttonPause = 3;
int buttonPrevious = 4;
boolean isPlaying = false;
void setup () {
pinMode(buttonPause, INPUT);
digitalWrite(buttonPause,HIGH);
pinMode(buttonNext, INPUT);
digitalWrite(buttonNext,HIGH);
pinMode(buttonPrevious, INPUT);
digitalWrite(buttonPrevious,HIGH);
mySerial.begin (9600);
Serial.begin (9600);
Serial.print(" basladi");
delay(1000);
playFirst();
isPlaying = true;
}
void loop () { 
  
 // Örnek serial read komutu. 10 byte bekle. while (mySerial.available()<10); // Wait until initialization parameters are received (10 bytes) 
 
  if (mySerial.available()) { // dfplayer dan gelen bilgileri yazdır. ****
    say=1;
    Serial.print(mySerial.read(),HEX);
  }
  if (say==1){
    Serial.println("   gelen");
    say=0;
  }
 // if (Serial.available()) {
 //   mySerial.write(Serial.read());
 // }
  
 if (digitalRead(buttonPause) == ACTIVATED)
  {
    if(isPlaying)
    {
      pause();
      isPlaying = false;
    }else
    {
      isPlaying = true;
      play();
    }
  }
 if (digitalRead(buttonNext) == ACTIVATED)
  {
    if(isPlaying)
    {
      playNext();
    }
  }
   if (digitalRead(buttonPrevious) == ACTIVATED)
  {
    if(isPlaying)
    {
      playPrevious();
    }
  }
}
void playFirst()
{
 //execute_CMD(0x0C,0,0); // Reset module
  //delay(500);
 execute_CMD(0x3F, 0, 0);
delay(500);
  setVolume(20);
  delay(500);
  // execute_CMD(0x11,0,1); // repeat play =0 1 repeat stop play 0 0
  //execute_CMD(0x0B,0,0);  // normal çalışma bir değişiklik yaratmıyor. 
  // execute_CMD(0x0D,0,0);
  
  //delay(500);
  //execute_CMD(0x4B,0,0); // hangi parçayı çaldığını gösterir. 
  // execute_CMD(0x0D,0,0);
 // execute_CMD(0x18,0,0); // random all
 // delay(500);
  execute_CMD(0x4B,0,0); // hangi parçayı çaldığını gösterir.
  //execute_CMD(0x18,0,0); // random all
  delay(500);
  
  //execute_CMD(0x17,0,14); // loop folder  
   //execute_CMD(0x0B,0,0); // Normal Çalışma 
    
  //delay(500);
}
void pause()
{
  execute_CMD(0x0E,0,0);
  delay(500);
}
void play()
{
  execute_CMD(0x0D,0,1); 
  delay(500);
}
void playNext()
{
  //execute_CMD(0x0D,0,0);
   execute_CMD(0x01,0,0); // next 
  delay(5500);
  //execute_CMD(0x08,0,155); // 155 şarkı numarası devamlı aynı şarkıyı çalar. 155. şarkı yokken hata vermiyor bir şarkı seçiyor. 
 // execute_CMD(0x07,0,0); // EQU seçme 0-5 arası
 // execute_CMD(0x03,0,3);// 3. şarkıyı çalar ve durur. dizin belirtilmez. 
 //execute_CMD(0x0E,0,0); // pause 
// execute_CMD(0x1A,0,1); // special pause mode  ancak 01A 0 0 ile eski haline döner yada reset ile. ***
 //  delay(4500);
// execute_CMD(0x1A,0,0);// special no pause mode. ***  0E gibi değil 0E ile duran şarkı 0D ile çalıştırılabilir. 
//   delay(2500);  
  
   // execute_CMD(0x16,0,0);// stop track fakat 3D durdu bilgisi gelmez. 
   //delay(5500); 
   // execute_CMD(0x11,0,0);// repeat play=0 1   repeat stop = 0 0
   //delay(2500); 
  //execute_CMD(0x48,0,0);  // toplam parça sayısını gösterir. TF için
  //delay(500);
  execute_CMD(0x4B,0,0); // hangi parçayı çaldığını gösterir. 
  delay(500);
  
//execute_CMD(0x43,0,0); // valume seviyesini goster
// delay(500);
  //execute_CMD(0x42,0,0);  // play durumunu gösterir. ayrıca hangi aygıt çalıyor onu gösterir. tf usb gibi. 
 // execute_CMD(0x12,0,3);  // mp3 dizinindeki şarkılardan 3. sünü çal. bu komut sadece mp3 dizinindekilerden seçtiğinizi direkt olarak çalar ve bitiminde durur. 
 // delay(500);
}

void playPrevious()
{
  execute_CMD(0x02,0,1);
  delay(500);
}
void setVolume(int volume)
{
  execute_CMD(0x06, 0, volume); // Set the volume (0x00~0x30)
  delay(2000);
}
void execute_CMD(byte CMD, byte Par1, byte Par2)
// Excecute the command and parameters
{
// Calculate the checksum (2 bytes)
word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);
// Build the command line
byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,
Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte};
//Send the command line to the module
for (byte k=0; k<10; k++)
{
mySerial.write( Command_line[k]);
Serial.print( Command_line[k],HEX);
}
Serial.println();
}

Bu programı, en tepesinde yazan siteden aldım. Kendim ihtiyacıma göre düzenledim.
Verilen komutlardan bazılarının açıklaması yanında yazmaktadır. bu komutlar denenmek üzere o bölümlere yazıldı.  Ayrıca orijinal programda olmayan myserial kısmından gelenleri seri monitöre yazan kısım eklendi. Bu şekilde modülün gönderdiği bilgileri de seri monitörde görebilirsiniz.
Bu bilgiler önemlidir. Hangi parça numarası çalıyor. Parça bitti mi tekrar ediyor mu bu tip bilgiler önemli ayrıca kaç dizin var, kaç dosya var, Kaçıncı şarkı oynatılıyor. Bu tip bilgileri de alabilirsiniz. Bunlara bakarak mikrokontrolcü karar verebilir.

Orjinal dosya ise  Paylaştığım Tüm dosyalar arasında mp3.zip dosyasıdır. 

DFplayer devre şeması, tüm dosyalar arasındadır. Bu devreye bakarak AUX girişlerini görebilirsiniz.

Ses dosyası formatlarını, bu sitede online olarak çevirebilirsiniz. Kullanımı gayet kolay ve hızlı.

DFplayer ile KONUŞAN SAAT programı (PIC 16F1827 kullanılmıştır.)

Bu program her ne kadar PICbasic ile yapıldıysa da seslendirme kısmı program sonundadır ve kolaylıkla programlama dilinize çevirebilirsiniz. PICBASIC 3.0 ve yukarısı derleyici kullanın ya da config satırını derleyicinize göre düzeltin. 

Yukarıdaki devre, DS1307 li RTC modülünden, okunan saat bilgisinde, dakika kısmının her  değiştiğinde, DFplayer’a dijitlerdeki numaraya göre, dosya ismi seçilerek komut gönderilir.
DFplayer daki komutlardan biri, hem ana dizin içerisinde bulunan dizin numarasını, hem de dosya numarasını vermeye imkan tanıdığından, dosya numaralarını seçebiliyoruz.
Komut dizilimi bu şekildedir. $7E,$FF,$06,$0F,$00,$02,degeryaz,ch,cl,$EF  burada degeryaz değişkeni dosya numarasıdır. hemen solundaki $02 ise ana dizin içerisindeki 2 numaralı dizini işaret eder.
Dosyalar wav ve mp3 olarak kayıt edildi.
1 rakamı seslendirilecek ise, 001.wav dosyası işaret edilir. 10 rakamı seslendirilecek ise 010.wav dosyası işaret edilir.
Her komuttan sonra çalma süresi kadar bekleme verilir. Ben wav dosyalarımı 700ms yetecek şekilde düzenlediğim için pause 700 koydum. Sizin kayıt edeceğiniz dosyalardaki sesler daha uzunsa, sizler bu süreyi ayarlayabilirsiniz.
Ayrıca birler basamağında 0 rakamı varsa 10 dedikten sonra sıfır söylenmemesi için dosya numarası 056.wav işaret edildi.
Normalde bu dosya olmadığı için hata verecek ve dosyayı oynatamayacaktır. Şayet onlar basamağında 0 rakamı varsa bunu sıfır olarak okuyacaktır. Mesela 08 gibi.  Hata seri port üzerinden geri bildirim olarak gönderilir. CMD kodu 40 dır. Fakat ben devrede geri bildirim istemediğim için sorun olmuyor. (Kullandığım hoparlör 8ohm 0.5W bundan dolayı ses az çıkıyor. 3W hoparlöre kadar kullanabilirsiniz. )

Devrede EASYLCD LCD display modülü kullanıldı. Bu modül için ayrıntıları buradan okuyabilirsiniz. 

PICBASIC programı aşağıdadır.

'****************************************************************
'*  Name    : UNTITLED.BAS                                      *
'*  Author  : [select VIEW...EDITOR OPTIONS]                    *
'*  Notice  : Copyright (c) 2013 [select VIEW...EDITOR OPTIONS] *
'*          : All Rights Reserved                               *
'*  Date    : 29.07.2013                                        *
'*  Version : 1.0                                               *
'*  Notes   :                                                   *
'*          :                                                   *
'****************************************************************

#config
  __config _CONFIG1, _FOSC_INTOSC & _WDTE_OFF & _PWRTE_ON & _MCLRE_OFF & _CP_ON & _CPD_ON & _BOREN_OFF & _CLKOUTEN_OFF & _IESO_OFF & _FCMEN_OFF
  __config _CONFIG2, _WRT_ALL & _PLLEN_OFF & _STVREN_OFF & _LVP_OFF & _BORV_LO & _LVP_OFF
#ENDCONFIG


; 8mhz OSC  _________________________
DEFINE OSC 8
OSCCON= %01110000 
;_______________________________________


ANSELA=0
ANSELB=0
APFCON1=%00000000    
 APFCON0=%00000000
WPUB=255
WPUA=255

adcon0=0
adcon1=0
OPTION_REG.7=0

 TRISA=%00000000
TRISB=%11011000     
 
 ; orjinal
; ********  8 mhz de   9600 baud 8 N 1 ****************
DEFINE HSER_RCSTA 90h ; Enable serial port & continuous receive
DEFINE HSER_TXSTA 20h ;' Enable transmit, BRGH = 0
DEFINE HSER_CLROERR 1 ;' Clear overflow automatically
DEFINE HSER_SPBRGH 0
DEFINE HSER_SPBRG 51         ;++++++++++++  SPBRG  L olmalı +++++++++++++++++++++

BAUDCON= %01001000         ' Enable 16 bit baudrate generator

 
'________________________________saat değişkenleri________________________________________________ 
SCL var PORTB.1
SDA var PORTB.0
gossaat var byte
gosdak var byte

saatbak var byte
dakbak var byte
saat1d  var byte
saat2d  var byte
dak1d   var byte
dak2d   var byte
checktopla  var word
ch      var     byte
cl      var     byte
degeryaz    var byte
 bakchk    var byte

gosgun var byte
gosay var byte
GOSYIL VAR BYTE

TEMP VAR BYTE

saat var byte
dak var byte
sn var byte 
GUN VAR BYTE
AY VAR BYTE
YIL VAR BYTE
HAFGUN VAR BYTE


yon var byte
den var byte  
yer var byte
gosden var byte
yilarti var byte
hesap var byte
k var byte

bos var byte
SENSSAY VAR BYTE
datesay var byte

;clear 
   bakchk=1:degeryaz=0   ; bir kereye mahsus dfplayer'a reset atar
   if bakchk=1 then
checktopla=(65535-($FF+$06+$0C+$00+$00+degeryaz)+1)
 CH=checktopla.highbyte
CL=checktopla.lowbyte
 hserout [$7E,$FF,$06,$0C,$00,$00,degeryaz,ch,cl,$EF]
 
  bakchk=0
 pause 500
endif
 
pause 100
SEROUT2 PORTB.5,84,["LCDDD"]
 pause 100
 SEROUT2 PORTB.5,84,["LCDDD"]
 pause 100
 SEROUT2 PORTB.5,84,["LCDBO"]
 pause 25
 SEROUT2 PORTB.5,84,["LCDBL 6"]
 pause 250
;hserout [$7E,$FF,$06,$06,$01,$0,$14,$FE,$E0,$EF]
; PAUSE 200
; hserout [$7E,$FF,$06,$06,$01,$0,$14,$FE,$E0,$EF]
; PAUSE 200
; hserout [$7E,$FF,$06,$11,$01,$0,$01,$FE,$E8,$EF] ;7EFF611101FEE8EF
; PAUSE 200
; hserout [$7E,$FF,$06,$18,$01,$0,$0,$FE,$E2,$EF]  ; 7EFF618100FEE2EF
;  PAUSE 200
'--------------------------ANA PROGRAM--------------------------------------
 I2CWrite SDA,SCL,$D0,$07,[%00010000]

AYAR:
  SEROUT2 PORTB.5,84,["LCDCH"]
  pause 25
  while PORTB.6=0
wend
AYAR1:   

 
    GOSUB saatoku
    

  IF PORTB.6 =0 THEN 
  goto SAATAYAR1
endif   

     PAUSE 100
 '   i=0  :  Q=0
    GOTO AYAR1
'-------------------------GÖSTERGE AYAR KODLARI---------------------------------
SAATAYAR1 :
SEROUT2 PORTB.5,84,["LCDCB"]

pause 25
 SEROUT2 PORTB.5,84,["LCDWR 1,7-"]
While PORTB.6=0
wend
pause 25


saatayar:
temp=saat

yer=1

bak:  
if PORTB.6=0 then goto dakayar
if PORTB.3=0 then yon=1:goto saatayar2
if PORTB.4=0 then yon=2:goto saatayar2
goto bak

saatayar2:
if yon=2 then goto asagi
if temp>22 then 
temp=0
goto yazdir
else
temp=temp+1
goto yazdir
endif
goto bak 

asagi:
if temp=0 then temp=23:goto yazdir

if temp<2 then 
temp=0
goto yazdir
else 
temp=temp-1
goto yazdir
endif
GOTO BAK
'_______________________ saat ayarı sonu _______________

yazdir:
select case yer
case 1
den=7   ;$86
saat=temp
case 2
den=10  ;$89
dak=temp
case 3
den=7   ;$c6                  ; burada 2. satır için düzenleme yap c6 dediği yer 2. satır olacak.*****************
gun=temp
case 4
den=10  ;$c9
ay=temp
case 5
den=15  ;$Ce
yil=temp
end select


if yer<3 then 
SEROUT2 PORTB.5,84,["LCDWR 1,",dec2 DEN,"-",DEC2 TEMP]
pause 100
SEROUT2 PORTB.5,84,["LCDWR 1,",dec2 DEN,"-"]
pause 100    ;200
endif



if yer>2 then 
SEROUT2 PORTB.5,84,["LCDWR 2,",dec2 DEN,"-",DEC2 TEMP]
pause 100
SEROUT2 PORTB.5,84,["LCDWR 2,",dec2 DEN,"-"]
pause 100    ;200
endif

if yer=1 then goto bak
if yer=2 then goto bakdak
if yer=3 then goto gundak
if yer=4 then goto aydak
if yer=5 then goto yildak


'------------------- dakika ayar -----------------

dakayar:
yer=2
temp=dak

SEROUT2 PORTB.5,84,["LCDWR 1,10-"]
pause 25
While PORTB.6=0
wend


bakdak:
if PORTB.6=0 then goto yilayar
if PORTB.3=0 then yon=1:goto dakayar2
if PORTB.4=0 then yon=2:goto dakayar2
goto bakdak

dakayar2:
if yon=2 then goto dakasa
if temp>58 then 
temp=0
goto yazdir
else
temp=temp+1
goto yazdir
endif
 

dakasa:
if temp=0 then temp=59:goto yazdir
if temp<2 then 
temp=0
goto yazdir
else 
temp=temp-1
goto yazdir
endif


'----------------------- dakika ayar sonu __________________

'------------------- GUN ayar başlangıcı-----------------
gunayar:
yer=3
temp=gun
                
SEROUT2 PORTB.5,84,["LCDWR 2,7-"] 
               
While PORTB.6=0
wend

 gundak:
if PORTB.6=0 then 
gosub zaman_yaz

goto ayar
endif 

if PORTB.3=0 then yon=1:goto gunayar2
if PORTB.4=0 then yon=2:goto gunayar2
goto gundak

gunayar2:
if ay=1 or ay=3 or ay=5 or ay=7 or ay=8 or ay=10 or ay=12 then 
gosden=31
else
gosden=30
endif
if yon=2 then goto gunasa
if temp>gosden-1  then 
temp=1
goto yazdir
else
temp=temp+1
goto yazdir
endif

gunasa:
if temp<2 then 
temp=gosden
goto yazdir
else 
temp=temp-1
goto yazdir
endif


'----------------------- GUN ayar sonu __________________
'------------------- AY ayar Başlangıcı-----------------
ayayar:
yer=4
temp=ay
                  
SEROUT2 PORTB.5,84,["LCDWR 2,10-"]                    
pause 25
while PORTB.6=0
wend



aydak:
if PORTB.6=0 then goto gunayar
if PORTB.3=0 then yon=1:goto ayayar2
if PORTB.4=0 then yon=2:goto ayayar2
goto aydak

ayayar2:
if yon=2 then goto ayasa
if temp>11  then 
temp=1
goto yazdir
else
temp=temp+1
goto yazdir
endif

ayasa:
if temp<2 then 
temp=12
goto yazdir
else 
temp=temp-1
goto yazdir
endif


'----------------------- AY ayar sonu __________________
'------------------- YIL ayar Başlangıcı-----------------
yilayar:
yer=5
temp=yil
                                ;lcdout $fe,$ce
SEROUT2 PORTB.5,84,["LCDWR 2,15-"] 
pause 25
while PORTB.6=0
wend
                               

 yildak:

if PORTB.6=0 then goto ayayar
if PORTB.3=0 then yon=1:goto yilayar2
if PORTB.4=0 then yon=2:goto yilayar2
goto yildak

yilayar2:
if yon=2 then goto yilasa
if temp>98  then 
temp=0
yilarti=30
                        ;lcdout $fe,$cb,dec2 yilarti
goto yazdir
else
temp=temp+1
goto yazdir
endif


yilasa:
if yilarti=30 and temp=0 then 
yilarti=20
temp=99
                        ;lcdout $fe,$cb,dec2 yilarti
goto yazdir
endif
if temp<2 then 
temp=0
goto yazdir
else 
temp=temp-1
goto yazdir
endif



'---------------------------------SAAT OKU--------------------------------------
SAATOKU:

    I2CRead SDA, SCL,$D1,$00,[SN,DAK,SAAT,HAFGUN,GUN,AY,YIL,TEMP]
         BOS=((sn>>4) & $0F)*10+(SN & $0F):sn=BOS
         BOS=((DAK>>4) & $0F)*10+(DAK & $0F):DAK=BOS
         BOS=((SAAT>>4) & $0F)*10+(Saat & $0F):SAAT=BOS
         BOS=((GUN>>4) & $0F)*10+(GUN & $0F):GUN=BOS
         BOS=((AY>>4) & $0F)*10+(AY & $0F)  :AY=BOS
         BOS=((YIL>>4) & $0F)*10+(YIL & $0F):YIL=BOS

if bakchk=dak then 
else
call seslendir
bakchk=dak
endif



 atlaoku:
SEROUT2 PORTB.5,84,["LCDWR 1,1-","Hour:"," ",DEC2 saat,":",DEC2 dak,":",DEC2 sn ]

PAUSE 25
datesay=datesay+1:if datesay>5 then 
datesay=0

SEROUT2 PORTB.5,84,["LCDWR 2,1-","Date:"," ",DEC2 gun,".",DEC2 ay,".20",DEC2 YIL ]

PAUSE 25
endif
  RETURN

ZAMAN_YAZ:
hesap=YIL/4
k=status.0
if k=1 AND AY=2 AND GUN>28 then
GUN=28
ELSE

 if k=0 and ay=2 and gun>28 then 
    gun=29
    else
    endif
endif
;baslayaz: sn=00:dak=10:saat=13:gun=25:ay=6:YIL=17
        TEMP=(SN DIG 1)<<4+SN DIG 0:SN=TEMP
        TEMP=(DAK DIG 1)<<4+DAK DIG 0:DAK=TEMP
        TEMP=(SAAT DIG 1)<<4+SAAT DIG 0:SAAT=TEMP
        TEMP=(GUN DIG 1)<<4+GUN DIG 0:GUN=TEMP
        TEMP=(AY DIG 1)<<4+AY DIG 0:AY=TEMP
        TEMP=(YIL DIG 1)<<4+YIL DIG 0:YIL=TEMP

        I2CWrite SDA, SCL,$D1,$00,[SN,DAK,SAAT,HAFGUN,GUN,AY,YIL]
        PAUSE 10 

        return 
        
saatayir:

seslendir:
 
    saat1d=51:goto atlases

 atlases:
degeryaz=saat1d 
call checksum
pause 1000
saatbak=saat : temp=saat mod 10:saat2d=temp:temp=saat-temp:saat1d=temp

dakbak= dak  : temp=dak mod 10:dak2d=temp:temp=dak-temp:dak1d=temp

if saat1d=0 then 
    saat1d=53:goto atlases1
else 
    goto atlases1
endif
 atlases1:
degeryaz=saat1d 
call checksum
pause 700




if saat2d=0 then 
    saat2d=56:goto atlases2
else 
    goto atlases2
endif
 atlases2:
degeryaz=saat2d 
call checksum
pause 700



if dak1d=0 then 
    dak1d=53:goto atlases3
else
    goto atlases3
endif

atlases3:
degeryaz=dak1d 
call checksum
pause 700


if dak2d=0 then 
    dak2d=56:goto atlases4
else 
    goto atlases4 
endif

atlases4:
degeryaz=dak2d 
call checksum
pause 700
degeryaz=56


return

checksum:
checktopla=(65535-($FF+$06+$0F+$00+$02+degeryaz)+1)

CH=checktopla.highbyte
CL=checktopla.lowbyte
 hserout [$7E,$FF,$06,$0F,$00,$02,degeryaz,ch,cl,$EF]

return

end

 

Tüm dosyaları buradan alabilirsiniz. 

Arduino ile çalışması :

Android ile bluetooth çalışma :

DFPLAYER  SPK ile minimum donanım ile çalışması :

Konuşan saat +16F1827+DFplayer çalışması. ( Dikkat video sonuna ikinci video eklenmiştir. )


 

 

 

 

29 Comments

  1. DFPlayer alıp sizin sitenizi keşfettiğimden beri yazılarınızı izliyorum. Özellikle DFPlayer ile ilgili makaleniz benim için temel el kitabı gibi oldu.Teşekkürler.

    CCS C Compiler’de 16F628A+DFPLayer checksum hesaplaması için işin içinden çıkamadım. Problem aşağıda kodlar arasında yazılı. Ayrıca hesapla(0x11, 0, 1); şeklinde komut göndermede de başarılı olamadım.

    Diğer işler tamam I2C kütüphanesi ile LCD’ye yazdırıyorum RS232 ile DFPlayer’e komut gönderiyorum, UART ve DFPlayer kütüphaneleri üzerinde çalışıyorum. UART 16F628 ile uyumlu değil . Kaynağım:
    https://www.makerelectronico.com/dfplayer-mini-reproductor-mp3-interfaz-serial-uart/

    Yardımınız olursa sevinirim. Elimde iki tane 16F628A vardı. Onları değerlendirmek istedim. Gerçekleştirdiğim çalışmaları da sitemde arşiv niyetine yayınlıyorum. İyi günler dilerim.

    #include //kullanılacak pic#include
    #fuses XT,NOWDT,NOPROTECT,NOPUT,NOBROWNOUT //pic sigorta ayarları
    #use delay (clock=4000000)
    //#use I2C(master, I2C1, FAST = 100000, STREAM = I2C_LCD)
    #use i2c(Master,Fast,sda=PIN_B4,scl=PIN_B5,STREAM = I2C_LCD) //LCD ile haberleşmek için I2C protokolü
    #include //I2C LCD sürücü kaynak kodu
    //#bit RCIF=0xF9E.5
    //#include
    //#include

    #use RS232 (baud = 9600, bits = 8, parity = N, xmit = pin_b2, rcv = pin_b1) //DFPlayer ile haberleşmek için RS232 protokulü

    //————————————————————————————————————————-
    #define led1 pin_A2 // 1 nolu pin
    #define buton1 pin_A3 // 2 nolu pin (1k direnç ile gnd’ye) —buton +5v dan tetiklemeli

    //DFPlayer—————————————————————————————————————–
    # define Start_Byte 0x7E
    # define Version_Byte 0xFF
    # define Command_Length 0x06
    # define End_Byte 0xEF
    # define Acknowledge 0x00
    # define CMD 0x11
    # define Par1 0x00
    # define Par2 0x01
    int i=0;
    void hesap() {
    //int checksum=(65535-(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2))+1;
    int checksum=-(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);

    int value=checksum;
    int low=value & 0x00FF;
    int high=value>>8;

    //printf(“%i\n”,low);
    //printf(“%i\n”,high);

    //126,255,6,17,0,0,1,254,233,239
    //0x7E,0xFF,0X06,0X11,0X00,0X00,0X01,0XFE,0XE9,0XEF

    //——————————————————————– H A T A ———————————————————————————————-
    // alt satırda high ve low değerleri eklediğim yerde [Error 27…..Expression must evaluate to a constant ] hatası veriyor.
    // high yerine 254, low yerine 233 olarak direk desimal değer girince dfplayer’a komut gönderip çalıştırıyor.
    // dönüşümlerde bir hatam var da anlamadım…
    //
    //—————————————————————————————————————————————————————————————
    unsigned char komut_DFPlayer[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge, Par1, Par2, high,low, End_Byte};
    for (i=0;i<10;++i)
    {
    putc(komut_DFPlayer[i]); // komutu gönderiyoruz.
    }
    }

    void LCD_Baslat()
    {
    //setup_oscillator(OSC_4MHZ); // Set internal osilatör 4MHz-LCD için

    /*
    LCD_Begin(0x4E); // LCD modülünü I2C ile başlat address = 0x4E
    LCD_Goto(2, 1); // Sütun 2 satır 1'e git
    LCD_Out("Kodla Gitsin");
    LCD_Goto(2, 2);
    // Sütun 2 satır 2'ye git
    LCD_Out("DFPlayer");
    */
    }

    void play()
    {
    for (i=0;i<10;++i)
    {

    //putc(komut_DFPlayer[i]); // komutu DFPlayere gönderiyoruz.
    //printf("\n");
    }
    delay_ms(1000);
    }

    void main(void)
    {

    LCD_Baslat();
    delay_ms(1000);

    while(true){
    if (input(buton1) == 1) {

    output_high(led1); // kontrol amaçlı LED (LED 1 nolu pine 1k direnç ile bağlı)

    hesap();
    delay_ms(2000);
    output_low(led1); // kontrol amaçlı LED (LED 1 nolu pine 1k direnç ile bağlı)
    LCD_Baslat();
    }

    }

    }

  2. hata yazan yerde high low olarak değişken belirleyemezsiniz. bu sizin İDE nizde parametre olarak kullanılıyor olabilir. bunun yerine yuksek,dusuk olarak değişken tanımlayın derim. bu sanırım hata kısmına çözüm olabilir. bunun yanısıra aynı hata için bu forumda bir çözüm önerisi var sanırım değişken tanımlaması ile ilgili. ccs-c ile uğraşmadığımdan sorunu belirleyemiyorum. https://www.ccsinfo.com/forum/viewtopic.php?t=54123

    checksumda 2 formül var. hex ya da desimal hesaplama checksum formülünün başındaki 65535 ya da FFFF var. sizinkinde yok. benim tavsiyem önce verilmiş olan örnekleri kullanarak sonundaki checksum değerlerine siz kendiniz hesaplayarak ulaşabiliyormusunuz bir bakın sonrasında ise programınızda değişikliği yapın. şu andaki haliyle maalesef hesap tam değil. checksum formülüme bir daha bakın derim.

  3. Hocam Df player de aux giriş var mıdır. kulaklıga veya anfiye cıkış uçları usb de ama aux ses girişi var mıdır. Şundan dolayı soruyorum aux ses girişi varsa sd kartdan veya usb den çaldıgı müziği kapatacaktır.

    1. AUX girişi var. bu sayfada CMD komutlarında 0x09 olanın açıklamasına bakılırsa seçme durumu da var. fakat şu var ki modül yapılırken pin çıkarılmamış. . Gerçek te kullanılan entegreye bakıldığında modülde hangisi kullanılıyor bilemiyorum fakat internetteki şemalarında YX5200 kullanılıyor görünüyor. bu entegrenin datasheeti burada çince ama 5. sayfasında entegrenin bağlantı şemasına bakarsanız var olduğunu görürsünüz. Ayrıca AUX tan bile olsa giriş yapıldığında otomatik geçmiyor. aux seçmeniz gerekiyor. belki şu yapılabilir aux devresi çalıştığında işlemcinizi uyarır ve seri port üzerinden AUX bilgisi dfplayera gönderilir ve AUX girişi hızlı bir şekilde seçilmiş olur. AUX çıkışını hissedecek devre tv lerdeki scarttan video sinyali varmı diye seçen sistem gibi düşünün 0.5V gibi bir ses sinyali geldiğinde opamp bunu hisseder ve çıkışı 1 yapar ve mikroişlemci hemen seri bilgi gönderir ve dfplayer modülünü susturur ve aux girişine geçmesini sağlar. yani aux girişine sinyal verdiğinizde otomatik aux girişi seçilmesi sanırım olmuyor. pdf dosyası burada. MR.LED kişisinin yorumunda attach dosyalarında şema ve pdf var.
      https://www.eevblog.com/forum/microcontrollers/mp3-files-on-spi-flash-for-yx5200-24ss-mp3-chip/

  4. 10 adet waw dosyasını 10 adet harıcı butona baglayabılırmıyız arduıno olmadan ve ya arduınoyla.butona basınca atadıgım ses calıp kapanıcak basılı tutarsam tuttugum surece calıcak

    1. sayfanın başında dfplayer butonlu çizimler var. bunları kullanabilirsin. fakat basılı tuttuğum sürece dersen yanlış olur. basınca başlayacak bir daha stop butonuna ya da başka wav dosyasının anahtarına basman gerekir. ya da arduino kullanıp busy pininden alacağın bilgiye göre bitince diğeri baslar. arduino koyarsan zaten seri port üzerinden istediğini yapabilirsin yukarıda komutlar var.

  5. Güzel kardeşim çok detaylı ve güzel bir yazı olmuş. bende ek yapayım. bir fonksiyonu daha basitleştirelim. çünkü her seferinde hi byte low byte hesaplayıp göndermektense. komut gönderen fonksiyonu sadece iki parametreli yapıp

    void execute_CMD(byte CMD, int parameter)
    {
    byte par1 = highByte(parameter);
    byte par2 = lowByte(parameter);
    // Calculate the checksum (2 bytes)
    word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);
    // Build the command line
    byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,
    Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte};
    //Send the command line to the module
    for (byte k=0; k<10; k++)
    {
    mySerial.write( Command_line[k]);
    Serial.print( Command_line[k],HEX);
    }

    şeklinde bende çorbaya bir tuz katıyorum

    1. Teşekkür ederim yorumunuz için. Benim de beklentim buydu, eksik ya da yanlış bilgiler olursa burada yaptığınız gibi eklemeler yapıp arkadaşlara daha çok faydalı olabilmek.

  6. Merhabalar bdfplayer ile ses dosyası çaldım fakat çok ısınma oluyor ve bir yerden sonra yanıyor bir sebebi olabilir mi tam olarak nerden bu modülü sağlıklı bir şekilde alabilirm 2 adet aldım biri hiç çalışmadı aynı devrede diğeri çalıştı fakat aşırı isindi yardımcı olursanız sevinirim teşekkürler

    1. Yanmasinin sebebi kalitesiz olmasindan olmayabilir. Birincisi her ne Kadar 3.3v ve 5v dese de adaptor kullaniyorsaniz 5 voltun ustune kisa bir sure icin cikiyor olabilir ben denemelerimi powerbank ile yapiyorum ya da adaptor sonrasi regule dntegresi kullaniyorum. Bir sonraki secenek ise hoparlor 4 ya da 8 ohm diyorsa hoparlor gücü fazla olsun diye patalel baglarsaniz direnc duser cikisi yanarl bunun dn guzel cozumu ise dfplayerin kulaklik cikisini kullanip kulaklik baglamak ya da hoparlor cikisini lm380 ya da onun gibi kucuk tip amfilere baglamak burada bir hata yaparsan isinan entegre kucuk audio entegresi olur. Yani cikis bozulursa icindeki amfi entegresi isinir. Adaptorden dolayi oluyorsa dfplayer entegresi bozuluyordur. Benim adaptorle ilk enerji verdigimde pik gerilimden dolayi yanan entegrelerim oldu diyebilirim. Bundan dolayi powerbank ile deneme yapmaya basladim.

  7. Hocam emeğinize sağlık, bir soru sormak istiyorum. BDX53C darlington transistör ile RGB şerit ledleri kontrol ediyorum, öte yandan DFPlayer kullanarak, RF kumanda ile duruma göre müzik çalıp ledleri söndürmek veya terkar yakmak istiyorum ancak parazit sorunum var. (DFPlayer Amfiye bağlı) Ne yaparsam yapıyım devremdeki paraziti çözemedim, Ledler yandığı anda sürekli bir cızırtı alıyorum hoparlörden. Ücretli/ücretsiz destek verir misiniz 2 aydır bu proje ile uğraşıyorum çöpe gidecek proje rica ediyorum 🙁

    Devrem şu şekilde:

    https://i.ibb.co/2y11y75/devre.png

  8. Mailinizi yeni gördüm, çok teşekkür ediyorum hocam. Elimde bazı komponentler yok onları edindikten sonra deneyeceğim. Allah razı olsun

  9. Merhaba, bilgi için teşekkür ederiz, şunu sormak istiyorum otomatik oynatma seçeneği nasıl olacak, sürekli tekrarlamasını istiyorum, harici bağlantılarla,dosyasız.

    1. yukarıda harici butonlarla çalışma şekli belirtildi. SEG butonları hangi sıraya geldiyse onu oynatmak içindir. Yani 5. şarkının butonuna basarsanız o çalar. sanırım devamlı basılı olacak şekilde tutarsanız otomatik çalma başlar. Yorumlara da bakınız başka kişilerinde böyle istekleri var. Zaman içerisinde farklı şekilde çözmüş olabilirler.
      Kolay gelsin.

  10. Hocam bununla alakalı bir proje yapmak istiyorum amacımız müzik çalacak ve asansör katı söyleyecek fakat müzik katı söyledikten sonra aynı yerden devam etmeli bunu destekliyormu acaba yazınızı okudum fakat bunla alakalı bir bölüm bulamadım

    1. Bunun mümkün olabildiğini zannetmiyorum. fakat denenebilecek bir şey var. bu sayfada 016 komutu current track yazıyor durdurup aynı tracktan başlayabilir. Ya da bundan 2 tane yapıp ses seviyesini durdurup mute gibi diğeri kat kısmını söyler sonrasında müzik sesini açabilirsiniz. Bir de mikser gerekir. 2 ses katını ortak kullanmak için.
      Aynı modülü hem kat için hem de müzik için kullanacaksanız müzik en baştan başlar. Ya da radyo koyun. O devamlı çalsın bu sadece katları söylesin. Sadece ses kısmını kontrol edin. dijital ses kontrol entegreleri var. kolay gelsin.

  11. Hocam merhabalar, benim projemde dfplayer’a sd kart takılı onun içerisinde projede geçerli 4 tane ses var bunlar sabit. Ben şöyle bir şey istiyorum, mesela bir buton yaptım basınca Df playerdeki sd karttan ses çalacak ancak bu devreye bir tane de Bluetooth modülü koymak istiyorum yani gerektiğinde o hoparlörlerden müzik dinleyelim çünkü kocaman 2 tane hoparlör sadece 4 tane kısa sesi çalmak için boş yere yatacak. Araştırdığımda ise Bluetooth ses modülü var ama kimse bunu arduino ile kullanmamış. Yani ben bu modülden bir yanıt almak istiyorum, eğer Bluetooth’a bağlanıldıysa Dfplayer’deki sesi çalma telefondaki sesi çal gibi. Veya diyelim Bluetooth ile bağlandık telefondan çalıyoruz müziği ve devredeki tuşa bastık bu sefer o müziği durdurup sd karttki müziği çalsın. Bu sistem nasıl yapılabilir fikirlerinize ihtiyacım var 🙏🏻

    1. DFplayer da 2 yöntem var. birincisi dış ortam kontrolünde kullanabileceğiniz busy çıkışı. Busy demek şu anda dfplayer hoparlörü kullanıyor demektir. Yani busy çıkışı high olduğunda bir röle çeker ve ses devresini dfplayer’a bağlar. BUSY pimi LOW duruma geçince röle bırakarak telefon ses hattı hoparlöre bağlanır. Bu tabii ki basit olarak anlatılmak için. Röle ağır kalacağı için sesin bir kısmı duyulmayabilir bunun için 4051 gibi bir analog multiplexer devresi var bu kullanılabilir ya da bir transistörlü devre mikser gibi kullanılabilir. Ayrıca dfplayer dursun telefon devam etsin diyebilirsiniz mesela telefon geldi. dfplayer çalışmasın diyorsanız onu da dfplayer’ın PAUSE komutu var ( yukarıdaki komut açıklamalarında bulabilirsiniz) Bunu gönderip dfplayerı geçici olarak durdurabilirsiniz. PAUSE komutu verebileceğiniz gibi bir de anahtar ile bunu yapabilirsiniz. DFPLAYER butonlu çalışma resmine bakabilirsiniz. Yani hem dfplayerı geçici durdurabilirsiniz hem de busy pimini kullanarak dış devreyi kontrol edebilirsiniz.

  12. Merhaba,
    mp3 oynatıldığı veya oynatılmadığı durumda da busy sürekli 1 verisini gönderiyor.
    readCurrentFileNumber() fonksiyonu ise her iki durumda da -1 gönderiyoru. Isplaying yani parça çalıyormu durumuyla ilgili örnek paylaşabilir veya yönlendirebilir misiniz. Teşekkürler

    1. BUSY pini. Bu pin LOW ise hala ses dosyası oynatılıyor. HIGH ise ses dosyası duruyor demektir.
      Yukarıdaki gibi yazmışım. Bu denenmiş demektir. Fakat burada şöyle bir şey olabilir. GND çakışması. GND ler seri port üzerinden gelen GND ile Harici taktığınız power gnd leri birleşti mi.
      Ayrıca dfplayer bazı uçları bozuk olur diyeceğim ama modül çalışıyor. Bu pim de çalışması lazım. Şayet yanlışlıkla üzerinden yüksek bir akım geçmediyse. Bazen bazı arkadaşlar direkt kontrol çıkışına bağlarlar direnç olmadan bu şekilde yapıldıysa o pim çıkışı hasar almış olabilir.
      Bu gecikmiş cevap için özür dilerim.
      Kolay gelsin.

  13. Sanırım sadece numarasını alabiliyorsunuz. Fakat Arduino ile SD kart okuma yaptırıp gelen bilgileri numara ile eşleştirebiliyorsunuz. Her sd kart değişiminde tekrar okumanız gerekir. burada yapabileceğiniz kodlar var. bunlar sayfada cmd kodu olarak geçiyor. belki böyle bir ekran görüntüsü hazırlayabilirsiniz.

    0x42 The current status * [DH] = Device number [DL] = 0 no play, 1 play Anlık durum öğrenilir. DH ve DL bilgileri gösterir.
    0x43 The current volume * [DH]=0, [DL]= Volume (0x00-0x30) anlık ses durumunu gösterir. Gelen sayı HEX olarak gelir.
    0x44 The current EQ * [DH]=0, [DL]= EQ(0/1/2/3/4/5) [Normal/Pop/Rock/Jazz/Classic/Base] Ekolayzır durumunu öğren
    0x45 The current playback mode * [DH]=0, [DL]= (0x00: no CMD 0x08 used, 0x02: CMD 0x08 used, not usefull) Çalma durumunu öğren.
    0x46 The current software version * [DH]=0, [DL]= Software version. (My version is 5) yazılım versiyonunu öğren.
    0x47 The total number of U-disk files * [DH]=highByte(NUM), [DL]=lowByte(NUM). Not validated toplam şarkı sayısını gösterir. U-disk için
    0x48 The total number of TF-card files * [DH]=highByte(NUM), [DL]=lowByte(NUM) toplam şarkı sayısını gösterir. TF kart için
    0x49 The total number of flash files * [DH]=highByte(NUM), [DL]=lowByte(NUM). Not validated toplam şarkı sayısını gösterir. Flash için
    0x4A Keep on (Datasheet) ? Unknown. No returned parameter Bilinmiyor. Datasheet açıklama yapmıyor.
    0x4B The current track of U-Disk * [DH]=highByte(NUM), [DL]=lowByte(NUM), Current track on all media Kaçıncı şarkı çaldığını gösterir. U-disk ( benim modülde TF karta karşılık geliyor.) sizler diğer kodları deneyebilirsiniz.
    0x4C The current track of TF card * [DH]=highByte(NUM), [DL]=lowByte(NUM), Current track on all media Kaçıncı şarkı çaldığını gösterir. TF kart
    0x4D The current track of Flash * [DH]=highByte(NUM), [DL]=lowByte(NUM), Current track on all media Kaçıncı şarkı çaldığını gösterir. FLASH

  14. İyi çalışmalar hocam,
    Benim sorum, checksum hesabıyla ilgili. checksum hesabı yapmadan modülün bir çok özelliğini işlemci kullanarak kontrol ediyorum.checksum hesabı şartmı?bize getirisi nedir?
    bi formda checksum hesabıyla ilgili aşağıdaki bilgi paylaşılmış. Fakat ben bu hesabı anlayamadım(sayı sistemleri konusunda zayım ondan galiba) bu konuda yardımcı olabilirmisiniz.

    0X7E, 0xFF, 0x06, 0X03, 00, 00, 0x01, 0xFE, 0xF7 , 0XEF (10 bitten oluşan komut )

    buradaki fe ve f7 checksum byteları
    fe ve f7 yi bulmak için 2. 3. 4. 5. 6. 7. bytetaki değerleri toplayıp 0 dan çıkarmalısın.
    FF+06+03+00+00+01=0109
    0-0109=FE F7

    1. Merhaba modülün bir çok özelliğini kullandığınızı söylüyorsunuz sanırım bunu oradaki işlemcisiz kullanım için resimlerdeki butonları simüle ederek yapıyorsunuzdur.
      Şayet bunun yerine istediğiniz 1 şarkıyı seçmek için bir kod yollamanız gerekiyorsa mutlaka checksum kullanmanız gerek. Bu yazıda hangi komutları göndereceğinizi anlattığım gibi sd karttan nasıl şarkı seçeceğinizi de anlattım.
      Ayrıca CHECKSUM için ayrıntılı bilgi verdim ve kolay yolllarını gösterdim. Başka yerdeki bilgiye değil bu sayfadaki bilgiye bakarsanız kolaylıkla checksum değerine ulaşabilirsiniz.
      Yine de bilgi isterseniz buraya yazarsanız yanıtlamaya çalışırım.

  15. Merhaba, cevap için teşekkürler,
    Basic dilini kullanıyorum.Modülü işlemci kullanarak deniyorum.sd kartımda 20 adet mp3 ses dosyası var.bunları 001,002,003 gibi sıraladım.İlgili komutu gönderip 1.parça çalıyor sonra 2-3-4….gibi devam ediyor.Tek bir parçayı tekrarlatmak gibi özelliği aktif ediyorum.volum ayarını yapabiliyorum.ekolayzır özelliğini kullanabiliyorum.Başlangıç ses seviyesini seçebiliyorum gibi.bunların hiçbirinde checksum hesabı yapmadım. Anladığım kadarıyla dizinden bir şarkı seçmek için checksum hesabı gerekiyor gibi doğrumudur hocam?

    1. merhaba checksum konusunu araştırdım maalesef checksum olmadan diye bir şey yazmıyor. Fakat kullandığınız bir kütüphane varsa otomatik hesapladığı için sizin hesaplamanıza gerek kalmıyordur.

      Pic basic kullanıyorsanız programınızı 97safak@gmail.com adresine yollayabilir misiniz. Merak ettim. Nasıl bir komut yapısı kullanıyorsunuz.

      Checksum olmadan komutların iletilebileceğini internette dış kaynaklı dosyalarda da bulamadım. Ya da dfplayer yeni modül kullanıyor olabilirsiniz. Son versiyonda checksum iptal edilmiş olabilir.

      Belki de sizin vardığınız sonuç da doğru olabilir. Sadece sd karttan şarkı seçildiğinde gerekiyor olabilir denemedim ama sizin deneme sonuçlarınızı paylaşırsanız buraya sizi kaynak göstererek sonucu eklerim.

      Kolay gelsin.

    2. Şimdi bir açıklama buldum. Açıklama şudur.
      Normalde CHECKSUM ile ve CHECKSUM olmadan seri haberleşme yapılıyor.
      Fakat bazı devre kullanıcıları işlemcide kristal osilatör yerine internal osilatör ya da RC osilatör kullanıyorlar. Ayrıca seri haberleşme kablosunun uzunluğu da ve kullanıldığı yerde sorun olabilir. Bu durumlarda haberleşme de parazit olabiliyor.
      Bundan dolayı checksum kullanılırsa daha iyi olduğu söyleniyor.

      Yani kısacası siz devrenizden hatalı bir seri haberleşme komutu gitmeyeceğini düşünüyorsanız CHECKSUM kullanmadan da gönderebilirsiniz.

      Bende sayenizde öğrenmiş oldum.

      Fakat denemedim.. Yine de açıklama çok net olduğundan böyle olduğunu kabul ediyorum.

      Kolay gelsin.

      1. Merhaba,
        şehir dışında olduğumdan dolayı biraz gecikmeli cevap yazıyorum kusura bakmayın.kütüphane kullanmıyorum.pbp da kütüphane olayı yok zaten.Bahsettiğim proğram yanımda bulunan laptop da yok.dönüş yaptığımda mailinize göndereceğim.Sonuçları paylaşırsınız.

Bir cevap yazın

E-posta hesabınız yayımlanmayacak.