Skip to content

Commit 4a3d5fb

Browse files
committed
Update library to work with v1.1 ICs
1 parent 2357c58 commit 4a3d5fb

File tree

2 files changed

+88
-51
lines changed

2 files changed

+88
-51
lines changed

src/SparkFun_MY1690_MP3_Library.cpp

Lines changed: 85 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -32,37 +32,52 @@ bool MY1690::begin(Stream &serialPort, uint8_t pin)
3232
uint8_t x = 0;
3333
while (isConnected() == false)
3434
{
35+
while(1)
36+
;
3537
delay(100);
3638
if (x++ == 15)
3739
return (false);
3840
}
3941

40-
return (stopPlaying()); // Stop any playing tracks
42+
stopPlaying(); // Stop any playing tracks. Stop doesn't always return 'STOP' so don't return it
43+
44+
return (true);
4145
}
4246

43-
// Version response seems to have changed. Currently units are repsonding with '1.1'.
44-
// getVersion returns the rough interpretation of this string in int form. See getNumberReponse for more info.
47+
// Try to get the version number from the device
4548
uint16_t MY1690::getVersion(void)
4649
{
47-
commandBytes[0] = MP3_COMMAND_PLAY;
48-
// commandBytes[0] = MP3_COMMAND_GET_VERSION_NUMBER;
50+
commandBytes[0] = MP3_COMMAND_GET_VERSION_NUMBER;
51+
52+
// Sometimes it responds with 'OK1.1\r\n'
4953
sendCommand(1);
54+
if(getStringResponse("OK1.1\r\n") == true)
55+
return (101);
5056

51-
return (getNumberResponse());
57+
// Sometimes it responds with '1.1\r\n'
58+
sendCommand(1);
59+
if(getStringResponse("1.1\r\n") == true)
60+
return (101);
61+
62+
sendCommand(1);
63+
if(getStringResponse("OK1.0\r\n") == true)
64+
return (100);
65+
66+
sendCommand(1);
67+
if(getStringResponse("1.0\r\n") == true)
68+
return (100);
69+
70+
sendCommand(1);
71+
int version = getNumberResponse();
72+
return (version);
5273
}
5374

5475
// Verify the device responds correctly with a version number
5576
bool MY1690::isConnected(void)
5677
{
57-
uint16_t version = getVersion();
58-
if (version > 0 && version <= 0x101)
78+
int version = getVersion();
79+
if (version == 100 || version == 101)
5980
return (true);
60-
else if (version > 0x101)
61-
{
62-
Serial.print(F("Warning: Unknown MY1690 Protocol version: 0x"));
63-
Serial.println(version, HEX);
64-
return (true);
65-
}
6681

6782
return (false);
6883
}
@@ -156,10 +171,18 @@ bool MY1690::playTrackNumber(uint16_t trackNumber)
156171
bool MY1690::setVolume(uint8_t volumeLevel)
157172
{
158173
// Any number above 30 will be automatically set to 30 by MY1690
174+
// Trim value so return is true
175+
if(volumeLevel > 30)
176+
volumeLevel = 30;
177+
159178
commandBytes[0] = MP3_COMMAND_SET_VOLUME;
160179
commandBytes[1] = volumeLevel;
161180
sendCommand(2);
162-
return (getOKResponse());
181+
182+
// In v1.1, setVolume no longer responds with an OK. We must query it
183+
if (getVolume() == volumeLevel)
184+
return (true);
185+
return (false);
163186
}
164187

165188
uint8_t MY1690::getVolume(void)
@@ -227,18 +250,21 @@ bool MY1690::isPlaying(void)
227250
return (false);
228251
}
229252

253+
// Responds with '0000 \r\n' (note the space), '0001 \r\n', etc
230254
uint8_t MY1690::getPlayStatus(void)
231255
{
232256
commandBytes[0] = MP3_COMMAND_GET_STATUS;
233257
sendCommand(1);
234258
return (getNumberResponse());
235259
}
236260

237-
bool MY1690::play(void)
261+
void MY1690::play(void)
238262
{
239263
commandBytes[0] = MP3_COMMAND_PLAY;
240264
sendCommand(1);
241-
return (getOKResponse());
265+
266+
// In v1.1 there are no OK responses. Busy goes high after ~30ms.
267+
// User can also use the isPlaying() after 30ms to see if song has started
242268
}
243269

244270
bool MY1690::pause(void)
@@ -266,18 +292,22 @@ bool MY1690::playPrevious(void)
266292
// If a song is playing, then ~14ms later 'STOP' is reported
267293
bool MY1690::stopPlaying(void)
268294
{
269-
bool currentlyPlaying = isPlaying();
295+
//Use hardware pins or software command
296+
if (isPlaying() == false)
297+
return (true);
270298

271299
commandBytes[0] = MP3_COMMAND_STOP;
272300
sendCommand(1);
301+
302+
//v1.1 doesn't respond with OK or STOP, instead the isPlaying can be used
303+
//getOKResponse();
273304

274-
if (currentlyPlaying == false)
275-
return (getOKResponse());
305+
delay(10); // IC takes 5ms to stop a track
276306

277-
getOKResponse();
307+
if (isPlaying() == false)
308+
return (true);
278309

279-
// Wait 15ms for 'STOP' to come through
280-
return (getSTOPResponse());
310+
return (false);
281311
}
282312

