Skip to content

Commit 191a209

Browse files
authored
Add files via upload
0 parents  commit 191a209

File tree

15 files changed

+241
-0
lines changed

15 files changed

+241
-0
lines changed

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
MIT License
2+
3+
Copyright (c) 2022 redoxcode
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.
22+

README.md

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
## Description
2+
A micropython library to control the DFPlayer mini mp3 player module.
3+
4+
This library focuses on the most essential functions. Some advanced functions of the dfmini, like the equalizer modes are not implemented yet.
5+
6+
Further this library is made to use the folders function of the dfmini. You can use up to 99 folders and 255 files per folder.
7+
The files on your micro sd card need to be structured like this:
8+
9+
.
10+
├── 01
11+
│   ├── 001.mp3
12+
│   ├── 002.mp3
13+
│   └── ...
14+
├── 02
15+
│   ├── 001.mp3
16+
│   ├── 002.mp3
17+
│   └── ...
18+
├── 03
19+
│   ├── 001.mp3
20+
│   ├── 002.mp3
21+
│   └── ...
22+
└── ...
23+
24+
There should be no gaps in the numbering scheme.
25+
It might be best to prepare the whole file structure on your harddrive first and then copy them in one go on a freshly formated micro sd card, as the dfmini might get confused from artifacts left on the sd cards filesystem.
26+
You can use the files in /sample_files to test your module.
27+
28+
Sometimes the module isn't able to keep up if you try to send commands to fast, so some delay between the commands is needed.
29+
30+
## Examples
31+
32+
### Play a file from a folder
33+
```Python
34+
import time
35+
from dfplayer import DFPlayer
36+
df=DFPlayer(uart_id=1,tx_pin_id=4,rx_pin_id=5)
37+
#wait some time till the DFPlayer is ready
38+
time.sleep(0.2)
39+
#change the volume (0-30). The DFPlayer doesn't remember these settings
40+
df.volume(25)
41+
time.sleep(0.2)
42+
#play file ./01/001.mp3
43+
df.play(1,1)
44+
```
45+
### Find the number of files in a folder
46+
If a folder doesn't exist, get_files_in_folder will return -1
47+
```Python
48+
import time
49+
from dfplayer import DFPlayer
50+
df=DFPlayer(uart_id=1,tx_pin_id=4,rx_pin_id=5)
51+
#wait some time till the DFPlayer is ready
52+
time.sleep(0.2)
53+
print(df.get_files_in_folder(1))
54+
time.sleep(0.2)
55+
print(df.get_files_in_folder(4))
56+
```
57+
58+
## API
59+
### class DFPlayer(uart_id,tx_pin_id=None,rx_pin_id=None)
60+
- uart_id: Uart channel you want to use (0 or 1 for pi pico)
61+
- tx_pin_id: Pin id for uart tx if your board supports changing the pins of the uart channel.
62+
- tx_pin_id: Pin id for uart rx if your board supports changing the pins of the uart channel.
63+
64+
```play(folder,file)```
65+
Play a file from a folder (stops all previous playback)
66+
- folder: Folder number of the file you want to play
67+
- file: File number of the file you want to play
68+
69+
```stop()```
70+
Stop all playback
71+
72+
```volume(vol)```
73+
Set the volume of the module
74+
- vol: Volume of the module. The range is 0 to 30. The DFPlayer doesn't remember these settings
75+
76+
```get_volume()```
77+
Returns the current volume setting of the module
78+
79+
```ìs_playing()```
80+
Returns if currently some playback is running
81+
82+
```get_files_in_folder(folder)```
83+
Returns the number of files in a folder or -1 if the folder doesn't exist
84+
- folder: folder to get the number of files in
85+
86+
```reset()```
87+
Reset the module
88+
89+
```send_cmd(cmd,param1=0,param2=0)```
90+
Sends a command byte with 2 bytes for parameters to the module.
91+
This can be used to send commands not yet implemented in this library
92+
- cmd: cammand byte (0-255)
93+
- param1: parameter 1 or MSB of a 2 byte parameter
94+
- param2: parameter 2 or LSB of a 2 byte parameter
95+
96+
```send_query(cmd,param1=0,param2=0)```
97+
Like send_cmd, but returns the bytes the module sends as answer to the query
98+
- cmd: cammand byte (0-255)
99+
- param1: parameter 1 or MSB of a 2 byte parameter
100+
- param2: parameter 2 or LSB of a 2 byte parameter
101+

