Hi fellow Arduino'ers
I recently took up arduino, and bought a kit of different components. Now I have finished all of the beginners' tutorials and I am beginning to make some projects on my own. My main reason for wanting to learn Arduino, was to be able to make a cloud sculpture complete with lightning and speakers inspiration from this guy. Until now, I have been able to get the "lightning" running pretty decently, but my newest addition is causing me troubles. It's a MP3 serial player module (bought on dx.com). I have trouble understanding the example code, and I was wondering if you guys could help me a bit? I can make it play the mp3 files on my SD card (following the code), but I don't know how to control it further than that. Help me understand what 0X0F01 etc. means
Test example:
#include <SoftwareSerial.h>
#define ARDUINO_RX 5//should connect to TX of the Serial MP3 Player module
#define ARDUINO_TX 6//connect to RX of the module
SoftwareSerial mySerial(ARDUINO_RX, ARDUINO_TX);
static int8_t Send_buf[8] = {0} ;
#define CMD_PLAY_W_INDEX 0X03
#define CMD_SET_VOLUME 0X06
#define CMD_SEL_DEV 0X09
#define DEV_TF 0X02
#define CMD_PLAY 0X0D
#define CMD_PAUSE 0X0E
#define CMD_SINGLE_CYCLE 0X19
#define SINGLE_CYCLE_ON 0X00
#define SINGLE_CYCLE_OFF 0X01
#define CMD_PLAY_W_VOL 0X22
void setup()
{
mySerial.begin(9600);
delay(500);//Wait chip initialization is complete
sendCommand(CMD_SEL_DEV, DEV_TF);//select the TF card
delay(200);//wait for 200ms
sendCommand(CMD_PLAY_W_VOL, 0X0F01);//play the first song with volume 15 class
}
void loop()
{
}
void sendCommand(int8_t command, int16_t dat)
{
delay(20);
Send_buf[0] = 0x7e; //starting byte
Send_buf[1] = 0xff; //version
Send_buf[2] = 0x06; //the number of bytes of the command without starting byte and ending byte
Send_buf[3] = command; //
Send_buf[4] = 0x00;//0x00 = no feedback, 0x01 = feedback
Send_buf[5] = (int8_t)(dat >> 8);//datah
Send_buf[6] = (int8_t)(dat); //datal
Send_buf[7] = 0xef; //ending byte
for(uint8_t i=0; i<8; i++)//
{
mySerial.write(Send_buf[i]) ;
}
}
Yes, that's the one!
The manual you've linked is great, however it does not clear things for me
Like how do I use the "command bytes", or what this part of the arduino code does:
void sendCommand(int8_t command, int16_t dat)
{
delay(20);
Send_buf[0] = 0x7e; //starting byte
Send_buf[1] = 0xff; //version
Send_buf[2] = 0x06; //the number of bytes of the command without starting byte and ending byte
Send_buf[3] = command; //
Send_buf[4] = 0x00;//0x00 = no feedback, 0x01 = feedback
Send_buf[5] = (int8_t)(dat >> 8);//datah
Send_buf[6] = (int8_t)(dat); //datal
Send_buf[7] = 0xef; //ending byte
for(uint8_t i=0; i<8; i++)//
{
mySerial.write(Send_buf[i]) ;
}
Basically I'm not understanding the code. I'm used to all of the code taking place in the void loop part, but
in this case, there is so much more going on.
Is there some site or guide I can read, for understanding the logic of the test example?
Sorry for all the questions, I'm just eager to learn more about this
I can make it play the mp3 files on my SD card (following the code),
I don't see any code there for an SD card , is the SD connected to the arduino or directly connected to the device ?
What is going on there, is that the arduino is sending 8-byte serial messages to the device. The format and contents of those messages would be defined by the device. You would need some kind of documentation for the device to understand all of the possible commands that the device might have.
There are two meaningful components of your command message to the device.
The first is the "command", and the available commands would appear to be shown by the #define's. The second is the "data", which is a number which would mean different things for different commands.
The 0x0F01 means a 2-byte integer, with the hexadecimal value 0F01. From the context, it appears that this 16 bit data value is actually two separate bytes stuck together. The first byte is 0F, which is hexadecimal for 15, and has something to do with volume. The second byte is 01, which is hexadecimal for 1, and means play the first file, apparently.
If you want to play the second file on the SD card, try changing 0x0f01 to 0x0F02, and see what you get.
I'm used to all of the code taking place in the void loop part, but
The reason for this, is you only want to tell the device what to start doing once, you don't want to tell it what to do, millions of times, which is what would happen if you put that code into loop( ).
The obstacle I perceive you will have with this device, is that although there is a field for "feedback", there is no information about it. The communication between the arduino and the device all one-way.
In particularly, there seems to be no way for the arduino to ask the device if the track is finished yet, in order to ask for a different one.
Hey Michinyon.
Thank you for taking the time explaining this for me.
To answer your question, the micro SD card slot is located on the mp3 player module.
It seems (from the manual) that you are also able to play specific tracks on the SD card.
But you are right in that it's tricky to understand the feedback mechanism.
Have I understood it right, that if the command: CMD_PLAY_W_VOL, 0X1E01, would play the first song at volume 30 then? Because 30 = 1E in hexadecimal?
If you were to implement the mp3-capabilities in the void loop, how would you do it?
The cloud I'm making will be controlled via an infrared remote, triggering different functions.
Would this work?:
if (digitalRead=some specific IR code){
*some lightning show* and then
sendCommand(CMD_SEL_DEV, DEV_TF); //select the TF card
delay(100);//wait for 200ms
sendCommand(CMD_PLAY_W_VOL, 0X0F0random(10)); //play a random song out of 9 songs (15Vol)
delay(15000); //delay for 15 seconds, making sure the lightning sound has been played
}
It just seems so rough, because I have to use the delay function.
I would love to be able to make some moodlightning while sound is playing (like the continous sound of rain mixed with small flashes and lightning).
same Problem here... got an Catalex YX5300 MP3 Board ..... using this Demo_Sketch
/***********************************************************/
// Demo for the Serial MP3 Player Catalex (YX5300 chip)
// Hardware: Serial MP3 Player *1
// Board: Arduino UNO
// http://www.dx.com/p/uart-control-serial-mp3-music-player-module-for-arduino-avr-arm-pic-blue-silver-342439#.VfHyobPh5z0
//
//
//
// Uncomment SoftwareSerial for Arduino Uno or Nano.
#include <SoftwareSerial.h>
#define ARDUINO_RX 5 //should connect to TX of the Serial MP3 Player module
#define ARDUINO_TX 6 //connect to RX of the module
SoftwareSerial mp3(ARDUINO_RX, ARDUINO_TX);
//#define mp3 Serial3 // Connect the MP3 Serial Player to the Arduino MEGA Serial3 (14 TX3 -> RX, 15 RX3 -> TX)
static int8_t Send_buf[8] = {0}; // Buffer for Send commands. // BETTER LOCALLY
static uint8_t ansbuf[10] = {0}; // Buffer for the answers. // BETTER LOCALLY
static int8_t pre_vol, volume = 0x0f; // Volume. 0-30 DEC values. 0x0f = 15.
String mp3Answer; // Answer from the MP3.
boolean playing = false; // Sending 'p' the module switch to Play to Pause or viceversa.
/************ Command byte **************************/
#define CMD_NEXT_SONG 0X01 // Play next song.
#define CMD_PREV_SONG 0X02 // Play previous song.
#define CMD_PLAY_W_INDEX 0X03
#define CMD_VOLUME_UP 0X04
#define CMD_VOLUME_DOWN 0X05
#define CMD_SET_VOLUME 0X06
#define CMD_SNG_CYCL_PLAY 0X08 // Single Cycle Play.
#define CMD_SEL_DEV 0X09
#define CMD_SLEEP_MODE 0X0A
#define CMD_WAKE_UP 0X0B
#define CMD_RESET 0X0C
#define CMD_PLAY 0X0D
#define CMD_PAUSE 0X0E
#define CMD_PLAY_FOLDER_FILE 0X0F
#define CMD_STOP_PLAY 0X16
#define CMD_FOLDER_CYCLE 0X17
#define CMD_SHUFFLE_PLAY 0x18 //
#define CMD_SET_SNGL_CYCL 0X19 // Set single cycle.
#define CMD_SET_DAC 0X1A
#define DAC_ON 0X00
#define DAC_OFF 0X01
#define CMD_PLAY_W_VOL 0X22
#define CMD_PLAYING_N 0x4C
/************ Opitons **************************/
#define DEV_TF 0X02
#define SINGLE_CYCLE_ON 0X00
#define SINGLE_CYCLE_OFF 0X01
/*********************************************************************/
void setup()
{
Serial.begin(9600);
mp3.begin(9600);
delay(500);
sendCommand(CMD_SEL_DEV, DEV_TF);
delay(200);
// sendCommand(CMD_PLAY_W_VOL, 0X0F28); // Playing a 15 (0x0F) Vol the song num 40 (0x28).
}
void loop()
{
char c=' ';
// If there a char on Serial call sendMP3Command to sendCommand
if( Serial.available() )
{
c = Serial.read();
sendMP3Command(c);
}
// Check for the answer.
if (mp3.available())
{
Serial.println(decodeMP3Answer());
}
delay(100);
}
/********************************************************************************/
/*Function sendMP3Command: seek for a 'c' command and send it to MP3 */
/*Parameter: c. Code for the MP3 Command, 'h' for help. */
/*Return: void */
void sendMP3Command(char c){
switch (c) {
case '?':
case 'h':
Serial.println("HELP ");
Serial.println(" p > Play / Pause ");
Serial.println(" n > Next");
Serial.println(" b > Previous");
Serial.println(" u > Volume UP");
Serial.println(" d > Volume DOWN");
break;
case 'p':
if(!playing){
Serial.println("Play ");
sendCommand(CMD_PLAY_W_VOL, 0X0F01);//play the first song with volume 15 class
sendCommand(CMD_SNG_CYCL_PLAY, 0);
//sendCommand(CMD_PLAY, 0);
playing = true;
}else{
Serial.println("Pause");
sendCommand(CMD_PAUSE, 0);
playing = false;
}
break;
case 'n':
Serial.println("Next");
sendCommand(CMD_NEXT_SONG, 0);
sendCommand(CMD_PLAYING_N, 0x0000); // ask for the number of file is playing
break;
case 'b':
Serial.println("Previous");
sendCommand(CMD_PREV_SONG, 0);
sendCommand(CMD_PLAYING_N, 0x0000); // ask for the number of file is playing
break;
case 'u':
Serial.println("Volume Up");
sendCommand(CMD_VOLUME_UP, 0);
break;
case 'd':
Serial.println("Volume Down");
sendCommand(CMD_VOLUME_DOWN, 0);
break;
case 'k':
Serial.println("single");
sendCommand(CMD_SNG_CYCL_PLAY, 0);
break;
}
}
/********************************************************************************/
/*Function decodeMP3Answer: Decode MP3 answer. */
/*Parameter:-void */
/*Return: The */
String decodeMP3Answer(){
String decodedMP3Answer="";
decodedMP3Answer+=sanswer();
// if (ansbuf[3] == 0x4C) // currently planying
// {
// decodedMP3Answer+=" -> Playing: "+String(ansbuf[6],DEC);
// }
switch (ansbuf[3]) {
case 0x3A:
decodedMP3Answer+=" -> Memory card inserted.";
break;
case 0x3D:
decodedMP3Answer+=" -> Completed play num "+String(ansbuf[6],DEC);
break;
case 0x4C:
decodedMP3Answer+=" -> Playing: "+String(ansbuf[6],DEC);
break;
case 0x41:
decodedMP3Answer+=" -> Data recived correctly. ";
break;
}
return decodedMP3Answer;
}
/********************************************************************************/
/*Function: Send command to the MP3 */
/*Parameter:-int8_t command */
/*Parameter:-int16_ dat parameter for the command */
void sendCommand(int8_t command, int16_t dat)
{
delay(20);
Send_buf[0] = 0x7e; //
Send_buf[1] = 0xff; //
Send_buf[2] = 0x06; // Len
Send_buf[3] = command;//
Send_buf[4] = 0x01; // 0x00 NO, 0x01 feedback
Send_buf[5] = (int8_t)(dat >> 8); //datah
Send_buf[6] = (int8_t)(dat); //datal
Send_buf[7] = 0xef; //
for(uint8_t i=0; i<8; i++)
{
mp3.write(Send_buf[i]) ;
}
}
/********************************************************************************/
/*Function: sbyte2hex. Returns a byte data in HEX format. */
/*Parameter:- uint8_t b. Byte to convert to HEX. */
/*Return: String */
String sbyte2hex(uint8_t b)
{
String shex;
//Serial.print("0x");
shex="0X";
//if (b < 16) Serial.print("0");
if (b < 16) shex+="0";
//Serial.print(b, HEX);
shex+=String(b,HEX);
//Serial.print(" ");
shex+=" ";
return shex;
}
/********************************************************************************/
/*Function: sanswer. Returns a String answer from mp3 UART module. */
/*Parameter:- uint8_t b. void. */
/*Return: String. If the answer is well formated answer. */
String sanswer(void)
{
uint8_t i = 0;
String mp3answer="";
// Get only 10 Bytes
while(mp3.available() && (i < 10))
{
uint8_t b = mp3.read();
ansbuf[i] = b;
i++;
//Serial.print(sbyte2hex(b));
mp3answer+=sbyte2hex(b);
}
//Serial.println();
// if the answer format is correct.
if ((ansbuf[0] == 0x7E) && (ansbuf[9] == 0xEF))
{
//return true;
return mp3answer;
}
//return false;
return "???: "+mp3answer;
}
trying to Play Audiofiles in Random Order (ShuffflePlay).
Trying this command lines:
case 's':
Serial.println("Shuffle");
sendCommand(CMD_SHUFFLE_PLAY, 0);
sendCommand(CMD_PLAYING_N, 0x0000); // ask for the number of file is playing
break;
but nothing happend.
Please Help to get my YX5300 to Play mp3 in random Order.
To play a specific track you the final command sent should be 7E FF 06 03 00 00 01 EF where the final 01 is the track number, you could therefore randomise the final number to get a shuffle effect. The command for playing the track would look like:
This looks really helpful for what I am trying to do, which is play a random MP3 from the Catalex board when a distance sensor is set off. I am using the code and circuit listed here - Arduino Project Hub - and it is working perfectly. As a newbie, I can't work out hos tyo adapt your random code above to work with my current code - any suggestions?
ee0u30eb:
To make it random change the 0x02 to a variable, and use a randomiser within limits to set that variable.