YX5300 No acknowledge or unsolicited response

Hello!

I'm using a YX5300 for a simple audio project, but I've yet to get the module to send any response to my MEGA(clone 2560/16U2). The module is otherwise functional, I can play different tracks without issue. (Bonus minor issue: slight noise/chirping in the headphones when not playing, silenced by a light touch of a finger on the SD card slot)

I have tested 2 YX5300 modules, 3 serial ports on the MEGA, and 2 libraries (SerialMP3Player and MD_YX5300) using their examples (BasicCommands and MD_YX5300_Test) changing only the RX/TX pins. I have yet to receive anything back in the form of a command acknowledge or unsolicited message (finished playback, SD card insert/remove, etc) even though both libraries are capable of receiving the responses. I have also checked my hardware, moved the components to different breadboard locations and used different connectors.

What I get back what I issue a command through the serial monitor:

MD_YX5300:

>Play Track 1
Cback status: STS_OK, 0x0
Cback status: STS_TIMEOUT, 0x0

SerialMP3Player:

Play //Specific Track
Sending: 0X7e 0Xff 0X06 0X03 0X01 0X00 0X0a 0Xef 
Play //Play
Sending: 0X7e 0Xff 0X06 0X0d 0X01 0X00 0X00 0Xef 
// There should be 8 bits coming back after each command

The best part is I only need a few simple functions for my project:

  1. Play a single file at a time.
  2. Receive a "playback finished" signal.
  3. Maybe volume control if I'm feeling fancy.

I feel like I'm missing something obvious, but for my life of me, I can't seem to find it. Do I need to update the firmware on the MEGA?

Has anyone else experienced this?

Example Sketches:

MD_YX5300 - MD_YX5300_Test
// Test program for the MD_YX5300 library
//
// Menu driven interface using the Serial Monitor to test individual functions.
//
// Dependencies
// MD_cmdProcessor library found at https://github.com/MajicDesigns/MD_cmdProcessor
//

#ifndef USE_SOFTWARESERIAL
#define USE_SOFTWARESERIAL 1   ///< Set to 1 to use SoftwareSerial library, 0 for native serial port
#endif

#include <MD_YX5300.h>
#include <MD_cmdProcessor.h>

#if USE_SOFTWARESERIAL
#include <SoftwareSerial.h>

// Connections for serial interface to the YX5300 module
const uint8_t ARDUINO_RX = 15;    // connect to TX of MP3 Player module
const uint8_t ARDUINO_TX = 14;    // connect to RX of MP3 Player module

SoftwareSerial  MP3Stream(ARDUINO_RX, ARDUINO_TX);  // MP3 player serial stream for comms
#define Console Serial           // command processor input/output stream
#else
#define MP3Stream Serial2  // Native serial port - change to suit the application
#define Console   Serial   // command processor input/output stream
#endif

#define ARRAY_SIZE(a) (sizeof(a)/sizeof(a[0]))
#define CMD(s) { Console.print(F("\n>")); Console.print(F(s)); Console.print(F(" ")); }

// Define YX5300 global variables
MD_YX5300 mp3(MP3Stream);
bool bUseCallback = true; // use callbacks?
bool bUseSynch = false;   // use synchronous? 

