Skip to content

Commit 655988d

Browse files
author
rdagger
committed
Initial commit
1 parent 991bbb2 commit 655988d

File tree

2 files changed

+343
-0
lines changed

2 files changed

+343
-0
lines changed

LICENSE

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) 2015
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+

jq6500.py

Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
"""Micropython serial library for JQ6500 mini MP3 module."""
2+
from machine import UART
3+
from time import sleep
4+
5+
6+
class Player(object):
7+
"""JQ6500 mini MP3 module."""
8+
9+
EQ_NORMAL = 0
10+
EQ_POP = 1
11+
EQ_ROCK = 2
12+
EQ_JAZZ = 3
13+
EQ_CLASSIC = 4
14+
EQ_BASS = 5
15+
16+
SRC_SDCARD = 1
17+
SRC_BUILTIN = 4
18+
19+
LOOP_ALL = 0 # Plays all the tracks and repeats.
20+
LOOP_FOLDER = 1 # Plays all the tracks in the same folder and repeats.
21+
LOOP_ONE = 2 # Plays the same track and repeats.
22+
LOOP_RAM = 3 # Unknown
23+
LOOP_ONE_STOP = 4 # Plays the track and stops.
24+
LOOP_NONE = 4
25+
26+
STATUS_STOPPED = 0
27+
STATUS_PLAYING = 1
28+
STATUS_PAUSED = 2
29+
30+
def __init__(self, port=2, volume=20):
31+
"""
32+
Constructor for JQ6500.
33+
34+
Args:
35+
port (int): UART port # (default: 2).
36+
volume(int) : Initial volume (default: 20, range 0-30).
37+
"""
38+
self.uart = UART(port, 9600)
39+
# Bug in UART loses first 2 bytes
40+
self.uart.write(bytes([0xEF, 0xEF]))
41+
self.uart.read()
42+
self.reset()
43+
self.set_volume(volume)
44+
45+
def clean_up(self):
46+
"""Clean up and release resources."""
47+
self.reset()
48+
if 'deinit' in dir(self.uart):
49+
self.uart.deinit()
50+
51+
def play(self):
52+
"""Play the current file."""
53+
self.write_bytes([0x0D])
54+
55+
def restart(self):
56+
"""Restart current playing or paused file from the beginning."""
57+
old_volume = self.get_volume()
58+
self.set_volume(0)
59+
self.next()
60+
self.pause()
61+
self.set_volume(old_volume)
62+
self.prev()
63+
64+
def pause(self):
65+
"""Pause the current file. Use play() to resume."""
66+
self.write_bytes([0x0E])
67+
68+
def next(self):
69+
"""Play the next file."""
70+
self.write_bytes([0x01])
71+
72+
def prev(self):
73+
"""Play the previous file."""
74+
self.write_bytes([0x02])
75+
76+
def next_folder(self):
77+
"""Play the next folder."""
78+
self.write_bytes([0x0F, 0x01])
79+
80+
def prev_folder(self):
81+
"""Play the previous folder."""
82+
self.write_bytes([0x0F, 0x00])
83+
84+
def play_by_index(self, file_index):
85+
"""
86+
Play file by FAT table index.
87+
88+
Args:
89+
file_index (int): File FAT table index number.
90+
91+
Notes:
92+
The index number has nothing to do with the filename.
93+
To sort SD Card FAT table, search for a FAT sorting utility.
94+
"""
95+
self.write_bytes([0x03, (file_index >> 8) & 0xFF, file_index & 0xFF])
96+
97+
def play_by_number(self, folder_number, file_number):
98+
"""
99+
Play file by folder number and file number.
100+
101+
Args:
102+
folder_number (int): Folder name number.
103+
file_number (int): Filename number.
104+
105+
Notes:
106+
Only applies to SD Card.
107+
To use this function, folders must be named from 00 to 99,
108+
and files must be named from 000.mp3 to 999.mp3.
109+
"""
110+
self.write_bytes([0x12, folder_number & 0xFF, file_number & 0xFF])
111+
112+
def volume_up(self):
113+
"""Increase volume by 1 (Volume range 0-30)."""
114+
self.write_bytes([0x04])
115+
116+
def volume_down(self):
117+
"""Decrease volume by 1 (Volume range 0-30)."""
118+
self.write_bytes([0x05])
119+
120+
def set_volume(self, level):
121+
"""
122+
Set volume to a specific level.
123+
124+
Args:
125+
level (int): Volume level (Volume range 0-30).
126+
"""
127+
assert(0 <= level <= 30)
128+
self.write_bytes([0x06, level])
129+
130+
def set_equalizer(self, mode):
131+
"""
132+
Set equalizer to 1 of 6 preset modes.
133+
134+
Args:
135+
mode (int): (EQ_NORMAL, EQ_POP, EQ_ROCK, EQ_JAZZ,
136+
EQ_CLASSIC, EQ_BASS).
137+
"""
138+
self.write_bytes([0x07, mode])
139+
140+
def set_looping(self, mode):
141+
"""
142+
Set looping mode.
143+
144+
Args:
145+
mode (int): (LOOP_ALL , LOOP_FOLDER, LOOP_ONE, LOOP_RAM,
146+
LOOP_ONE_STOP, LOOP_NONE).
147+
"""
148+
self.write_bytes([0x11, mode])
149+
150+
def set_source(self, source):
151+
"""
152+
Set source location of MP3 files (on-board flash or SD card).
153+
154+
Args:
155+
source (int): (SRC_SDCARD, SRC_BUILTIN).
156+
157+
Notes:
158+
SD card requires JQ6500-28P model.
159+
"""
160+
self.write_bytes([0x09, source])
161+
162+
def sleep(self):
163+
"""
164+
Put the device to sleep.
165+
166+
Notes:
167+
Not recommended for use with SD cards.
168+
"""
169+
self.write_bytes([0x0A])
170+
171+
def reset(self):
172+
"""
173+
Soft reset of the device.
174+
175+
Notes:
176+
Method is not reliable (especially with SD cards).
177+
Power-cycling is preferable.
178+
"""
179+
self.write_bytes([0x0C])
180+
sleep(.5)
181+
182+
def get_status(self):
183+
"""
184+
Get device status. (STATUS_PAUSED,STATUS_PLAYING, STATUS_STOPPED).
185+
186+
Notes:
187+
Only returns playing or paused with built-in flash.
188+
Method is unreliable with SD cardsself.
189+
"""
190+
self.write_bytes([0x42])
191+
status = self.read_bytes()
192+
return status
193+
194+
def get_volume(self):
195+
"""Get current volume level (0-30)."""
196+
self.write_bytes([0x43])
197+
level = self.read_bytes()
198+
return level
199+
200+
def get_equalizer(self):
201+
"""
202+
Get current equalizer mode.
203+
204+
(EQ_NORMAL, EQ_POP, EQ_ROCK, EQ_JAZZ, EQ_CLASSIC, EQ_BASS).
205+
"""
206+
self.write_bytes([0x44])
207+
eq = self.read_bytes()
208+
return eq
209+
210+
def get_looping(self):
211+
"""
212+
Get current looping mode.
213+
214+
(LOOP_ALL , LOOP_FOLDER, LOOP_ONE, LOOP_RAM, LOOP_ONE_STOP, LOOP_NONE).
215+
"""
216+
self.write_bytes([0x45])
217+
looping = self.read_bytes()
218+
return looping
219+
220+
def get_file_count(self, source):
221+
"""
222+
Return the number of files on the specified media.
223+
224+
Args:
225+
source (int): (SRC_SDCARD, SRC_BUILTIN).
226+
"""
227+
if source == self.SRC_SDCARD:
228+
self.write_bytes([0x47])
229+
else:
230+
# SRC_BUILTIN
231+
self.write_bytes([0x49])
232+
count = self.read_bytes()
233+
return count
234+
235+
def get_folder_count(self, source):
236+
"""
237+
Return the number of folders on the specified media.
238+
239+
Args:
240+
source (int): (SRC_SDCARD, SRC_BUILTIN).
241+
242+
Notes:
243+
Only SD cards can have folders.
244+
"""
245+
if source == self.SRC_SDCARD:
246+
self.write_bytes([0x53])
247+
count = self.read_bytes()
248+
return count
249+
else:
250+
return 0
251+
252+
def get_file_index(self, source):
253+
"""
254+
Get FAT file index of current file.
255+
256+
Args:
257+
source (int): (SRC_SDCARD, SRC_BUILTIN).
258+
259+
Notes:
260+
Refers to current playing or paused file. If stopped refers
261+
to the next file to play.
262+
"""
263+
if source == self.SRC_SDCARD:
264+
self.write_bytes([0x4B])
265+
count = self.read_bytes()
266+
return count
267+
else:
268+
# SRC_BUILTIN
269+
self.write_bytes([0x4D])
270+
count = self.read_bytes()
271+
return count + 1
272+
273+
def get_position(self):
274+
"""Get current position in seconds of current file."""
275+
self.write_bytes([0x50])
276+
position = self.read_bytes()
277+
return position
278+
279+
def get_length(self):
280+
"""Get length in seconds of current file."""
281+
self.write_bytes([0x51])
282+
length = self.read_bytes()
283+
return length
284+
285+
def get_name(self):
286+
"""
287+
Get the filename of the current file on the SD card.
288+
289+
Notes:
290+
SD card must be active source.
291+
"""
292+
self.write_bytes([0x52])
293+
return self.uart.read()
294+
295+
def get_version(self):
296+
"""Get version number."""
297+
self.write_bytes([0x46])
298+
version = self.read_bytes()
299+
return version
300+
301+
def read_bytes(self):
302+
"""Return 4 bytes from UART port."""
303+
b = self.uart.read(4)
304+
print(b)
305+
if len(b) > 0:
306+
return int(b, 16)
307+
else:
308+
return -1
309+
310+
def write_bytes(self, b):
311+
"""
312+
Write byte(s) to the UART port.
313+
314+
Args:
315+
b ([byte]): List of bytes to write to the UART port.
316+
"""
317+
message_length = len(b) + 1
318+
data = [0x7E, message_length] + b + [0xEF]
319+
# print (','.join('0x{:02X}'.format(x) for x in data))
320+
self.uart.read()
321+
self.uart.write(bytes(data))

0 commit comments

Comments
 (0)