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