void cbResponse(const MD_YX5300::cbData *status)
// Used to process device responses either as a library callback function
// or called locally when not in callback mode.
{
  if (bUseSynch)
    Console.print(F("\nSync Status: "));
  else
    Console.print(F("\nCback status: "));

  switch (status->code)
  {
  case MD_YX5300::STS_OK:         Console.print(F("STS_OK"));         break;
  case MD_YX5300::STS_TIMEOUT:    Console.print(F("STS_TIMEOUT"));    break;
  case MD_YX5300::STS_VERSION:    Console.print(F("STS_VERSION"));    break;
  case MD_YX5300::STS_CHECKSUM:   Console.print(F("STS_CHECKSUM"));    break;
  case MD_YX5300::STS_TF_INSERT:  Console.print(F("STS_TF_INSERT"));  break;
  case MD_YX5300::STS_TF_REMOVE:  Console.print(F("STS_TF_REMOVE"));  break;
  case MD_YX5300::STS_ERR_FILE:   Console.print(F("STS_ERR_FILE"));   break;
  case MD_YX5300::STS_ACK_OK:     Console.print(F("STS_ACK_OK"));     break;
  case MD_YX5300::STS_FILE_END:   Console.print(F("STS_FILE_END"));   break;
  case MD_YX5300::STS_INIT:       Console.print(F("STS_INIT"));       break;
  case MD_YX5300::STS_STATUS:     Console.print(F("STS_STATUS"));     break;
  case MD_YX5300::STS_EQUALIZER:  Console.print(F("STS_EQUALIZER"));  break;
  case MD_YX5300::STS_VOLUME:     Console.print(F("STS_VOLUME"));     break;
  case MD_YX5300::STS_TOT_FILES:  Console.print(F("STS_TOT_FILES"));  break;
  case MD_YX5300::STS_PLAYING:    Console.print(F("STS_PLAYING"));    break;
  case MD_YX5300::STS_FLDR_FILES: Console.print(F("STS_FLDR_FILES")); break;
  case MD_YX5300::STS_TOT_FLDR:   Console.print(F("STS_TOT_FLDR"));   break;
  default: Console.print(F("STS_??? 0x")); Console.print(status->code, HEX); break;
  }

  Console.print(F(", 0x"));
  Console.print(status->data, HEX);
}

void setCallbackMode(bool b)
{
  bUseCallback = b;
  CMD("Callback");
  Console.print(b ? F("ON") : F("OFF"));
  mp3.setCallback(b ? cbResponse : nullptr);
}

void setSynchMode(bool b)
{
  bUseSynch = b;
  CMD("Synchronous");
  Console.print(b ? F("ON") : F("OFF"));
  mp3.setSynchronous(b);
}


char * getNum(char *cp, uint32_t &v, uint8_t base = 10)
{
  char* rp;

  v = strtoul(cp, &rp, base);

  return(rp);
}

// Command processor handlers
void handlerHelp(char* param);

void handlerP_bang(char* param) { CMD("Play Start"); mp3.playStart(); cbResponse(mp3.getStatus()); }
void handlerPP(char* param)     { CMD("Play Pause"); mp3.playPause(); cbResponse(mp3.getStatus()); }
void handlerPZ(char* param)     { CMD("Play Stop");  mp3.playStop();  cbResponse(mp3.getStatus()); }
void handlerP_gt(char* param)   { CMD("Play Next");  mp3.playNext();  cbResponse(mp3.getStatus()); }
void handlerP_lt(char* param)   { CMD("Play Prev");  mp3.playPrev();  cbResponse(mp3.getStatus()); }

void handlerP(char* param)
{
  uint32_t t;
  
  getNum(param, t);
  CMD("Play Track");
  Console.print(t);
  mp3.playTrack(t);
  cbResponse(mp3.getStatus());
}

void handlerPT(char* param)
{
  uint32_t fldr, file;

  param = getNum(param, fldr);
  getNum(param, file);
  CMD("Play Specific Fldr");
  Console.print(fldr);
  Console.print(F(", "));
  Console.print(file);
  mp3.playSpecific(fldr, file);
  cbResponse(mp3.getStatus());
}

void handlerPF(char* param)
{
  uint32_t fldr;

  getNum(param, fldr);
  CMD("Play Folder");
  Console.print(fldr);
  mp3.playFolderRepeat(fldr);
  cbResponse(mp3.getStatus());
}

void handlerPX(char* param)
{
  uint32_t fldr;
  
  getNum(param, fldr);
  CMD("Play Shuffle Folder");
  Console.print(fldr);
  mp3.playFolderShuffle(fldr);
  cbResponse(mp3.getStatus());
}

void handlerPR(char* param)
{
  uint32_t file;

  getNum(param, file);
  CMD("Play File repeat");
  Console.print(file);
  mp3.playTrackRepeat(file);
  cbResponse(mp3.getStatus());
}


void handlerVM(char *param)
{
  uint32_t cmd;
  
  getNum(param, cmd);
  CMD("Volume Enable");
  Console.print(cmd);
  mp3.volumeMute(cmd != 0);
  cbResponse(mp3.getStatus());
}

void handlerV(char *param)
{
  uint32_t v;
  
  getNum(param, v);
  CMD("Volume"); 
  Console.print(v);
  mp3.volume(v); 
  cbResponse(mp3.getStatus());
}

