創作內容

10 GP

Arduino DFPlayer Mini BlueTooth MP3 Player

作者:貓貓風 ฅ●ω●ฅ│2019-10-12 00:57:19│巴幣:20│人氣:3401
.



















此篇為自己製作簡易的 藍芽 MP3 撥放器

需要材料如下

1. DFPlayer Mini : 用來對MP3檔案進行解碼並將訊號傳送至喇叭撥放

2. Arduino NANO: 用來對DFPlayer Mini進行通訊的 MCU
   也可使用 UNO 或 MEGA 等 都可以

3. 喇叭 : 用來撥放音頻訊號

4. Micro SD(1GB or 2GB): 儲存 MP3檔案

5. 藍芽模組 HC05 / HC06 : 進行指令接收,將收到指令給MCU做動作

DFPlayer Mini 簡介

·        DFPlayer Mini是一款小巧且價格低廉的MP3模組,可以直接接駁揚聲器。
·        模組配合供電電池、揚聲器、按鍵可以單獨使用,也可以通過串口控制,作為Arduino UNO或者是任何有串口的單片機的一個模組。
·        模組本身完美的集成了MP3WAVWMA的硬解碼。
·        同時軟體支援SD卡驅動,支援FAT16FAT32檔案系統。
·        通過簡單的串口指令即可完成播放指定的音樂,以及如何播放音樂等功能,無需繁瑣的底層操作,使用方便,穩定可靠。
產品參數
·        支持取樣速率(KHz):8/11.025/12/16/22.05/24/32/44.1/48
·        24位元DAC輸出,動態範圍支援:90dB,信噪比支持:85dB
·        完全支持FAT16FAT32檔案系統,最大支持32GSD卡,支持32GU盤、64M位元組  
         的 NORFLASH
·        多種控制模式可選。IO控制模式、串口模式、AD按鍵控制模式
·        廣播語插播功能,可以暫停正在播放的背景音樂。廣告播放完畢回到背景音繼續播放
·        音訊資料按資料夾排序,最多支援100個資料夾,每隔資料夾可以分配255首曲目
·        30級音量可調,6EQ可調

接線示意圖