283313
bool MY1690::reset(void)
@@ -314,46 +344,58 @@ bool MY1690::playPause(void)
314344
return (getOKResponse());
315345
}
316346

317-
// MY1690 responds with OK0004\n\r in ASCII to a get command
318-
// The ASCII response is HEX so OK000d is 14.
347+
// In version 1.1, sometimes MY1690 responds with '0000 \r\n' to a get command. No OK, and a space.
348+
// Sometimes 'OK0001 \r\n'. Ok, and a space. Yay!
349+
// In version 1.0 it was lower case letters. In v1.1, it's upper case HEX.
319350
// Convert the four letters to a decimal value
320351
uint16_t MY1690::getNumberResponse(void)
321352
{
322-
#define EXPECTED_LENGTH 8
353+
const uint8_t maxLength = 9;
354+
uint8_t okResponseOffset = 0;
355+
323356
if (responseAvailable() == false)
324357
return (0); // Timeout
325358

326359
// Get four byte response
327360
uint16_t responseValue = 0;
328361
uint8_t i = 0;
329362

330-
while (_serialPort->available() && i < EXPECTED_LENGTH)
363+
while (_serialPort->available() && i <= maxLength)
331364
{
332365
uint8_t incoming = _serialPort->read();
333-
if (i == 0 || i == 1)
334-
; // This is throw away value 'O' and 'K'
335-
else if (i >= 2 && i <= 5)
366+
if ((i == 0 && incoming == 'O') || (i == 1 && incoming == 'K'))
336367
{
337-
if (incoming != '\r' && incoming != '\n') // Added because version response is 3 characters long
368+
// Throw away chars
369+
370+
okResponseOffset = 2; // Increase scanning i by 2 more
371+
}
372+
else if (i <= (3 + okResponseOffset))
373+
{
374+
//Added because getVersion response is three characters long
375+
if (incoming != '\r' && incoming != '\n')
338376
{
339-
// Convert ASCII HEX values to decimal
340-
responseValue <<= 4;
341-
if (incoming >= '0' && incoming <= '9')
342-
responseValue += (incoming - '0');
343-
else if (incoming >= 'a' && incoming <= 'z')
344-
responseValue += (incoming - 'a') + 10;
377+
// Convert ASCII HEX values to decimal
378+
responseValue <<= 4;
379+
if (incoming >= '0' && incoming <= '9')
380+
responseValue += (incoming - '0');
381+
else if (incoming >= 'A' && incoming <= 'Z')
382+
responseValue += (incoming - 'A') + 10;
383+
else if (incoming >= 'a' && incoming <= 'z')
384+
responseValue += (incoming - 'a') + 10;
345385
}
346386
}
387+
else if (incoming == '\n')
388+
break; // End of response
347389
else
348390
{
349-
; // These are the \n \r characters
391+
; // Throw out \r and ' ' characters
350392
}
351393

352394
i++;
353395

354396
// The device can take a few ms between response chars
355397
uint8_t escapeCounter = 0;
356-
while (_serialPort->available() == 0 && i < EXPECTED_LENGTH)
398+
while (_serialPort->available() == 0 && i <= maxLength)
357399
{
358400
if (escapeCounter++ > 10)
359401
return (responseValue); // Give up
@@ -368,19 +410,14 @@ uint16_t MY1690::getNumberResponse(void)
368410
// MY1690 responds with OK (no \n \r) in ASCII to a control command
369411
bool MY1690::getOKResponse(void)
370412
{
371-
return (getStringResponse("OK", 2));
413+
return (getStringResponse("OK"));
372414
}
373415

374-
// MY1690 responds with STOP (no \n \r) in ASCII to stop command
375-
// if a song is currently playing
376-
bool MY1690::getSTOPResponse(void)
416+
// Returns true if MY1690 responds with a given string
417+
bool MY1690::getStringResponse(const char *expectedResponse)
377418
{
378-
return (getStringResponse("STOP", 4));
379-
}
419+
uint8_t expectedLength = strlen(expectedResponse);
380420

381-
// Returns true if MY1690 reponds with a given string
382-
bool MY1690::getStringResponse(const char *expectedResponse, uint8_t expectedLength)
383-
{
384421
if (responseAvailable() == false)
385422
return (false); // Timeout
386423

src/SparkFun_MY1690_MP3_Library.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ class MY1690
8787
bool begin(Stream &serialPort = Serial, uint8_t pin = 255);
8888

8989
// Control functions
90-
bool play(void);
90+
void play(void);
9191
bool pause(void);
9292
bool playNext(void);
9393
bool playPrevious(void);
@@ -129,9 +129,9 @@ class MY1690
129129
uint16_t getNumberResponse(void);
130130
bool getOKResponse(void);
131131
bool getSTOPResponse(void);
132-
bool getStringResponse(const char *expectedResponse, uint8_t expectedLength);
132+
bool getStringResponse(const char *expectedResponse);
133133

134-
bool responseAvailable(uint8_t maxTimeout = 50);
134+
bool responseAvailable(uint8_t maxTimeout = 100);
135135

136136
void clearBuffer(void);
137137
};

0 commit comments

Comments
 (0)