@@ -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
4548uint16_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
5576bool 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)
156171bool 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
165188uint8_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
230254uint8_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
244270bool MY1690::pause (void )
@@ -266,18 +292,22 @@ bool MY1690::playPrevious(void)
266292// If a song is playing, then ~14ms later 'STOP' is reported
267293bool 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
283313bool 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
320351uint16_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
369411bool 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
0 commit comments