以下程式主要功能
使用藍芽接收撥放指令,將儲存在SD卡的MP3由 DFPlayer Mini  給喇叭撥放
注意 MP3 命名只能為數字 1  2  3  副檔名為 .mp3   例如: 1.mp3
MP3放置路徑為  SD\MP3\   SD卡的 MP3資料夾裡面
或是依照程式指定不同路徑


  1.   
  2. #include "Arduino.h"  
  3. #include "SoftwareSerial.h"                    // 採用SoftwareSerial程式庫  
  4. #include "DFRobotDFPlayerMini.h"        // 採用DFRobotDFPlayerMini程式庫  
  5.   
  6. SoftwareSerial mySoftwareSerial(2, 3);
  7. //mySoftwareSerial(RX, TX),宣告軟體序列傳輸埠  
  8.                                                                  
  9. SoftwareSerial BT(10, 11);     
  10. // mySoftwareSerial(RX, TX), 宣告軟體序列傳輸埠  
  11.   
  12. DFRobotDFPlayerMini myDFPlayer;         //宣告MP3 Player  
  13. void printDetail(uint8_t type, int value);  //印出詳情  
  14.   
  15. // the setup function runs once when you press reset or power the board  
  16. void setup()   
  17. {  
  18.     Serial.begin(9600);            // 定義Serial Baud
  19.     mySoftwareSerial.begin(9600);  // 定義mySoftwareSerial baud
  20.   
  21.     Serial.println(F("DFRobot DFPlayer Mini Demo"));   
  22.     Serial.println(F("Initializing DFPlayer ... (May take 3~5 seconds)"));  
  23.     bool is_init_success = myDFPlayer.begin(mySoftwareSerial);  
  24.     BT.begin(9600);  
  25.     if (is_init_success == false)    // 如果DFPlayer Mini回應不正確.  
  26.     {  //Use softwareSerial to communicate with mp3.   
  27.         BT.println(F("Unable to begin:"));                      
  28.         BT.println(F("1.Please recheck the connection!"));  
  29.         BT.println(F("2.Please insert the SD card!"));  
  30.         while (true);                                       
  31.     }  
  32.      
  33.     BT.println(F("DFPlayer Mini online."));
  34. // 如果DFPlayer Mini回應正確.印出"DFPlayer Mini online."  
  35.     
  36.     myDFPlayer.setTimeOut(500); // 設定通訊逾時為500ms  
  37.   
  38.     //----Set volume----  
  39.     myDFPlayer.volume(20);     // 設定音量, 範圍0~30.   
  40.   
  41.     //----Set different EQ----  // 設定EQ(等化器 Equalizer)  
  42.     myDFPlayer.EQ(DFPLAYER_EQ_NORMAL);  
  43.   
  44.     //----Set device we use SD as default---- // 設定SD卡  
  45.     myDFPlayer.outputDevice(DFPLAYER_DEVICE_SD);  
  46.   
  47.     //----Mp3 control---- // 設定MP3參數  
  48.     //  myDFPlayer.sleep();            //sleep  
  49.     //  myDFPlayer.reset();            //Reset the module  
  50.       myDFPlayer.enableDAC();     //Enable On-chip DAC  
  51. }  
  52.   
  53. // the loop function runs over and over again until power down or reset  
  54. char val;    
  55. String recieveData = "";     
  56. void loop()   
  57. {  
  58.     if (myDFPlayer.available())  // 監視MP3有沒有回應  
  59.     {                                          // 有的話印出詳情  
  60.         printDetail(myDFPlayer.readType(), myDFPlayer.read());
  61.         //Print the detail message from DFPlayer to handle different errors and states.  
  62.     }  
  63.   
  64.     while(BT.available())  
  65.     {  
  66.        val=BT.read(); //每次接收一個字元    
  67.          
  68.        if(val == '\n')  
  69.        {  
  70.         Serial.println(recieveData);  
  71.             if(recieveData == "add\r")  
  72.           {  
  73.             myDFPlayer.volumeUp();   // 增加音量  
  74.             BT.println("volumeUp"); // clear buffer  
  75.             BT.read(); // clear buffer  
  76.             recieveData = "";  
  77.           }  
  78.           else if(recieveData == "sub\r")  
  79.           {  
  80.             myDFPlayer.volumeDown(); // 降低音量  
  81.             BT.println("volumeDown"); // clear buffer  
  82.             BT.read(); // clear buffer  
  83.             recieveData = "";  
  84.           }  
  85.            else if(recieveData == "POP\r")  
  86.           {  
  87.             myDFPlayer.EQ(DFPLAYER_EQ_POP);  
  88.             BT.println("POP MODE"); // clear buffer  
  89.             BT.read(); // clear buffer  
  90.             recieveData = "";  
  91.           }  
  92.            else if(recieveData == "ROCK\r")  
  93.           {  
  94.             myDFPlayer.EQ(DFPLAYER_EQ_ROCK);   
  95.             BT.println("ROCK MODE"); // clear buffer  
  96.             BT.read(); // clear buffer  
  97.             recieveData = "";  
  98.           }  
  99.            else if(recieveData == "JAZZ\r")  
  100.           {  
  101.             myDFPlayer.EQ(DFPLAYER_EQ_JAZZ);  
  102.             BT.println("JAZZ MODE"); // clear buffer  
  103.             BT.read(); // clear buffer  
  104.             recieveData = "";  
  105.           }  
  106.            else if(recieveData == "CLASSIC\r")  
  107.           {  
  108.             myDFPlayer.EQ(DFPLAYER_EQ_CLASSIC);  
  109.             BT.println("CLASSIC MODE"); // clear buffer  
  110.             BT.read(); // clear buffer  
  111.             recieveData = "";  
  112.           }  
  113.            else if(recieveData == "BASS\r")  
  114.           {  
  115.              myDFPlayer.EQ(DFPLAYER_EQ_BASS);  
  116.             BT.println("BASS MODE"); // clear buffer  
  117.             BT.read(); // clear buffer  
  118.             recieveData = "";  
  119.           }  
  120.            else if(recieveData == "Stop\r")  
  121.           {  
  122.             myDFPlayer.pause();  
  123.             BT.println("Stop"); // clear buffer  
  124.             BT.read(); // clear buffer  
  125.             recieveData = "";  
  126.           }  
  127.           else if(recieveData == "Start\r")  
  128.           {  
  129.             myDFPlayer.start();  
  130.             BT.println("Start"); // clear buffer  
  131.             BT.read(); // clear buffer  
  132.             recieveData = "";  
  133.           }  
  134.           else if(recieveData == "loopon\r")  
  135.           {  
  136.             myDFPlayer.enableLoop();  
  137.             BT.println("loop on"); // clear buffer  
  138.             BT.read(); // clear buffer  
  139.             recieveData = "";  
  140.           }  
  141.           else if(recieveData == "loopoff\r")  
  142.           {  
  143.             myDFPlayer.disableLoop(); //disable loop.  
  144.             BT.println("loop off"); // clear buffer  
  145.             BT.read(); // clear buffer  
  146.             recieveData = "";  
  147.           }  
  148.            else if(recieveData == "random\r")  
  149.           {  
  150.            myDFPlayer.randomAll(); //Random play all the mp3.  
  151.             BT.println("Random Mode"); // clear buffer  
  152.             BT.read(); // clear buffer  
  153.             recieveData = "";  
  154.           }  
  155.           else  
  156.           {  
  157.             int index = 1;  
  158.             for(int i = 1 ; i <= 255 ; i++)  
  159.             {  
  160.               if(i == recieveData.toInt())  
  161.               {  
  162.                  myDFPlayer.play(index);  
  163.                 BT.println(index); // clear buffer    
  164.                 while(BT.available())  
  165.                 {  
  166.                   BT.read(); // clear buffer  
  167.                 }  
  168.                 recieveData = "";  
  169.                  break;  
  170.               }  
  171.               index++;  
  172.             }  
  173.              recieveData = "";  
  174.           }  
  175.         break;  
  176.        }  
  177.        else  
  178.        {  
  179.          recieveData += val; //字元組成字串    
  180.        }  
  181.        delay(1);   
  182.     }  
  183.         
  184.       
  185. }  
  186.   
  187.   
  188. void printDetail(uint8_t type, int value)   
  189. {  
  190.     switch (type) {  
  191.     case TimeOut:  
  192.         Serial.println(F("Time Out!"));  
  193.         break;  
  194.     case WrongStack:  
  195.         Serial.println(F("Stack Wrong!"));  
  196.         break;  
  197.     case DFPlayerCardInserted:  
  198.         Serial.println(F("Card Inserted!"));  
  199.         break;  
  200.     case DFPlayerCardRemoved:  
  201.         Serial.println(F("Card Removed!"));  
  202.         break;  
  203.     case DFPlayerCardOnline:  
  204.         Serial.println(F("Card Online!"));  
  205.         break;  
  206.     case DFPlayerPlayFinished:  
  207.         Serial.print(F("Number:"));  
  208.         Serial.print(value);  
  209.         Serial.println(F(" Play Finished!"));  
  210.         break;  
  211.     case DFPlayerError:  
  212.         Serial.print(F("DFPlayerError:"));  
  213.         switch (value) {  
  214.         case Busy:  
  215.             Serial.println(F("Card not found"));  
  216.             break;  
  217.         case Sleeping:  
  218.             Serial.println(F("Sleeping"));  
  219.             break;  
  220.         case SerialWrongStack:  
  221.             Serial.println(F("Get Wrong Stack"));  
  222.             break;  
  223.         case CheckSumNotMatch:  
  224.             Serial.println(F("Check Sum Not Match"));  
  225.             break;  
  226.         case FileIndexOut:  
  227.             Serial.println(F("File Index Out of Bound"));  
  228.             break;  
  229.         case FileMismatch:  
  230.             Serial.println(F("Cannot Find File"));  
  231.             break;  
  232.         case Advertise:  
  233.             Serial.println(F("In Advertise"));  
  234.             break;  
  235.         default:  
  236.             break;  
  237.         }  
  238.         break;  
  239.     default:  
  240.         break;  
  241.     }  
  242. }  