void handlerV_plus(char* param)  { CMD("Volume Up");   mp3.volumeInc(); cbResponse(mp3.getStatus()); }
void handlerV_minus(char* param) { CMD("Volume Down"); mp3.volumeDec(); cbResponse(mp3.getStatus()); }

void handlerQE(char* param) { CMD("Query Equalizer");    mp3.queryEqualizer();   cbResponse(mp3.getStatus()); }
void handlerQF(char* param) { CMD("Query File");         mp3.queryFile();        cbResponse(mp3.getStatus()); }
void handlerQS(char* param) { CMD("Query Status");       mp3.queryStatus();      cbResponse(mp3.getStatus()); }
void handlerQV(char* param) { CMD("Query Volume");       mp3.queryVolume();      cbResponse(mp3.getStatus()); }
void handlerQX(char* param) { CMD("Query Folder Count"); mp3.queryFolderCount(); cbResponse(mp3.getStatus()); }
void handlerQY(char* param) { CMD("Query Tracks Count"); mp3.queryFilesCount();  cbResponse(mp3.getStatus()); }

void handlerQZ(char* param)
{
  uint32_t fldr;
  
  getNum(param, fldr);
  CMD("Query Folder Files Count");
  Console.print(fldr);
  mp3.queryFolderFiles(fldr);
  cbResponse(mp3.getStatus());
}

void handlerS(char *param) { CMD("Sleep");   mp3.sleep();  cbResponse(mp3.getStatus()); }
void handlerW(char *param) { CMD("Wake up"); mp3.wakeUp(); cbResponse(mp3.getStatus()); }
void handlerZ(char *param) { CMD("Reset");   mp3.reset();  cbResponse(mp3.getStatus()); }

void handlerE(char *param)
{
  uint32_t e;

  getNum(param, e);
  CMD("Equalizer");
  Console.print(e);
  mp3.equalizer(e);
  cbResponse(mp3.getStatus());
}

void handlerX(char *param)
{
  uint32_t cmd;

  getNum(param, cmd);
  CMD("Shuffle");
  Console.print(cmd);
  mp3.shuffle(cmd != 0);
  cbResponse(mp3.getStatus());
}

void handlerR(char* param)
{
  uint32_t cmd;

  getNum(param, cmd);
  CMD("Repeat");
  Console.print(cmd);
  mp3.repeat(cmd != 0);
  cbResponse(mp3.getStatus());
}

void handlerY(char *param)
{
  uint32_t cmd;
  
  getNum(param, cmd);
  setSynchMode(cmd != 0);
}

void handlerC(char * param)
{
  uint32_t cmd;

  getNum(param, cmd);
  setCallbackMode(cmd != 0);
}

const MD_cmdProcessor::cmdItem_t PROGMEM cmdTable[] =
{
  { "?",  handlerHelp,    "",     "Help", 0 },
  { "h",  handlerHelp,    "",     "Help", 0 },
  { "p!", handlerP_bang,  "",     "Play", 1 },
  { "p",  handlerP,       "n",    "Play file index n (0-255)", 1 },
  { "pp", handlerPP,      "",     "Play Pause", 1 },
  { "pz", handlerPZ,      "",     "Play Stop", 1 },
  { "p>", handlerP_gt,    "",     "Play Next", 1 },
  { "p<", handlerP_lt,    "",     "Play Previous", 1 },
  { "pt", handlerPT,      "f n",  "Play Track folder f, file n", 1 },
  { "pf", handlerPF,      "f",    "Play loop folder f", 1 },
  { "px", handlerPX,      "f",    "Play shuffle folder f", 1 },
  { "pr", handlerPR,      "n",    "Play loop file index n", 1 },
  { "v+", handlerV_plus,  "",     "Volume up", 2 },
  { "v-", handlerV_minus, "",     "Volume down", 2 },
  { "v",  handlerV,       "x",    "Volume set x (0-30)", 2 },
  { "vm", handlerVM,      "b",     "Volume Mute on (b=1), off (0)", 2 },
  { "qe", handlerQE,      "",     "Query equalizer", 3 },
  { "qf", handlerQF,      "",     "Query current file", 3 },
  { "qs", handlerQS,      "",     "Query status", 3 },
  { "qv", handlerQV,      "",     "Query volume", 3 },
  { "qx", handlerQX,      "",     "Query folder count", 3 },
  { "qy", handlerQY,      "",     "Query total file count", 3 },
  { "qz", handlerQZ,      "f",    "Query files count in folder f", 3 },
  { "s",  handlerS,       "",     "Sleep", 4 },
  { "w",  handlerW,       "",     "Wake up", 4 },
  { "e",  handlerE,       "n",    "Equalizer type n", 5 },
  { "x",  handlerX,       "b",    "Play Shuffle on (b=1), off (0)", 5 },
  { "r",  handlerR,       "b",    "Play Repeat on (b=1), off (0)", 5 },
  { "z",  handlerZ,       "",     "Reset", 5 },
  { "y",  handlerY,       "b",    "Synchronous mode on (b=1), off (0)", 6 },
  { "c",  handlerC,       "b",    "Callback mode on (b=1), off (0)", 6 },
};

