I'm building an arcade game which will be controlled by the Arduino Mega. I have successfully figured out how to play MP3 files on a single YX5300 using the SerialMP3Player library through pins 14 and 15 (TX3 and RX3). This MP3 player plays a tone when a target is hit. Now I want to turn my attention to adding a second YX5300 for the sole purpose of playing background music that will play continuously (and at a lower volume) during the entire game through a separate speaker. The tones from the first YX5300 will played through a separate speaker and at a volume much higher than the background music so they can be heard. Can someone direct me to an example that might help me out? I've looked and can't find a good comparison. Thanks.
the library is pretty poorly written as it hardcodes Serial3 or use SoftwareSerial (or let's say it was created with a UNO in mind and only one module connected)
probably best course of action would be to borrow the commands from that library and just apply to Serial1, Serial2 and Serial3 - you would be able to handle this way multiple modules (and keep Serial for debug)
In the beginning of your code, that you did not post, should be a line similar to:
SerialMP3Player mp3(RX,TX);
Where you create an instance of a SerialMP3Player object in a specific serial port. You can try creating more of these for other serial ports, of which the Mega has 4. Each object will need a different name. So you could name one bg_mp3, and another sfx_mp3, etc. Then use them at different times in the program.
if you look at the library, it does instantiate a SoftwareSerial object with the pins... not good...
Looked at the sample code. Didn't realize it was hard wired. Your solution is better.
Ok I'll give that a look. Thank you
Again the goal here is to be able to play 2 mp3 tunes at once on the Mega and the SerialMP3Player library doesn't support that. Per the above suggestion, I am attempting to pull out the code from this library and put it in my sketch. The YouTube video above shows how to do this with the ESP32 but it is not compatible with the Mega. I've got a good start to the code shown below but it won't compile. I have put messages in the code where you see the ***. Can anyone give me any coding advice here?
/*
Sketch for YX5300 MP3 module using Mega and multiple serial ports so that two tunes can play at same time throught their own speaker via one Mega Arduino
*/
#include <Arduino.h>
static int8_t Send_buf[8] = {0} ;
/* Byte Data Format
Byte 0 = [0x7e] - Every command starts with this
Byte 1 = [0xFF] - Version information
Byte 2 = [0xxx] - Number of bytes of he command without starting byte and ending byte
Byte 3 = [0xxx] - Command such as "Play"
Byte 4 = [0xxx] - 0x00 = not feedback, 0x02 = feedback (use 0000)
Byte 5 = [00xx] = 1st byte of data
Byte 6 = [00xx] = 2nd byte of data
Byte 7 = [0xEF] = Ending byte of the command
*/
#define DEV_TF 0X02 // Variable for TF card
//Byte 6 (opton 1) and 7 (option 2) data commands
#define CMD_SEL_DEV 0X09 // Sets storage device to TF card
#define CMD_PLAY_W_VOL 0X22
#define CMD_PLAY_W_INDEX 0X03
#define CMD_SET_VOLUME 0X06
#define CMD_PLAY_FOLDER_FILE 0X0F
#define CMD_STOP_PLAY 0X16
void setup() {
Serial.begin(9600);
// Serial2.begin(9600, SERIAL_8N1, 16, 17); *** NOTE: This was from ESP32 example that does not compile ***
Serial1.begin(9600); // Should be pins 18 & 19 // *** I added this code ***
Serial2.begin(9600); // Should be pins 16 & 17 // *** I added this code ***
delay(200);
sendCommand(CMD_SEL_DEV, 0, DEV_TF); // *** Compiler says "sendCommand not defined in this scope"
}
void loop() {
for (i=0; i<7; i++) {
sendCommand(PLAY_FOLDER_FILE 1,i); // plays 3 seconds of each of the 7 mp3 files in folder 1
delay(3000);
}
void sendCommand(byte command, byte option1, byte option_2) // defines sendCommand
delay(200);
Send_buff[0] = 0x7e; // Compiler error says "expected initializer before 'Send_buff' "
Send_buff[1] = 0xff;
Send_buff[2] = 0x06;
Send_buff[3] = command;
Send_buff[4] = 0x00;
Send_buff[5] = option1;
Send_buff[6] = option2;
Send_buff[7] = 0xef;
for (i = 0; i < 8; i++) {
Serial2.write(Send_buf[i]); // *** Not sure if Compiler will perform this ***
}
}
This is the documentation for the Yx5300 MP3 player
[https://geekmatic.in.ua/pdf/Catalex_MP3_board.pdf](https://YX5300 Documentation)
I’ll try to have a look at cleaning up the library later today if I get a chance (ie if weather gets bad
)
I rewrote the code to more closely resemble the SerialMP3Player library (e.g. variable names). I did get this code to compile. I will now see if it works...
/*
* Partial code taken from SerialMP3Player.h library - Library for Serial MP3 Player board from Catalex (YX5300 chip)
* Modified for Mega Arduino to play two tunes simultaneously from two separate YX5300 MP3 players
*/
// *********************************************************************** //
// Libraries
// *********************************************************************** //
#include <Arduino.h>
// *********************************************************************** //
// Variables for set up
// *********************************************************************** //
static int8_t Send_buf[8] = {0} ; // 8 byte variable to be sent to YX5300 MP3 player
unsigned long int command = 0; // variable to keep track of value for Byte 3 in string above
unsigned long int dat1 = 0; // variable to keep track of value for Byte 5 in string above
unsigned long int dat2 = 0; // variable to keep track of value for Byte 6 in string above
/* Byte Data Format from the YX5300 MP3 Player Documentation
Byte 0 = [0x7e] - Every command always starts with this
Byte 1 = [0xFF] - Version information which remains constant
Byte 2 = [0xxx] - Number of bytes of he command without starting byte and ending byte and is always 06 [0x06]
Byte 3 = [0xxx] - Command such as "Play" (see Byte 6 and 7 options below)
Byte 4 = [0xxx] - 0x00 = not feedback, 0x02 = feedback (use 0000)
Byte 5 = [00xx] = 1st byte of data(see options below)
Byte 6 = [00xx] = 2nd byte of data (see options below)
Byte 7 = [0xEF] = Ending byte of the command remains constant
Resulting byte string is [0x7e] [0xff] [0x06] [Command] [dat1] [dat2] [0xEF]
*/
void setup() {
Serial2.begin(9600); // Mega Arduino pins TX16 & RX17
delay(200);
// Initialization required for YX5300 to direct to storage device
command = 0x09; // Sets YX5300 storage device to TF card
dat1 = 0x00; // Default settings for TF card initialization
dat2 = 0x00; // Default settings for TF card initialization
// Command Structure 0x7E 0xFF 0x06 CMD FBACK DAT1 DAT2 0xEF
Send_buf[0] = 0x7E; // Start byte
Send_buf[1] = 0xFF; // Version
Send_buf[2] = 0x06; // Command length not including Start and End byte.
Send_buf[3] = command; // Command
Send_buf[4] = 0x00; // Feedback 0x00 NO, 0x01 YES
Send_buf[5] = dat1; // DATA1 datah
Send_buf[6] = dat2; // DATA2 datal
Send_buf[7] = 0xEF; // End byte
for(int i=0; i<8; i++) {
Serial2.write(Send_buf[i]); //Sends 8 byte instruction code to YX5300
}
}
void loop() {
// Sample loop to play YX5300
command = 0x22; // Play with volume
dat1 = 0x01; // 1st file on micro SD card
dat2 = 0x30; // Volume of 30
// Command Structure 0x7E 0xFF 0x06 CMD FBACK DAT1 DAT2 0xEF
Send_buf[0] = 0x7E; // Start byte
Send_buf[1] = 0xFF; // Version
Send_buf[2] = 0x06; // Command length not including Start and End byte.
Send_buf[3] = command; // Command
Send_buf[4] = 0x00; // Feedback 0x00 NO, 0x01 YES
Send_buf[5] = dat1; // DATA1 datah
Send_buf[6] = dat2; // DATA2 datal
Send_buf[7] = 0xEF; // End byte
for(int i=0; i<8; i++) {
Serial2.write(Send_buf[i]); //Sends 8 byte instruction code to YX5300
}
}
OK - let us know if you need more eyes looking at this
I rewrote the code a bit and got it to compile (again). Now I've hooked up the Mega and YX5300 player and the code doesn't get the YX5300 player to play anything. The LED on the YX5300 board is a solid red. Based on prior experience, this means it's not getting correct instruction. When I had it working before it blinked the red LED. Here is the most recent code that I need help with.
For starters, this information will be helpful...
-
Board = Mega 2560 R3
-
YX5300 MP3 Player #1 TX wired to Mega RX1 (pin 19) RX wired to Mega TX1 (pin 18)
-
YX5300 MP3 Player #2 TX wired to Mega RX2 (pin 17) RX wired to Mega TX2 (pin 16)
-
Storage device on each YX5300 is a micro SD card. They are formated to FAT32. There are 2 files in the parent directory labeled "01" and "02". In file 01, there are 10 mp3 files.
-
Arduino library SoftSerial.h utilized to help designate serial ports 1 and 2 for Mega
-
Sketch utilizes int8_t Send_buf[8] to set up an 8 byte variable to pass commands to YX5300
-
The 8 byte variable is in this format: [0x7e] [0xff] [0x06] [Command] [dat1] [dat2] [0xEF] in which the only things that vary are the locations marked "command, dat1, and dat2".
-
Typical commands are "play" and "stop"
-
Most of the data from the command is in dat1 (dat2 is 0 in this case). Some commands require 2 bytes of data and in those cases dat1 and dat 2 are needed
-
YX5300 documentation found [here] (https://geekmatic.in.ua/pdf/Catalex_MP3_board.pdf) with summary below:
/*
* Partial code taken from SerialMP3Player.h library - Library for Serial MP3 Player board from Catalex (YX5300 chip)
* Modified for Mega Arduino to play two tunes simultaneously from two separate YX5300 MP3 players
*/
// *********************************************************************** //
// Libraries
// *********************************************************************** //
#include <Arduino.h>
#include <SoftwareSerial.h>
// *********************************************************************** //
// Variables for set up
// *********************************************************************** //
static int8_t Send_buf[8] = {0} ; // 8 byte variable to be sent to YX5300 MP3 player
unsigned long int command = 0; // variable to keep track of value for Byte 3 in string above
unsigned long int dat1 = 0; // variable to keep track of value for Byte 5 in string above
unsigned long int dat2 = 0; // variable to keep track of value for Byte 6 in string above
/* Byte Data Format from the YX5300 MP3 Player Documentation
Byte 0 = [0x7e] - Every command always starts with this
Byte 1 = [0xFF] - Version information which remains constant
Byte 2 = [0xxx] - Number of bytes of he command without starting byte and ending byte and is always 06 [0x06]
Byte 3 = [0xxx] - Command such as "Play" (see Byte 6 and 7 options below)
Byte 4 = [0xxx] - 0x00 = not feedback, 0x02 = feedback (use 0000)
Byte 5 = [0xxx] = 1st byte of data(see options below)
Byte 6 = [0xxx] = 2nd byte of data (see options below)
Byte 7 = [0xEF] = Ending byte of the command remains constant
Resulting byte string is [0x7e] [0xff] [0x06] [Command] [dat1] [dat2] [0xEF]
*/
SoftwareSerial serialOne(18, 19); // Software Serial 1 pinouts on Mega for background music
SoftwareSerial serialTwo(16, 17); // Software Serial 2 pinouts on Mega for target sounds
void setup() {
Serial.begin(9600);
while (!Serial) { // wait till Serial
}
serialOne.begin(9600); // sets baud rate to 9600
serialTwo.begin(9600); // sets baud rate to 9600
delay(200); // necessary for initialization
// Initialization required for YX5300 #1 to direct to storage device
command = 0x09; // Sets YX5300 storage device to TF card
dat1 = 0x00; // Default settings for TF card initialization
dat2 = 0x00; // Default settings for TF card initialization
// Serial 1 mp3 player initialization
serialOne.listen(); // listening on Serial One
while (serialOne.available() > 0) {
// char inByte = serialOne.read();
// Command Structure 0x7E 0xFF 0x06 CMD FBACK DAT1 DAT2 0xEF
Send_buf[0] = 0x7E; // Start byte
Send_buf[1] = 0xFF; // Version
Send_buf[2] = 0x06; // Command length not including Start and End byte.
Send_buf[3] = command; // Command
Send_buf[4] = 0x00; // Feedback 0x00 NO, 0x01 YES
Send_buf[5] = dat1; // DATA1 datah
Send_buf[6] = dat2; // DATA2 datal
Send_buf[7] = 0xEF; // End byte
for(int i=0; i<8; i++) {
Serial.write(Send_buf[i]); //Sends 8 byte instruction code to YX5300
}
}
// Initialization required for YX5300 #2 to direct to storage device
command = 0x09; // Sets YX5300 storage device to TF card
dat1 = 0x00; // Default settings for TF card initialization
dat2 = 0x00; // Default settings for TF card initialization
serialTwo.listen(); // listening on Serial Two
while (serialTwo.available() > 0) {
// char inByte = serialOne.read();
// Command Structure 0x7E 0xFF 0x06 CMD FBACK DAT1 DAT2 0xEF
Send_buf[0] = 0x7E; // Start byte
Send_buf[1] = 0xFF; // Version
Send_buf[2] = 0x06; // Command length not including Start and End byte.
Send_buf[3] = command; // Command
Send_buf[4] = 0x00; // Feedback 0x00 NO, 0x01 YES
Send_buf[5] = dat1; // DATA1 datah
Send_buf[6] = dat2; // DATA2 datal
Send_buf[7] = 0xEF; // End byte
for(int i=0; i<8; i++) {
Serial.write(Send_buf[i]); //Sends 8 byte instruction code to YX5300
}
}
}
void loop() {
// Sample loop to play YX5300 #1
command = 0x22; // Play with volume
dat1 = 0x0F; // Set Volume to 15
dat2 = 0x01; // Play 1st tune
serialOne.listen(); // listening on Serial Two
while (serialOne.available() > 0) {
// char inByte = serialOne.read();
// Command Structure 0x7E 0xFF 0x06 CMD FBACK DAT1 DAT2 0xEF
Send_buf[0] = 0x7E; // Start byte
Send_buf[1] = 0xFF; // Version
Send_buf[2] = 0x06; // Command length not including Start and End byte.
Send_buf[3] = command; // Command
Send_buf[4] = 0x00; // Feedback 0x00 NO, 0x01 YES
Send_buf[5] = dat1; // DATA1 datah
Send_buf[6] = dat2; // DATA2 datal
Send_buf[7] = 0xEF; // End byte
for(int i=0; i<8; i++) {
Serial2.write(Send_buf[i]); //Sends 8 byte instruction code to YX5300
}
}
// Sample loop to play YX5300 #2
command = 0x22; // Play with volume
dat1 = 0x0F; // Set Volume to 15
dat2 = 0x01; // Play 1st tune
serialTwo.listen(); // listening on Serial Two
while (serialTwo.available() > 0) {
// char inByte = serialOne.read();
// Command Structure 0x7E 0xFF 0x06 CMD FBACK DAT1 DAT2 0xEF
Send_buf[0] = 0x7E; // Start byte
Send_buf[1] = 0xFF; // Version
Send_buf[2] = 0x06; // Command length not including Start and End byte.
Send_buf[3] = command; // Command
Send_buf[4] = 0x00; // Feedback 0x00 NO, 0x01 YES
Send_buf[5] = dat1; // DATA1 datah
Send_buf[6] = dat2; // DATA2 datal
Send_buf[7] = 0xEF; // End byte
for(int i=0; i<8; i++) {
Serial2.write(Send_buf[i]); //Sends 8 byte instruction code to YX5300
}
}
delay (3000);
}
your mega has hardware serial ports, so don't use Software Serial... (and use those ports to send commands, not Serial)
try something like this (typed here based on your code, so totally untested)
#define serialOne Serial1
#define serialTwo Serial2
// Command Structure 0x7E 0xFF 0x06 CMD FBACK DAT1 DAT2 0xEF
byte commandBuffer[8] = {0x7E, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0xEF} ; // 8 byte variable to be sent to YX5300 MP3 player
void setup() {
Serial.begin(9600);
serialOne.begin(9600); // sets baud rate to 9600
serialTwo.begin(9600); // sets baud rate to 9600
delay(200); // necessary for initialization
commandBuffer[3] = 0x09; // Sets YX5300 storage device to TF card
commandBuffer[5] = 0x00; // Default settings for TF card initialization
commandBuffer[6] = 0x00; // Default settings for TF card initialization
// Initialization required for YX5300 to direct to storage device
serialOne.write((const char*) commandBuffer, sizeof commandBuffer);
serialTwo.write((const char*) commandBuffer, sizeof commandBuffer);
}
void loop() {
// Sample loop to play YX5300 #1
commandBuffer[3] = 0x22; // Play with volume
commandBuffer[5] = 0x01; // 1st file on micro SD card
commandBuffer[6] = 0x30; // Volume of 30
serialOne.write((const char*) commandBuffer, sizeof commandBuffer);
serialTwo.write((const char*) commandBuffer, sizeof commandBuffer);
delay (5000);
}
@J-M-L your suggested code works! Thank you so much! I did find an error in my hexadecimal callouts so the code below is now correct, compiles, and runs on a Mega 2560. Thanks again!
/*
The following code is written for the Mega Aruduino to communicate with multiple YX5300 MP3 Players using the various Mega serial ports.
This allows for two or more mp3 files to play simultaneously. This working code has been tested on the Mega 2560.
Copy mp3 files to SD card in this format
Create Folders 01, 02…
Name Files 001xxx.mp3, 002xxx.mp3 // xxx can be anything
Note that names for 008.xxx and 009.xxx return errors so must skip
Connect the Serial MP3 Player to the Arduino board
YX5300 → Mega
GND → GND
VCC → 5V
TX → RX
RX → TX
YX5300 Available Commands for Byte 6 (dat1) and 7 (dat2)
#define CMD_SEL_DEV 0X09 // Set device. 2 DEV_TF (SD Card)
#define CMD_PLAY 0X0D // Play
#define CMD_PLAYN 0X03 // Play n file from (1-255)
#define CMD_PLAY_W_VOL 0X22 // Play with a volumen
#define CMD_SET_VOL 0X06 // Set Volume (0-30)
#define CMD_STOP_PLAY 0X16 // Stop
#define CMD_NEXT 0X01 // Play next file
#define CMD_PREV 0X02 // Play previous file
#define CMD_VOL_UP 0X04 // Volumen up
#define CMD_VOL_DOWN 0X05 // Volumen down
// 0x07 // Reserved.
#define CMD_PLAY_SLOOP 0X08 // Single loop play
#define CMD_SLEEP_MODE 0X0A
#define CMD_WAKE_UP 0X0B
#define CMD_RESET 0X0C
#define CMD_PAUSE 0X0E // Pause
#define CMD_PLAY_F_FILE 0X0F // only avaible for Flash not SD Card.
#define CMD_PLAY_SHUFFLE 0x18 // Reserved
#define CMD_FOLDER_CYCLE 0X17 // Play all the files in the f folder
Query Commands
#define CMD_PLAYING_N 0x4C // qPlaying(); // Ask for the file is playing
#define CMD_QUERY_STATUS 0x42 // qStatus(); // Ask for the status
#define CMD_QUERY_VOLUME 0x43 // qVol(); // Ask for the volumen. // Sometime board fails
#define CMD_QUERY_FLDR_TRACKS 0x4E // qFTracks(); // Ask for the number of tracks folders
#define CMD_QUERY_TOT_TRACKS 0x48 // qTTracks(); // Ask for the total of tracks
#define CMD_QUERY_FLDR_COUNT 0x4F // qTFolders(); // Ask for the number of folders
Byte Data Format
Byte 0 = [0x7e] - Every command starts with this
Byte 1 = [0xFF] - Version information
Byte 2 = [0xxx] - Number of bytes of he command without starting byte and ending byte
Byte 3 = [0xxx] - Command such as "Play"
Byte 4 = [0xxx] - 0x00 = not feedback, 0x02 = feedback (use 0000)
Byte 5 = [00xx] = 1st byte of data
Byte 6 = [00xx] = 2nd byte of data
Byte 7 = [0xEF] = Ending byte of the command
*/
#define serialOne Serial1 // For YX5300 #1 playing background music
#define serialTwo Serial2 // For YX5300 #2 playing specific tunes when targets knocked down
// Command Structure 0x7E 0xFF 0x06 CMD FBACK DAT1 DAT2 0xEF
byte commandBuffer[8] = {0x7E, 0xFF, 0x06, 0x00, 0x00, 0x00, 0x00, 0xEF} ; // 8 byte variable to be sent to YX5300 MP3 player
void setup() {
Serial.begin(9600);
serialOne.begin(9600); // sets baud rate to 9600
serialTwo.begin(9600); // sets baud rate to 9600
delay(200); // necessary for initialization
commandBuffer[3] = 0x09; // Sets YX5300 storage device to TF card
commandBuffer[5] = 0x00; // Default settings for TF card initialization
commandBuffer[6] = 0x00; // Default settings for TF card initialization
// Initialization required for YX5300 to direct to storage device
serialOne.write((const char*) commandBuffer, sizeof commandBuffer);
serialTwo.write((const char*) commandBuffer, sizeof commandBuffer);
}
void loop() {
// Sample loop to play YX5300 #1
commandBuffer[3] = 0x22; // Play with volume
commandBuffer[5] = 0x0F; // Set Volume to 15 (0F is hexadecimal for 15)
commandBuffer[6] = 0x01; // Play 1st tune on YX5300 #1
serialOne.write((const char*) commandBuffer, sizeof commandBuffer); //command that tells YX5300 #1 to play
// Sample loop to play YX5300 #2
commandBuffer[3] = 0x22; // Play with volume
commandBuffer[5] = 0x1E; // Set Volume to 30 (1E is hexadecimal for 30)
commandBuffer[6] = 0x02; // Play 2nd tune on YX5300 #2
serialTwo.write((const char*) commandBuffer, sizeof commandBuffer); //command that tells YX5300 #2 to play
delay (5000); // Slows down loop so at least 5 seconds of each mp3 plays before starting over
}
Have fun ![]()
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.