藍芽傳送指令及撥放運行畫面與實際執行演示

先進行音量 跟模式調整後(等化器) 撥放 Eclipse.mp3




撥放曲目2  Parallel World  



相關 Arduino 創作





引用網址:https://home.gamer.com.tw/TrackBack.php?sn=4557364
All rights reserved. 版權所有,保留一切權利

相關創作

同標籤作品搜尋:涼涼風|Arduino

留言共 4 篇留言

雷穆斯
跪了OAO 這並不容易!
話說貓大您以前是學電路學或是資訊嗎?

10-15 23:28

貓貓風 ฅ●ω●ฅ
我沒學過電路喔 自己上網找資料學的10-15 23:35
[BOT]OTAKU
您好,最近正在查詢有關DFPlayer Mini的使用方式,Google搜尋到這篇,發現和網路上其他教程有一個相當大的差異,想請教一下有關的問題:
第162行: myDFPlayer.play(index);
這句在一般的教程中後面必定會加一句"delay();"而且一次delay就是整首歌的長度,導致整個執行序被卡死,在撥放過程中Arduino無法繼續接收其他指令(如IR Remote)。因為手邊沒有BT模組可以來測試,想請問:
1. 請問這組撥放器可以中途切歌嗎?亦即BT模組的接收在撥放過程中會不會被DFPlayerMini的play();卡死。
2. 如果可以的話,希望能請教一下是如何擺脫這個delay();的問題。