MD_cmdProcessor CP(Console, cmdTable, ARRAY_SIZE(cmdTable));

// handler functions
void handlerHelp(char* param)
{
  Console.print(F("\n[MD_YX5300 Test]\nSet Serial line ending to newline."));
  CP.help();
  Console.print(F("\n"));
}

void setup()
{
  // YX5300 Serial interface
  MP3Stream.begin(MD_YX5300::SERIAL_BPS);
  mp3.begin();
  setCallbackMode(bUseCallback);
  setSynchMode(bUseSynch);

  // command line interface
  Console.begin(57600);
  CP.begin();
  CP.help();
}

void loop()
{
  CP.run();
  mp3.check();
}

SerialMP3Player - BasicCommands
/******************************************************************************
  Basic Commands examples for the SerialMP3Player YX5300 chip.

  Copy the files of "SDcard_example" to an empty SD card
  Connect the Serial MP3 Player to the Arduino board
    GND β†’ GND
    VCC β†’ 5V
    TX β†’ pin 11
    RX β†’ pin 10

  After compile and upload the code,
  you can test some basic commands by sending the letters
  ? - Display Menu options.
  P01 - Play 01 file
  F01 - Play 01 folder
  S01 - Play 01 file in loop
  p - play
  a - pause
  s - stop
  > - Next
  < - Previous
  ...

  Some commands like 'P' must be followed by two digits.

  This example code is in the public domain.

  https://github.com/salvadorrueda/ArduinoSerialMP3Player

  by Salvador Rueda
 *******************************************************************************/

#include "SerialMP3Player.h"

#define TX 16
#define RX 17

SerialMP3Player mp3(RX,TX);


void setup() {
  mp3.showDebug(1);       // print what we are sending to the mp3 board.

  Serial.begin(9600);     // start serial interface
  mp3.begin(9600);        // start mp3-communication
  delay(500);             // wait for init

  mp3.sendCommand(CMD_SEL_DEV, 0, 2);   //select sd-card
  delay(500);             // wait for init

  menu('?',0); // print the menu options.
}

 char c;  // char from Serial
 char cmd=' ';
 char cmd1=' ';


// the loop function runs over and over again forever
void loop() {

  if (Serial.available()){
    c = Serial.read();
    decode_c(); // Decode c.
  }
  // Check for the answer.
  if (mp3.available()){
    Serial.println(mp3.decodeMP3Answer()); // print decoded answers from mp3
  }
}