pyproject.toml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# pyproject.toml
2+
3+
[build-system]
4+
requires = ["setuptools>=61.0.0", "wheel"]
5+
build-backend = "setuptools.build_meta"
6+
7+
[project]
8+
name = "micropython-dfmini"
9+
version = "1.0.0"
10+
description = "Library to use the DFPlayer mini mp3 player module with micropython"
11+
readme = "README.md"
12+
authors = [{ name = "redoxcode", email = "[email protected]" }]
13+
license = { file = "LICENSE" }
14+
classifiers = [
15+
"License :: OSI Approved :: MIT License",
16+
"Programming Language :: Python :: Implementation :: MicroPython"
17+
]
18+
keywords = ["dfmini","dfplayer", "mp3"]
19+
dependencies = []
20+
21+
[project.optional-dependencies]
22+
dev = []
23+
24+
[project.urls]
25+
Homepage = "https://github.com/redoxcode/micropython-dfplayer"
26+
27+

sample_files/01/001.mp3

3.28 KB
Binary file not shown.

sample_files/01/002.mp3

2.77 KB
Binary file not shown.

sample_files/01/003.mp3

3.08 KB
Binary file not shown.

sample_files/02/001.mp3

3.92 KB
Binary file not shown.

sample_files/02/002.mp3

2.7 KB
Binary file not shown.

sample_files/02/003.mp3

3.59 KB
Binary file not shown.

sample_files/03/001.mp3

3.51 KB
Binary file not shown.

sample_files/03/002.mp3

4.13 KB
Binary file not shown.

sample_files/03/003.mp3

3.79 KB
Binary file not shown.

src/dfplayer/__init__.py

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
import machine
2+
import time
3+
4+
class DFPlayer:
5+
def __init__(self,uart_id,tx_pin_id=None,rx_pin_id=None):
6+
self.uart_id=uart_id
7+
#init with given baudrate
8+
self.uart = machine.UART(uart_id, 9600)
9+
10+
#not all boards can set the pins for the uart channel
11+
if tx_pin_id or rx_pin_id:
12+
self.tx_pin=machine.Pin(tx_pin_id,machine.Pin.OUT)
13+
self.rx_pin=machine.Pin(rx_pin_id,machine.Pin.IN)
14+
self.uart.init(9600, bits=8, parity=None, stop=1, tx=self.tx_pin, rx=self.rx_pin)
15+
else:
16+
self.uart.init(9600, bits=8, parity=None, stop=1)
17+
18+
def flush(self):
19+
while self.uart.any():
20+
self.uart.read()
21+
22+
def send_query(self,cmd,param1=0,param2=0):
23+
self.flush()
24+
self.send_cmd(cmd,param1,param2)
25+
time.sleep(0.05)
26+
return self.uart.read()
27+
28+
def send_cmd(self,cmd,param1=0,param2=0):
29+
out_bytes = bytearray(10)
30+
out_bytes[0]=126
31+
out_bytes[1]=255
32+
out_bytes[2]=6
33+
out_bytes[3]=cmd
34+
out_bytes[4]=0
35+
out_bytes[5]=param1
36+
out_bytes[6]=param2
37+
out_bytes[9]=239
38+
checksum = 0
39+
for i in range(1,7):
40+
checksum=checksum+out_bytes[i]
41+
out_bytes[7]=(checksum>>7)-1
42+
out_bytes[7]=~out_bytes[7]
43+
out_bytes[8]=checksum-1
44+
out_bytes[8]=~out_bytes[8]
45+
self.uart.write(out_bytes)
46+
47+
def stop(self):
48+
self.send_cmd(22,0,0)
49+
50+
def play(self,folder,file):
51+
self.stop()
52+
time.sleep(0.05)
53+
self.send_cmd(15,folder,file)
54+
55+
def volume(self,vol):
56+
df.send_cmd(6,0,vol)
57+
58+
def reset(self):
59+
df.send_cmd(12,0,1)
60+
61+
def is_playing(self):
62+
return df.send_query(66)[6]
63+
64+
def get_volume(self):
65+
return df.send_query(67)[6]
66+
67+
def get_files_in_folder(self,folder):
68+
in_bytes = df.send_query(78,0,folder)
69+
if in_bytes[3]!=78:
70+
return -1
71+
return in_bytes[6]
72+
73+
74+
df = DFPlayer(1,4,5)
75+
time.sleep(0.2)
76+
df.volume(30)
77+
#df.reset()
78+
time.sleep(1.0)
79+
print(df.get_files_in_folder(0))
80+
time.sleep(0.2)
81+
print(df.get_files_in_folder(1))
82+
time.sleep(0.2)
83+
print(df.get_files_in_folder(2))
84+
time.sleep(0.5)
85+
print(df.get_files_in_folder(3))
86+
time.sleep(0.5)
87+
print(df.get_files_in_folder(4))
88+
89+
#df.play(1,1)
90+
#time.sleep(0.5)
91+
#df.stop()

src/dfplayer/__main__.py

Whitespace-only changes.

tests/empty_file

Whitespace-only changes.

0 commit comments

Comments
 (0)