04-30 16:45

[BOT]OTAKU
來一段自己寫失敗的範例:
以下這段是透過IR Remote丟一組訊號給Arduino,讓if迴圈判斷是哪個值後決定撥放哪一首歌,如果沒有delay()的話,每loop()一次就會重複執行一次myDFPlayer.play(),然後撥放器沒聲音輸出。
if (irrecv.decode(&results))
{
Serial.println(results.value);
if(results.value == 16724175)
{
Serial.println(results.value);
myDFPlayer.play(1);
Serial.println("play 1");

}
else if (results.value == 16718055){
Serial.println(results.value);
myDFPlayer.play(2);
Serial.println("play 2");
}
else if (results.value ==16743045){
Serial.println(results.value);
myDFPlayer.play(3);
Serial.println("play 3");
}
else {

}
irrecv.resume(); // Receive the next value
}

04-30 16:51

貓貓風 ฅ●ω●ฅ
因為你接收沒延遲 可能會收到亂碼 所以不會達成條件04-30 21:56
[BOT]OTAKU
您好,感謝您的回答,經過一些測試之後過關了,我覺得DFPlayerMini的說明還真的有點少,很多Library的參數都必須自己一個一個去試錯啊。

05-02 09:17

貓貓風 ฅ●ω●ฅ
畢竟是簡易的MP3解碼器 本身的功能就不是很強05-04 09:47
我要留言提醒:您尚未登入,請先登入再留言

10喜歡★s1234567 可決定是否刪除您的留言,請勿發表違反站規文字。

前一篇:Python 使用執行緒... 後一篇:Monster Hunt...

追蹤私訊切換新版閱覽

作品資料夾

ShuLongQinHu給大家
小屋新增彩色插圖~大正浪漫,和服義大利+日本(APH)歡迎來看看看更多我要大聲說6小時前


face基於日前微軟官方表示 Internet Explorer 不再支援新的網路標準,可能無法使用新的應用程式來呈現網站內容,在瀏覽器支援度及網站安全性的雙重考量下,為了讓巴友們有更好的使用體驗,巴哈姆特即將於 2019年9月2日 停止支援 Internet Explorer 瀏覽器的頁面呈現和功能。
屆時建議您使用下述瀏覽器來瀏覽巴哈姆特:
。Google Chrome(推薦)
。Mozilla Firefox
。Microsoft Edge(Windows10以上的作業系統版本才可使用)

face我們了解您不想看到廣告的心情⋯ 若您願意支持巴哈姆特永續經營,請將 gamer.com.tw 加入廣告阻擋工具的白名單中,謝謝 !【教學】