void menu(char op, int nval){
  // Menu
  switch (op){
    case '?':
    case 'h':
        Serial.println("SerialMP3Player Basic Commands:");
        Serial.println(" ? - Display Menu options. ");
        Serial.println(" P01 - Play 01 file");
        Serial.println(" F01 - Play 01 folder");
        Serial.println(" S01 - Play 01 file in loop");
        Serial.println(" V01 - Play 01 file, volume 30");
        Serial.println(" p - Play");
        Serial.println(" a - pause");
        Serial.println(" s - stop ");
        Serial.println(" > - Next");
        Serial.println(" < - Previous");
        Serial.println(" + - Volume UP");
        Serial.println(" - - Volume DOWN");
        Serial.println(" v15 - Set Volume to 15");
        Serial.println(" c - Query current file");
        Serial.println(" q - Query status");
        Serial.println(" x - Query folder count");
        Serial.println(" t - Query total file count");
        Serial.println(" r - Reset");
        Serial.println(" e - Sleep");
        Serial.println(" w - Wake up");
        break;

    case 'P':
        Serial.println("Play");
        mp3.play(nval);
        break;

    case 'F':
        Serial.println("Play Folder");
        mp3.playF(nval);
        break;

    case 'S':
        Serial.println("Play loop");
        mp3.playSL(nval);
        break;

    case 'V':
        Serial.println("Play file at 30 volume");
        mp3.play(nval,30);
        break;


    case 'p':
        Serial.println("Play");
        mp3.play();
        break;

    case 'a':
        Serial.println("Pause");
        mp3.pause();
        break;

    case 's':
        Serial.println("Stop");
        mp3.stop();
        break;

    case '>':
        Serial.println("Next");
        mp3.playNext();
        break;

    case '<':
        Serial.println("Previous");
        mp3.playPrevious();
        break;

    case '+':
        Serial.println("Volume UP");
        mp3.volUp();
        break;

    case '-':
        Serial.println("Volume Down");
        mp3.volDown();
        break;

    case 'v':
        Serial.println("Set to Volume");
          mp3.setVol(nval);
          mp3.qVol();
        break;

    case 'c':
        Serial.println("Query current file");
        mp3.qPlaying();
        break;

    case 'q':
        Serial.println("Query status");
        mp3.qStatus();
        break;

    case 'x':
        Serial.println("Query folder count");
        mp3.qTFolders();
        break;

    case 't':
        Serial.println("Query total file count");
        mp3.qTTracks();
        break;

    case 'r':
        Serial.println("Reset");
        mp3.reset();
        break;

    case 'e':
        Serial.println("Sleep");
        mp3.sleep();
        break;

    case 'w':
        Serial.println("Wake up");
        mp3.wakeup();
        break;
  }
}

void decode_c(){
  // Decode c looking for a specific command or a digit

  // if c is a 'v', 'P', 'F', 'S' or 'V' wait for the number XX
  if (c=='v' || c=='P' || c=='F' || c=='S' || c=='V'){
    cmd=c;
  }else{
    // maybe c is part of XX number
    if(c>='0' && c<='9'){
      // if c is a digit
      if(cmd1==' '){
        // if cmd1 is empty then c is the first digit
        cmd1 = c;
      }else{
        // if cmd1 is not empty c is the second digit
        menu(cmd, ((cmd1-'0')*10)+(c-'0'));
        cmd = ' ';
        cmd1 = ' ';
      }
    }else{
      // c is not a digit nor 'v', 'P', 'F' or 'S' so just call menu(c, nval);
      menu(c, 0);
    }
  }
}

Hardware Hookup:

+5V from MEGA

GND to MEGA

TX to MEGA RX3(15)

RX to MEGA TX3(14)

I suspect you mean bootloader not sketch. Your sketch is firmware. There is nothing to indicate the MEGA needs a new bootloader. I personally have at least 100 various boards and have NEVER done that.
I see it's been a while since you visited. You seem to have forgot we need to see a picture of YOUR hand drawn wiring NOT some instructions version, what you actually connected. Also you have to post all your source code Firts do an Auto Format (cmd/ctl T) then reply to tis and click the < CODE/ > on the top of the reply window then copy your code and paste in the reply. If there is any Serial log output that should also be posted in a code tag.

Thank you for the quick reply! Well, that is a relief!

My apologies! Since I couldn't get the examples sketches to work, I have not written anything myself. I've added everything to the main post.

Why two sketches, pick one and post in a NEW reply (editig OP is considered poor practice) also post any serial output (the ENTIRE log not snippets) Still waiting for a wiring diagram The reason this is critical that you look at your wires and draw them is that often doing that finds the error. Posting someone else's (instructions) wiring is useless.
I have no clue what your problem is, what we need is
What I did, what I expected and what actually happened.

Please explain the reason for using SoftwareSerial on a Mega 2560, a processor with 4 HardwareSerial ports.

Why two sketches?

If they are both having the same issue, the code probably is not the issue. I tried 2 modules, to remove the possibility of a defective module, so that was not the issue either. Multiple serial ports, connectors, etc to remove variables. I'm out of variables now, so I'm looking for help.

