最近有一位朋友因為想學習使用 Raspberry Pi Pico 及播放歌曲用途,所以還購買了一個播放模組
因此在下亦拜託朋友買多一個播放模組學習使用
因此在下亦拜託朋友買多一個播放模組學習使用
外觀
DFPlayer Mini 正面,有一個 Micro SD 卡糟
DFPlayer Mini 背面
GD3200B 是一種 音訊格式解碼晶片,其原生系列為 YX5200
可以存取 FAT16 及 FAT32 這兩種常見的檔案格式
及能夠將 WAV, MP3, WMA 3種常見音訊格式解碼
可以存取 FAT16 及 FAT32 這兩種常見的檔案格式
及能夠將 WAV, MP3, WMA 3種常見音訊格式解碼
8002 是一種 類比音訊增幅器
能夠驅動最高 3W的揚聲器
能夠驅動最高 3W的揚聲器
引腳
編號 | 引腳 | 方向 | 功能 |
---|---|---|---|
1 | VCC | 接受 3.3V 至 5V 電壓 | |
2 | RX | 輸入 | UART 序列輸入 |
3 | TX | 輸出 | UART 序列輸出 |
4 | DAC_R | 輸出 | 右側數碼音訊頻道 |
5 | DAC_L | 輸出 | 左側數碼音訊頻道 |
6 | SPK2 | 輸出 | 3W類比揚聲器終端2 |
7 | GND | 接地 | |
8 | SPK1 | 輸出 | 3W類比揚聲器終端1 |
9 | IO1 | 輸入 | IO操作模式1,詳細資料請參考 IO操作模式 |
10 | GND | 接地 | |
11 | IO2 | 輸入 | IO操作模式2,詳細資料請參考 IO操作模式 |
12 | AD1 | 輸入 | AD操作模式1,詳細資料請參考 AD操作模式 |
13 | AD2 | 輸入 | AD操作模式2,詳細資料請參考 AD操作模式 |
14 | USB+ | 讀取外接 USB 儲存裝置 D+ 線路 | |
15 | USB- | 讀取外接 USB 儲存裝置 D- 線路 | |
16 | BUSY | 輸出 | 高電壓為閒置狀態;低電壓為忙碌狀態 |
揚聲器
由於 DFPlayer Mini 只支援 3W或以下 的 揚聲器,因此在下從一個廢棄的 USB音箱 拆除一個 2W揚聲器
在下使用銅線焊接到 揚聲器終端
(在下使用的銅線表面有絕緣物料覆蓋,焊接及接駁前需要將絕緣物料去除才能使用)
(在下使用的銅線表面有絕緣物料覆蓋,焊接及接駁前需要將絕緣物料去除才能使用)
寫入檔案
DFPlayer Mini 會自動檢查 SD卡 中的 mp3 目錄
並會由 0000 至 9999 順序讀取 檔案名首4位數字 及 辨認副檔名為mp3,例如
如果只有數字,使用者一般情況下都無法記下所有檔案對應的曲目
而 DFPlayer Mini 只會處理 檔案名首4位數字,之後的檔案名並不理會
因此可以在 檔案名首4位數字 及 副檔名之間 的檔案名可以任意命名,例如
並會由 0000 至 9999 順序讀取 檔案名首4位數字 及 辨認副檔名為mp3,例如
0000.mp3 0001.mp3 0002.mp3 . . .
如果只有數字,使用者一般情況下都無法記下所有檔案對應的曲目
而 DFPlayer Mini 只會處理 檔案名首4位數字,之後的檔案名並不理會
因此可以在 檔案名首4位數字 及 副檔名之間 的檔案名可以任意命名,例如
0000-music-0.mp3 0001-music-1.mp3 0002-music-2.mp3 . . .
載入 SD卡
DFPlayer Mini 載入 SD卡 時, LED 會亮著,然後熄滅
IO操作模式
IO操作模式 是 DFPlayer Mini 最簡單的的操作模式
透過 2支IO引腳 接地時間長短 來執行 總共4個操作
透過 2支IO引腳 接地時間長短 來執行 總共4個操作
接地時間 | IO1 | IO2 |
---|---|---|
短 | 上一個項目 | 下一個項目 |
長 | 音量減少 | 音量增加 |
線路原型
IO操作模式 的線路
接駁線路
實際接駁線路
揚聲器的終端沒有區分極性,因此無需考慮方向
使用 按壓按鈕 連接 DFPlayer Mini 的 IO1引腳 及 IO2引腳 到 接地
測試線路
使用 紅色按鈕 將 IO1引腳 及 接地 連接
使用 白色按鈕 將 IO2引腳 及 接地 連接
短按 紅色按鈕, DFPlayer Mini 播放上一個項目
短按 白色按鈕, DFPlayer Mini 播放下一個項目
長按 紅色按鈕, DFPlayer Mini 音量減少
長按 白色按鈕, DFPlayer Mini 音量增加
使用 白色按鈕 將 IO2引腳 及 接地 連接
短按 紅色按鈕, DFPlayer Mini 播放上一個項目
短按 白色按鈕, DFPlayer Mini 播放下一個項目
長按 紅色按鈕, DFPlayer Mini 音量減少
長按 白色按鈕, DFPlayer Mini 音量增加
AD操作模式
AD操作模式 是 DFPlayer Mini 較進階的的操作模式
透過 2支AD引腳 連接的10種不同電阻值 來執行 總共20個操作
透過 2支AD引腳 連接的10種不同電阻值 來執行 總共20個操作
電阻值 | AD1 | AD2 |
---|---|---|
0Ω | Segment 1 | Segment 5 |
3KΩ | Segment 2 | Segment 6 |
6.2KΩ | Segment 3 | Segment 7 |
9.1KΩ | Segment 4 | Segment 8 |
15KΩ | 短接地為上一個項目;長接地為音量減少 | Segment 9 |
24KΩ | 短接地為下一個項目;長接地為音量增加 | Segment 10 |
33KΩ | 播放或暫停 | Segment 11 |
51KΩ | 循環播放 | Segment 12 |
100KΩ | 切換播放來源:USB、SD、SPI | Segment 13 |
200KΩ | 切換播放模式:全部、目錄、項目、隨機 | Segment 14 |
線路原型1
AD操作模式 的線路
線路原型2
由於 AD操作模式 所使用大部分電阻值都不是常見的電阻值,要符合指定電阻值是極不實際
雖然電阻值只是參考值,不需要絕對值,但又不知誤差範圍,因此在下改為使用電位器來調整電阻值來待替電阻器
接駁線路
實際接駁線路
使用 100KΩ電位器
測試線路
在下使用 萬用標 接駁到 電位器 來調整 15KΩ 、 24KΩ 及 33KΩ 測試
控制操作模式
DFPlayer Mini 除了使用 IO 及 AD引腳 控制播放器,還可以通過 序列訊號 讓 微控制器 操作
而 DFPlayer Mini 使用比較簡單的 通用非同步收發傳輸 (Universal Asynchronous Receiver Transmitter (UART)) 傳送訊號
但傳送的訊號並不簡單,而是一組頗繁複指令群
而 DFPlayer Mini 使用比較簡單的 通用非同步收發傳輸 (Universal Asynchronous Receiver Transmitter (UART)) 傳送訊號
但傳送的訊號並不簡單,而是一組頗繁複指令群
排序 | 指令 | 指令值 | 描述 |
---|---|---|---|
1 | 開始 | 0x7E | 傳送開始指令 |
2 | 版本 | 0xFF | 查詢版本資料,符合才可以運作 |
3 | 長度 | 0x06 | 版本、長度、功能、狀態、參數(高)、參數(低) 總共 6個指令 |
4 | 控制 | ? | 控制 DFPlayer 執行指定操作,詳細資料參考 控制指令 |
5 | 查詢 | ? | 查詢狀態資料:0 為不傳回;1 為傳回 如果需要傳回資料,微控制器的 RX引腳 要連接到 TX引腳 以接收資料 詳細資料參考 查詢指令 |
6 | 參數(高) | ? | 參數 的 第15至第8位元資料 |
7 | 參數(低) | ? | 參數 的 第7至第0位元資料 |
8* | 校驗和(高) | ? | 校驗和 的 第15至第8位元資料 |
9* | 校驗和(低) | ? | 校驗和 的 第7至第0位元資料 |
10 | 結束 | 0xEF | 傳送結束指令 |
* 校驗和 (Checksum) 是用作確保提交的資料一致
DFPlayer 的 校驗和 計算是一條簡單的方程式
再將 校驗和 分開為 高位元組 及 低位元組
DFPlayer 的 校驗和 計算是一條簡單的方程式
校驗和 = -(版本 + 長度 + 功能 + 狀態 + 參數(高) + 參數(低)) & 0xFFFF
再將 校驗和 分開為 高位元組 及 低位元組
校驗和(高) = (校驗和 & 0xFF00) >> 8 校驗和(低) = 校驗和 & 0x00FF
控制指令
功能 | 功能值 | 參數 |
---|---|---|
下一個項目 | 0x01 | |
上一個項目 | 0x02 | |
指定項目 | 0x03 | 0 至 9999 |
音量增加 | 0x04 | |
音量減少 | 0x05 | |
指定音量 | 0x06 | 0 至 30 |
指定EQ | 0x07 | 0 = Normal 1 = Pop 2 = Rock 3 = Jazz 4 = Classic 5 = Bass |
播放模式 | 0x08 | 0 = 全部循環播放 1 = 目錄循環播放 2 = 項目循環播放 3 = 隨機播放 |
播放來源 | 0x09 | 0 = USB 1 = SD 2 = Aux 3 = Sleep 4 = Flash |
關機 | 0x0A | |
重設 | 0x0C | |
播放 | 0x0D | |
暫停 | 0x0E | |
全部循環播放 | 0x11 | |
停止 | 0x16 |
如果需要發送 指定音量 的指令,先計算 校驗和
因此整個訊號為
共10組位元組訊號
-(0xFF + 0x06 + 0x06 + 0x00 + 0x00 + 0x00) & 0xFFFF # 校驗和 = 0xFEF5 # 校驗和(高) = 0xFE # 校驗和(低) = 0xF5
因此整個訊號為
0x7E 0xFF 0x06 0x06 0x00 0x00 0x00 0xFE 0xF5 0xEF
共10組位元組訊號
查詢指令
狀態 | 狀態值 | 參數 |
---|---|---|
音量 | 0x43 | |
EQ | 0x44 | |
播放模式 | 0x45 | |
版本 | 0x46 | |
USB 中項目的總數 | 0x47 | |
SD 中項目的總數 | 0x48 | |
已選擇 USB 項目的位置 | 0x4B | |
已選擇 SD 項目的位置 | 0x4C |
查詢指令 與 控制指令 相同,但查詢的訊號必須為 0x01
例如要查詢音量,指令應為
如果成功,會傳回一堆位元組資料,由於在下使用 CircuitPython 的 busio.uart 類別,會傳回 bytes 資料
例如查詢音量資料,會傳回
當中的 ~ (波紋號) 其實就是 \x7e ,而 \x06A 及 \x06C 其實分別是 \x06\x41 及 \x06\x43
即是傳回的訊號是
閣下應該會發現傳回的訊號與指令組非常相似,當中的 \x43 其實就是 查詢音量 的指令,之後的 \x00\x1E 就是音量值
因此要將傳回查詢資料,便需要檢查傳回的位元組陣列中,第3位元組 是否與 查詢指令 相同
如果相同,便將 第5位元組 及 第6位元組 傳回,就是要查詢的資料,即是
例如要查詢音量,指令應為
0x7E 0xFF 0x06 0x43 0x01 0x00 0x00 0xFE 0xB7 0xEF # 已計算校驗和
如果成功,會傳回一堆位元組資料,由於在下使用 CircuitPython 的 busio.uart 類別,會傳回 bytes 資料
例如查詢音量資料,會傳回
b'~\xff\x06A\x00\x00\x00\xfe\xba\xef~\xff\x06A\x00\x00\x00\xfe\xba\xef~\xff\x06A\x00\x00\x00\xfe\xba\xef~\xff\x06C\x00\x00\x1e\xfe\x9a\xef'
當中的 ~ (波紋號) 其實就是 \x7e ,而 \x06A 及 \x06C 其實分別是 \x06\x41 及 \x06\x43
即是傳回的訊號是
\x7E\xFF\x06\x41\x00\x00\x00\xFE\xBA\xEF \x7E\xFF\x06\x41\x00\x00\x00\xFE\xBA\xEF \x7E\xFF\x06\x41\x00\x00\x00\xFE\xBA\xEF \x7E\xFF\x06\x43\x00\x00\x1E\xFE\x9A\xEF
閣下應該會發現傳回的訊號與指令組非常相似,當中的 \x43 其實就是 查詢音量 的指令,之後的 \x00\x1E 就是音量值
因此要將傳回查詢資料,便需要檢查傳回的位元組陣列中,第3位元組 是否與 查詢指令 相同
如果相同,便將 第5位元組 及 第6位元組 傳回,就是要查詢的資料,即是
# 傳回 = (data[5] << 16) | data[6](注意:陣列由 0 開始)
收發訊號
控制操作模式 使用 UART 來收發訊號,DFPlayer Mini 的 RX引腳 為接收訊號,而 TX引腳 為發送訊號
如果只是單方使用 微控制器 向 DFPlayer Mini 發送控制訊號,只需要將 微控制器 的 TX引腳 接駁到 DFPlayer Mini 的 RX引腳 便可以
如果 微控制器 還需要向 DFPlayer Mini 查詢訊號,便需要將 微控制器 的 RX引腳 連接到 DFPlayer Mini 的 TX引腳
如果只是單方使用 微控制器 向 DFPlayer Mini 發送控制訊號,只需要將 微控制器 的 TX引腳 接駁到 DFPlayer Mini 的 RX引腳 便可以
如果 微控制器 還需要向 DFPlayer Mini 查詢訊號,便需要將 微控制器 的 RX引腳 連接到 DFPlayer Mini 的 TX引腳
由於 UART 只需一條訊號線便可以發送訊號,沒有時脈來區分高或低訊號
因此需要透過特定速度來讓收發訊號的裝置來確認內容
電子訊號速度用 鮑率 (Baudrate) 來判別
DFPlayer Mini 的 鮑率為 9600 ,即是 每1秒傳送9600位元 的速度
因此需要透過特定速度來讓收發訊號的裝置來確認內容
電子訊號速度用 鮑率 (Baudrate) 來判別
DFPlayer Mini 的 鮑率為 9600 ,即是 每1秒傳送9600位元 的速度
編程
由於 MicroPython 及 CircuitPython 已經內建 UART 的函式庫,不需要自己建立一套 UART 函式庫便可以立即操作
使用 MicroPython 的語法:
使用 CircuitPyhon 的語法:
在下使用 CircuitPython 亦製作一個簡單的函式庫讓 Raspberry Pi Pico 控制 DFPlayer Mini使用 MicroPython 的語法:
import machine id = 0 tx = 0 rx = 1 baudrate = 9600 bits = 8 parity = None uart = machine.UART(id, baudrate, bits, parity, tx, rx) data = [] # some byte array uart.write("".join(map(chr, data)))
使用 CircuitPyhon 的語法:
import board, busio tx = board.GP0 rx = baord.GP1 baudrate = 9600 bits = 8 parity = None uart = busio.UART(tx, rx, baudrate = baudrate, bits = bits, parity = parity) data = [] # some byte array uart.write(data)
import busio, time, board class DFPlayerMini: def __init__(self, tx, rx): self.__uart(tx, rx, baudrate = 9600, bits = 8, parity = None) def sendControl(self, command, parameterH, parameterL): byteArray = [0x7E, 0xFF, 0x06, command, 0x01, parameterH, parameterL, 0x00, 0x00, 0xEF] checksum = -(commands[1] + commands[2] + commands[3] + commands[4] + commands[5] + commands[6]) & 0xFFFF commands[7] = (checksum & 0xFF00) >> 8 commands[8] = checksum & 0x00FF self.__uart.write(bytes(byteArray)) time.sleep(0.1) dfPlayerMini = DFPlayerMini(board.GP0, board.GP1) dfPlayerMini.sendControl(0x01, 0x00, 0x00) # 控制 DFPlayer Mini 播放下一個項目
線路原型
在下使用 按壓按鈕 監察訊號狀態
如果使用 DM1微開關 ,便可以省卻 電阻器
如果使用 DM1微開關 ,便可以省卻 電阻器
接駁線路
雖然在下在原型中標示使用 10KΩ電阻器,但使用 1KΩ或以上的電阻器都可以
測試線路
使用控制操作模式可以將短按及長按的操作分離
載入 USB儲存裝置
由於普遍 USB儲存裝置都是 USB Type-A 插頭,要讓 DFPlayer Mini 連接到 USB儲存裝置,最好先製作 USB Type-A 的插孔
USB Type-A 引腳
編號 | 引腳 |
---|---|
1 | VCC |
2 | D- |
3 | D+ |
4 | GND |
USB Type-A 轉接器
在下自製的 USB Type-A 轉接器
連接 USB儲存裝置
(在下將印刷電路板上的文字標籤相反)
線路原型
在下使用 引腳座元件 待替 USB元件
接駁線路
由於在下通常只借用 USB轉接器 的電源引腳及接地引腳,很少使用所有 USB引腳
在辨認線路時經常弄錯 USB 的 D+引腳 及 D-引腳 (加上自己設計 USB轉接器 的電路板時亦弄錯標籤)
因此在下接駁到 USB 的線路是按照 USB 官方線路的顏色接駁,被免再次弄錯
在辨認線路時經常弄錯 USB 的 D+引腳 及 D-引腳 (加上自己設計 USB轉接器 的電路板時亦弄錯標籤)
因此在下接駁到 USB 的線路是按照 USB 官方線路的顏色接駁,被免再次弄錯
測試線路
在下將 USB 及 SD 同時連接到 DFPlayer Mini
透過切換 播放來源 後再選取播放的項目
但切換到指定 播放來源 後,播放項目到達盡頭後,不會自動切換 播放來源 ,而是在當前 播放來源 循環
透過切換 播放來源 後再選取播放的項目
但切換到指定 播放來源 後,播放項目到達盡頭後,不會自動切換 播放來源 ,而是在當前 播放來源 循環
補充資料
由於在下喜歡使用耳筒收聽,因此購買一個傳統的 3.5mm耳筒插孔
線路原型,只是不使用揚聲器,將 DAC_L 及 DAC_R 接駁到 3.5mm耳筒插孔 的 左聲道 及 右聲道
(習慣上,白線 為 左聲道,紅線 為 右聲道)
(習慣上,白線 為 左聲道,紅線 為 右聲道)
實際線路,如果只是測試用途,DAC_L 及 DAC_R 接反其實影響不大
另外接駁到 3.5mm耳筒插孔 還要接地,可以減少雜音
另外接駁到 3.5mm耳筒插孔 還要接地,可以減少雜音
由於只是由 揚聲器 改為 耳筒,因此在下沒有拍攝影片效果,與揚聲器沒有太大分別
總結
由於 DFPlayer Mini 已經發佈了一段長時間,只有 Arduino 的實作參與資料,官方亦只提供支援 Arduino 的函式庫
而 Raspberry Pi Pico 發佈至今只有 1年左右,在下在網絡上找不到相關的函式庫
不過 DFPlayer Mini 官方的文件亦不清晰,在下唯有先了解支援 Arduino 的函式庫後
反覆測試來製作支援 Raspberry Pi Pico 的函式庫
而 Raspberry Pi Pico 發佈至今只有 1年左右,在下在網絡上找不到相關的函式庫
不過 DFPlayer Mini 官方的文件亦不清晰,在下唯有先了解支援 Arduino 的函式庫後
反覆測試來製作支援 Raspberry Pi Pico 的函式庫
雖然 DFPlayer Mini 有提供 USB 線路,但同樣在網絡上找不到相關的實作
碰巧由於在下想方便地從電腦 USB 取電學習電子知識,因此曾經製作 USB轉接器,在這次實作中可以測試 USB儲存裝置
不過由於在下設計不良,最初接駁錯誤,導致燒毀了一支 USB
幸好並不貴重,只是用來製作 Linux Live USB ,亦沒有保存重要資料
碰巧由於在下想方便地從電腦 USB 取電學習電子知識,因此曾經製作 USB轉接器,在這次實作中可以測試 USB儲存裝置
不過由於在下設計不良,最初接駁錯誤,導致燒毀了一支 USB
幸好並不貴重,只是用來製作 Linux Live USB ,亦沒有保存重要資料
由於 IO操作模式 及 AD操作模式 都有一些操作會區分 短接地 及 長接地
但並沒有明確數據資料定義 接地時間 才算 短接地 或 長接地
因此在下用 time.sleep 以 100毫秒 遞增來測試 接地時間
最後發現當 接地時間 大於 775毫秒 便是 長接地,小於或等於 便是 短接地
如果認為 控制操作模式 過於複雜,可以使用 IO操作模式 或 AD操作模式 配合 接地時間 來達到基本操作效果
但並沒有明確數據資料定義 接地時間 才算 短接地 或 長接地
因此在下用 time.sleep 以 100毫秒 遞增來測試 接地時間
最後發現當 接地時間 大於 775毫秒 便是 長接地,小於或等於 便是 短接地
如果認為 控制操作模式 過於複雜,可以使用 IO操作模式 或 AD操作模式 配合 接地時間 來達到基本操作效果
在下將函式庫上載到 https://bitbucket.org/hkgoldenmra/raspberry-pi-pico-library/raw/7f06418a216b48a34131663133de67e4b4d31314/library/circuitpython/dfplayermini.py
有興趣可以下載並測試
有興趣可以下載並測試
沒有留言 :
張貼留言