一位好友幫忙代購淘寶的電子零件,建議我買DFPlayer mini這個模組,可以用來播放mp3音樂。一看價格覺得還可以,就加到購物清單中。利用一點點空檔時間,實作一下如何使用這個模組。我找了程式範本只有控制音樂前進一首、暫停及後退一首三個按鍵,要調整音量,要在一開始時設定,再上傳程式,覺得很麻煩。我增加控制聲音按鍵並修改程式在播放音樂時可以調整音量。
除此,我想到使用Web的方式來調整音量、控制歌曲往前或往後一首歌,方法是使用 NodeMCU 連接DFPlayer Mini,建立一個網頁在ESP8266,透過網頁控制前後一首歌及音量,有空時再來動手做看看是否能成功。
DFPlayer mini產品規格:
DFPlayer mini 接腳說明:
DFPlayer Mini串列埠指令格式,這是要透過串列埠傳送給DFPlayer mini的指令,總共有10個(checksum分成高及低兩個位元),可參考以程式 execute_CMD()這段函式的內容,透過陣列方式,經由串列埠傳送10個參數給DFPlayer mini。
上述指令的第四個參數是CMD,可代入以下控制指令值來執行其功能,如0x01會讓DFPlayer mini跳到下一首歌。
如果要查詢DFPlayer mini的狀態,可以將上述CMD參數,代入以下控制指令值來執行其功能,如0x43會回應目前的音量值。
DFPlayer mini產品規格:
- 支持取樣速率(KHz):8/11.025/12/16/22.05/24/32/44.1/48
- 24位元DAC輸出,動態範圍支援:90dB,信噪比支持:85dB
- 完全支持FAT16、FAT32檔案系統,最大支持32G的TF卡,支持32G的U盤、64M位元組的NORFLASH
- 多種控制模式可選:IO控制模式、串口模式、AD按鍵控制模式
- 廣播語插播功能,可以暫停正在播放的背景音樂。廣告播放完畢回到背景音繼續播放
- 音訊資料按資料夾排序,最多支援100個資料夾,每隔資料夾可以分配255首曲目
- 模組可播放MP3、WAV、WMA三種格式硬體解碼
- 30級音量可調,6級EQ可調
DFPlayer mini的接腳圖,來源:dfrobot.com
DFPlayer mini 接腳說明:
| 接腳編號 | 接腳名稱 | 功能描述 | 備註 |
|---|---|---|---|
| 1 | VCC | 模組電源輸入 | 3.3V~5V,建議5V,不要超過5.2V |
| 2 | RX | UART串列資料接收 | |
| 3 | TX | UART串列資料輸出 | |
| 4 | DAC_R | 音訊輸出右聲道 | 驅動耳機、功率放大機 |
| 5 | DAC_L | 音訊輸出左聲道 | 驅動耳機、功率放大機 |
| 6 | SPK2 | 接小喇叭 | 驅動小於3W喇叭 |
| 7 | GND | 接地 | |
| 8 | SPK1 | 接小喇叭 | 驅動小於3W喇叭 |
| 9 | IO1 | 觸發口 | 預設上一曲(長按音量減) |
| 10 | GND | 接地 | |
| 11 | IO2 | 觸發口 | 預設下一曲(長按音量加) |
| 12 | ADKEY1 | AD口1 | 當觸發時是第一首(長按迴圈第一首) |
| 13 | ADKEY2 | AD口2 | 當觸發時是第五首(長按迴圈第五首) |
| 14 | USB+ | USB+ DP | 接USB拇指碟或插電腦的USB口 |
| 15 | USB- | USB- DM | 接USB拇指碟或插電腦的USB口 |
| 16 | Busy | 播放狀態 | 有音訊,輸出低;無音訊,輸出高 |
DFPlayer Mini串列埠指令格式,這是要透過串列埠傳送給DFPlayer mini的指令,總共有10個(checksum分成高及低兩個位元),可參考以程式 execute_CMD()這段函式的內容,透過陣列方式,經由串列埠傳送10個參數給DFPlayer mini。
| 指令名稱 | 對應功能 | 功能描述 |
|---|---|---|
| $S | 起始位0x7E | 每則命令回饋均以$開頭,即0x7E |
| VER | 版本 | 版本資訊[目前預設為0xFF] |
| Len | len後位元組個數 | checksum不計算在內 |
| CMD | 命令字 | 表示特定的操作,如播放/暫停等 |
| Feedback | 命令回饋 | 是否需要回饋資訊,1回饋,0不回饋 |
| para1 | 參數1 | 查詢的資料高位元組(比如歌曲序號) |
| para2 | 參數2 | 查詢的資料低位元組 |
| checksum | 校驗和[占兩個位元組] | 累加和校驗[不計起始位$] |
| $0 | 結束位 | 結束位0xEF |
上述指令的第四個參數是CMD,可代入以下控制指令值來執行其功能,如0x01會讓DFPlayer mini跳到下一首歌。
| CMD命令(指令) | 对应的功能 | 參數(16位) |
|---|---|---|
| 0x01 | 下一曲 | |
| 0x02 | 上一曲 | |
| 0x03 | 指定曲目(NUM) | 1-2999 |
| 0x04 | 音量+ | |
| 0x05 | 音量- | |
| 0x06 | 指定音量 | 0-30 |
| 0x07 | 指定EQ 0/1/2/3/4/5 | Normal/Pop/Rock/Jazz/Classic/Bass |
| 0x08 | 單曲迴圈指定曲目播放 | 1-2999 |
| 0x09 | 指定播放設備 1/2/3/4/5 | U盤/SD/AUX/SLEEP/FLASH |
| 0x0A | 進入休眠——低功耗 | |
| 0x0B | 保留 | |
| 0x0C | 模組重定 | |
| 0x0D | 播放 | |
| 0x0E | 暫停 | |
| 0x0F | 指定資料夾播放 | 1-10(需要自己設定) |
| 0x10 | 擴音設置(無) | [DH=1:開擴音][DL:設置增益0-31] |
| 0x11 | 全部迴圈播放 | [1:迴圈播放][0:停止迴圈播放] |
| 0x12 | 指定MP3資料夾曲目 | 1-9999 |
| 0x13 | 插播廣告 | 1-9999 |
| 0x14 | 支持15個資料夾 | 見下面的詳細說明 |
| 0x15 | 停止播放,播放背景 | |
| 0x16 | 停止播放 |
如果要查詢DFPlayer mini的狀態,可以將上述CMD參數,代入以下控制指令值來執行其功能,如0x43會回應目前的音量值。
| CMD指令詳解 | 功能說明 | 對應參數(16位元) |
|---|---|---|
| 0x3C | STAY | - |
| 0x3D | STAY | - |
| 0x3E | STAY | - |
| 0x3F | 發送初始化參數 | 0-0x0F(低四位元每位元代表一種設備) |
| 0x40 | 返回錯誤,請求重發 | - |
| 0x41 | 應答 | - |
| 0x42 | 查詢當前狀態 | - |
| 0x43 | 查詢當前音量 | - |
| 0x44 | 詢當前EQ | - |
| 0x45 | 查詢當前播放模式 | 該版本保留此功能 |
| 0x46 | 查詢當前軟體版本 | 該版本保留此功能 |
| 0x47 | 查詢UDISK的總文件數 | - |
| 0x48 | 查詢TF卡的總文件數 | - |
| 0x49 | 查詢FLASH卡的總文件數 | - |
| 0x4A | 保留 | - |
| 0x4B | 查詢UDISK的當前曲目 | - |
| 0x4C | 查詢TF的當前曲目 | - |
| 0x4D | 查詢FLASH的當前曲目 | - |
[材料]
- Arduino Uno x 1
- DFPlayer Mini 模組 x1
- 麵包板 x1
- 按鍵 x5
- 電阻 1K x1
- 喇叭 x1
- 連接線 n 條
[接線圖]
| Arduino Uno | DFPlayer Mini | 其他 |
|---|---|---|
| VCC | VCC | - |
| GND | GND | - |
| D10 | TX | - |
| D11 | 接一個1K歐姆的電阻後再接RX | - |
| D2 | - | 接按鍵1,按鍵另一端接地(前一首按鍵) |
| D3 | - | 接按鍵2,按鍵另一端接地(暫停/開始按鍵) |
| D4 | - | 接按鍵3,按鍵另一端接地(下一首按鍵) |
| D5 | - | 接按鍵4,按鍵另一端接地(升高音量按鍵) |
| D6 | - | 接按鍵5,按鍵另一端接地(降低音量按鍵) |
| - | SPK1 | 接喇叭一端 |
| - | SPK2 | 接喇叭另一端 |
[程式]
#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 buttonNext = 2;
int buttonPause = 3;
int buttonPrevious = 4;
int buttonVolumeUp = 5;
int buttonVolumeDown = 6;
boolean isPlaying = false;
void setup () {
pinMode(buttonPause, INPUT);
digitalWrite(buttonPause,HIGH);
pinMode(buttonNext, INPUT);
digitalWrite(buttonNext,HIGH);
pinMode(buttonPrevious, INPUT);
digitalWrite(buttonPrevious,HIGH);
pinMode(buttonVolumeUp, INPUT);
digitalWrite(buttonVolumeUp,HIGH);
pinMode(buttonVolumeDown, INPUT);
digitalWrite(buttonVolumeDown,HIGH);
mySerial.begin (9600);
delay(1000);
playFirst();
isPlaying = true;
}
void loop () {
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();
}
}
if (digitalRead(buttonVolumeUp) == ACTIVATED) //升高聲音鍵
{
if(isPlaying)
{
voiceup();
}
}
if (digitalRead(buttonVolumeDown) == ACTIVATED) //降低聲音鍵
{
if(isPlaying)
{
voicedown();
}
}
}
void playFirst()
{
execute_CMD(0x3F, 0, 0);
delay(500);
setVolume(20); // 初次播放的預設的音量
delay(500);
execute_CMD(0x11,0,1);
delay(500);
}
void pause()
{
execute_CMD(0x0E,0,0); //暫停播放
delay(500);
}
void play()
{
execute_CMD(0x0D,0,1); //播放音樂
delay(500);
}
void playNext()
{
execute_CMD(0x01,0,1); //播放下一首
delay(500);
}
void playPrevious()
{
execute_CMD(0x02,0,1); //播放前一首
delay(500);
}
void voiceup()
{
execute_CMD(0x04,0,1); //增加音量
delay(500);
}
void voicedown()
{
execute_CMD(0x05,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) {
// 計算checksum (2 bytes)
word checksum = -(Version_Byte + Command_Length + CMD + Acknowledge + Par1 + Par2);
// 建立命令列
byte Command_line[10] = { Start_Byte, Version_Byte, Command_Length, CMD, Acknowledge,
Par1, Par2, highByte(checksum), lowByte(checksum), End_Byte};
//送出命令列給模組
for (byte k=0; k<10; k++){
mySerial.write( Command_line[k]);
}
}


https://www.webteach.tw/?p=1204
回覆刪除這塊我也有玩,可以單獨使用很方便 多塊18650的 充放電板就可以當播放機。
我還以為要搭配控制板才可以用,原來只要電池供電就可以播放歌曲,學到經驗了,謝謝分享!
刪除你好
回覆刪除我想指定歌曲跟單曲迴圈指定曲目播放的功能,請問如何寫程式?
你好, 請問D11為什麼要先接電組再接到RX ??
回覆刪除張貼留言