post in a NEW reply (editig OP is considered poor practice)

I was not aware of that, I'll do that going forward.

also post any serial output (the ENTIRE log not snippets)

SerialMP3Player - BasicCommands - Log
Sending: 0X7e 0Xff 0X06 0X09 0X01 0X00 0X02 0Xef 
SerialMP3Player Basic Commands:
 ? - Display Menu options. 
 P01 - Play 01 file
 F01 - Play 01 folder
 S01 - Play 01 file in loop
 V01 - Play 01 file, volume 30
 p - Play
 a - pause
 s - stop 
 > - Next
 < - Previous
 + - Volume UP
 - - Volume DOWN
 v15 - Set Volume to 15
 c - Query current file
 q - Query status
 x - Query folder count
 t - Query total file count
 r - Reset
 e - Sleep
 w - Wake up
Play //My input "p"
Sending: 0X7e 0Xff 0X06 0X0d 0X01 0X00 0X00 0Xef 
MD_YX5300 - MD_YX5300_Test - Log
F
? 	Help
h 	Help

p! 	Play
p n	Play file index n (0-255)
pp 	Play Pause
pz 	Play Stop
p> 	Play Next
p< 	Play Previous
pt f n	Play Track folder f, file n
pf f	Play loop folder f
px f	Play shuffle folder f
pr n	Play loop file index n

v+ 	Volume up
v- 	Volume down
v x	Volume set x (0-30)
vm b	Volume Mute on (b=1), off (0)

qe 	Query equalizer
qf 	Query current file
qs 	Query status
qv 	Query volume
qx 	Query folder count
qy 	Query total file count
qz f	Query files count in folder f

s 	Sleep
w 	Wake up

e n	Equalizer type n
x b	Play Shuffle on (b=1), off (0)
r b	Play Repeat on (b=1), off (0)
z 	Reset

y b	Synchronous mode on (b=1), off (0)
c b	Callback mode on (b=1), off (0)
>Play Start //My input "p! "
Cback status: STS_OK, 0x0
Cback status: STS_TIMEOUT, 0x0

Still waiting for a wiring diagram The reason this is critical that you look at your wires and draw them is that often doing that finds the error.

Diagram

Board

I have no clue what your problem is, what we need is
What I did, what I expected and what actually happened.

What I did:

  1. Installed a related library to the YX5300 module.
  2. Played a track
  3. removed and reinserted SD card

What I expected:

  1. For the track to play, to receive a command acknowledgement from the YX5300 module in the form of 8 bits, and to receive an unsolicited message that playback has finished.
  2. To receive a unsolicited message that the SD card hand been removed.
  3. To receive a unsolicited message that the SD card hand been reinserted.

What actually happened:

  1. The track played perfectly, but there was no command acknowledgement or unsolicited message.
  2. There was no unsolicited message.
  3. There was no unsolicited message.

What I have tried to fix it:

  1. Double check my wiring
  2. Move components to a different spot on the breadboard and check continuity on every connector.
  3. Use another library
  4. Use another YX5300 module
  5. Use another serial port on the MEGA
  6. Use another MEGA board

For whatever reason, I am not receiving anything from the module, even though the libraries state it will, the datasheet says it will, and other posts show that it does.

That is in an example sketch, not written by me. It seems that it was written in a way that a board with only 1 serial port(taken up by the USB to PC connection) could still use it. I figured that because of the if-statement above that line that decides to use the SoftwareSerial.h library or not.

Did you google 'MD YX5300'? Notice the Arduino refs, especially the ** UPDATE BELOW**. Also check this LINK
Since I am not able to follow your descriptions I will bow out after this post.

And what pins does Serial2 use on the Mega?

Since your code and description don't match up, I think I shall take my leave. Good luck.

Yes, I searched for everything related to the YX5300 and the libraries I am using. I saw that exact post, too. I am looking for the module to notify me that playback is finished. I do not want to control the playback once it has started.

Thank you for your help, anyway! What could I improve to make my descriptions clearer?

That was it!

I started with port 1 and changed to port 3, and skipped 2 entirely. Of course it was something tiny that I missed.

To be honest, I thought that was just a variable name. I'm not very familiar with coding outside of a function.

Thank you again!

Make sure to mark post 8 the solution so others benefit.