I am trying to implement code for the YX5300 MP3 player into my Arduino Uno project. I have broken down the original code example to all I need - basically just one trigger to cycle play one folder. This does work in that it starts playing when I push the button connected to pin 7 (it also displays the send command on the serial monitor):
#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);
static int8_t Send_buf[8] = {0}; // Buffer for Send commands. // BETTER LOCALLY
String sbyte2hex(uint8_t b);
const byte playPin = 7;
byte playButton = 0;
/************ Command byte *************************/
#define CMD_SLEEP_MODE 0X0A
#define CMD_WAKE_UP 0X0B
#define CMD_SEL_DEV 0X09
#define CMD_PLAY 0X0D
#define CMD_STOP_PLAY 0X16 // Stop playing continuously.
#define CMD_FOLDER_CYCLE 0X17
#define CMD_SET_DAC 0X1A
#define DAC_ON 0X00
#define DAC_OFF 0X01
#define DEV_TF 0X02
/*********************************************************************/
void setup()
{
Serial.begin(9600);
mp3.begin(9600);
delay(500);
sendCommand(CMD_SEL_DEV, 0, DEV_TF);
delay(500);
pinMode(playPin, INPUT);
}
void loop()
{
playButton = digitalRead(playPin);
if (playButton == HIGH) {
sendCommand(CMD_FOLDER_CYCLE, 1, 0);
}
}
/********************************************************************************/
/*Function: Send command to the MP3 */
/*Parameter: byte command */
/*Parameter: byte dat1 parameter for the command */
/*Parameter: byte dat2 parameter for the command */
void sendCommand(byte command){
sendCommand(command, 0, 0);
}
void sendCommand(byte command, byte dat1, byte dat2){
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] = dat1; // datah
Send_buf[6] = dat2; // datal
Send_buf[7] = 0xEF; //
Serial.print("Sending: ");
for (uint8_t i = 0; i < 8; i++)
{
mp3.write(Send_buf[i]) ;
Serial.print(sbyte2hex(Send_buf[i]));
}
Serial.println();
}
/********************************************************************************/
/*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;
shex = "0X";
if (b < 16) shex += "0";
shex += String(b, HEX);
shex += " ";
return shex;
}
/********************************************************************************/
/*Function: shex2int. Returns a int from an HEX string. */
/*Parameter: s. char *s to convert to HEX. */
/*Parameter: n. char *s' length. */
/*Return: int */
int shex2int(char *s, int n){
int r = 0;
for (int i=0; i<n; i++){
if(s[i]>='0' && s[i]<='9'){
r *= 16;
r +=s[i]-'0';
}else if(s[i]>='A' && s[i]<='F'){
r *= 16;
r += (s[i] - 'A') + 10;
}
}
return r;
}
This, however, does not work. The wiring is exactly the same. It does display the play command being sent to the YX5300. But the module does not start playing. As far as I am aware, I am using the exact same code for the player. I do not understand why the player won't start playing even though it receives the appropriate command:
/************ init mp3-player ***************/
#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);
static int8_t Send_buf[8] = {0}; // Buffer for Send commands. // BETTER LOCALLY
String sbyte2hex(uint8_t b);
#define CMD_SLEEP_MODE 0X0A
#define CMD_WAKE_UP 0X0B
#define CMD_SEL_DEV 0X09
#define CMD_PLAY 0X0D
#define CMD_STOP_PLAY 0X16 // Stop playing continuously.
#define CMD_FOLDER_CYCLE 0X17
#define CMD_SET_DAC 0X1A
#define DAC_ON 0X00
#define DAC_OFF 0X01
#define DEV_TF 0X02
/**************** init the real time clock ***************/
#include <Rtc_Pcf8563.h>
Rtc_Pcf8563 rtc;
/**************** setup pins & buttons ***************/
const byte led = 9; // Pin LED is connected to
const byte sixAmPin = 4; // Pin for set-alarm-to-6am-button
const byte sevenAmPin = 5; // Pin for set-alarm-to-7am-button
const byte eightAmPin = 6; // Pin for set-alarm-to-8am-button
const byte stopPin = 7; // Pin for stop button
const byte timeResetPin; // Pin for reset-clock-to-9am-button (useful e.g. after battery failure)
const byte playPin = 8; // Pin for play-music-button
byte sixAmButton = 0; // State of 6am-set-button
byte sevenAmButton = 0; // State of 7am-set-button
byte eightAmButton = 0; // State of 8am-set-button
byte stopButton = 0; // State of stopButton
byte timeResetButton = 0; // State of time-set-button
byte playButton = 0; // State of play-music-button
byte brightness = 0; // LED brightness
bool wakeupMode = false;
unsigned long prevStepTime = millis();
unsigned long time;
/*************** Changeable variables here **************/
byte setHour = 19;
byte setMin = 29;
byte fadeDuration = 1; // Duration of fade in minutes (default: 30)
byte afterBurn = 1; // Keep light on after alarm for this many minutes (default: 30)
/********************************************************/
unsigned long keepLight = afterBurn * 60000UL; // Calculate time to keep LED on after fade (in ms)
int fadeStepLength = fadeDuration * 6000 / 255; // Calculate step duration for increasing LED brightness (in ms) (default: fadeDuration * 60000 / 255)
void wakeup();
void readButtons();
/********** debug class ************/
unsigned long int prevDebugTime = 0;
void debug() {
unsigned long debugTime = millis();
if ( debugTime > prevDebugTime + 500 ) {
Serial.print("Brightness = ");
Serial.println(brightness);
Serial.print("Time = ");
Serial.println(time);
Serial.print("stopButton = ");
Serial.println(stopButton);
Serial.print("playButton = ");
Serial.println(playButton);
Serial.print("Time = ");
Serial.println(rtc.formatTime());
Serial.println();
prevDebugTime = millis();
}
}
/************************************/
void setup() {
Serial.begin(9600);
mp3.begin(9600);
delay(500);
sendCommand(CMD_SEL_DEV, 0, DEV_TF);
delay(500);
// declare LED pin to be an output:
pinMode(led, OUTPUT);
// declare button pins as inputs:
pinMode(stopPin, INPUT);
pinMode(sixAmPin, INPUT);
pinMode(sevenAmPin, INPUT);
pinMode(eightAmPin, INPUT);
pinMode(timeResetPin, INPUT);
pinMode(playPin, INPUT);
}
void loop() {
// If it is wake-up time and wakeupMode is on, trigger alarm and reset trigger; else turn on wakeupMode
if ( rtc.getHour() == setHour && rtc.getMinute() == setMin ) {
if (wakeupMode) {
wakeup();
wakeupMode = false;
}
else {
wakeupMode = true;
}
}
// Check for button input
readButtons();
// update LED in case stopButton was pressed
analogWrite(led, brightness);
// Todo: Setup power saving methods
debug();
}
void wakeup() {
// If wake-up-mode is true and brightness < 255, add +1 to brightness every 7 seconds (256 steps)
while (wakeupMode == true) {
//update clock
time = millis();
// If current time is wakeup-time, increase LED brightness slowly over the course of 30 minutes
if (brightness < 255 ) {
// Delay brightening in steps. Do only if interval has passed.
if (time > prevStepTime + fadeStepLength) {
brightness ++;
prevStepTime = millis(); // Resets counter to restart interval
}
}
// Turn off light and exit wakupMode x minutes after max brightness
else if (brightness == 255 && time > prevStepTime + keepLight) {
brightness = 0;
wakeupMode = false; // Exit wakeupMode loop
}
// Check for input from buttons
// readButtons(); //uncomment after testing
//debug();
// Set LED brightness accordingly
analogWrite(led, brightness);
}
}
void readButtons() {
// Always run this:
// Check if alarm gets set to 6, 7 or 8am
sixAmButton = digitalRead(sixAmPin);
if (sixAmButton == HIGH) {
setHour = 6;
}
sevenAmButton = digitalRead(sevenAmPin);
if (sevenAmButton == HIGH) {
setHour = 7;
}
eightAmButton = digitalRead(eightAmPin);
if (eightAmButton == HIGH) {
setHour = 8;
}
// If stopButton is pressed, turn off LED and reset alarm
stopButton = digitalRead(stopPin);
if (stopButton == HIGH) {
wakeupMode = true; //change to false after testing (default: false)
// brightness = 0; // uncomment after testing
wakeup(); // for testing purposes
//sendCommand(CMD_STOP_PLAY); // uncomment after testing
}
// Todo: If timeResetButton is pressed, reset clock to 9am
if (timeResetButton == HIGH) {
rtc.setTime(9, 0, 0);
}
// Todo: If Play music button is pressed, start playing music
playButton = digitalRead(playPin);
if (playButton == HIGH) {
sendCommand(CMD_FOLDER_CYCLE, 1, 0);
}
}
/********************************************************************************/
/*Function: Send command to the MP3 */
/*Parameter: byte command */
/*Parameter: byte dat1 parameter for the command */
/*Parameter: byte dat2 parameter for the command */
void sendCommand(byte command){
sendCommand(command, 0, 0);
}
void sendCommand(byte command, byte dat1, byte dat2){
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] = dat1; // datah
Send_buf[6] = dat2; // datal
Send_buf[7] = 0xEF; //
Serial.print("Sending: ");
for (uint8_t i = 0; i < 8; i++)
{
mp3.write(Send_buf[i]) ;
Serial.print(sbyte2hex(Send_buf[i]));
}
Serial.println();
}
/********************************************************************************/
/*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;
shex = "0X";
if (b < 16) shex += "0";
shex += String(b, HEX);
shex += " ";
return shex;
}
/********************************************************************************/
/*Function: shex2int. Returns a int from an HEX string. */
/*Parameter: s. char *s to convert to HEX. */
/*Parameter: n. char *s' length. */
/*Return: int */
int shex2int(char *s, int n){
int r = 0;
for (int i=0; i<n; i++){
if(s[i]>='0' && s[i]<='9'){
r *= 16;
r +=s[i]-'0';
}else if(s[i]>='A' && s[i]<='F'){
r *= 16;
r += (s[i] - 'A') + 10;
}
}
return r;
}
Just for some background: This is my code for a light alarm which, instead of playing a sound, will turn on an LED gradually, simulating a sunrise. I features multiple buttons to set the alarm time, stop the alarm (and, later, the music) and to start playing music.
Any hints on overall code architecture are also welcome (this is my first Arduino project, I hadn't written a single line of code for ten years prior to this). But my main concern is finding out where the bug is. My second concern is how to learn how to find out where the bug is.