Hi,
I am building an mp3 player for my very small nephew, with an YX-5300 Mp3 player, inspired by this project (sadly with a different chip).
After experimenting with directly sending serial commands via softwareSerial, I am now using the MD_YX5300 library from GitHub - MajicDesigns/MD_YX5300: Library for Serial MP3 Player based on YX5300 IC (Catalex Module), as it works asynchronously, without interruptions.
I can't query the number of files in a folder now - the example code does query it, but it gets the information in the uint16_t format.
#include <MD_YX5300.h>
// https://github.com/MajicDesigns/MD_YX5300/
// Connections for serial interface to the YX5300 module
const uint8_t ARDUINO_RX = 5; // connect to TX of MP3 Player module
const uint8_t ARDUINO_TX = 6; // connect to RX of MP3 Player module
// Constants for Buttons
#define PIN_KEY A3
#define BUTTON_TOLERANCE 25
#define LONG_KEY_PRESS_TIME_MS 2000L
#define DEBUG 1 // enable/disable debug output
#ifdef DEBUG
#define PRINT(s,v) { Serial.print(F(s)); Serial.print(v); }
#define PRINTX(s,v) { Serial.print(F(s)); Serial.print(v, HEX); }
#define PRINTS(s) { Serial.print(F(s)); }
#else
#define PRINT(s,v)
#define PRINTX(s,v)
#define PRINTS(s)
#endif
bool showFolderFiles = true;
long int lastCheck;
// Define global variables
MD_YX5300 mp3(ARDUINO_RX, ARDUINO_TX);
/********************************************************************************/
/****************************** VARIABLES (May change) **************************/
/********************************************************************************/
/****** Folder Management *****/
int numberOfFolders = 9;
uint8_t currentFolder = 1; // start with folder 1
unsigned int currentFile = 1; // FIXME change Type?
unsigned int numberOfFiles[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0}; // for 9 Folders
int numberoffilesinfolder;
/******************************/
/****** Button Management *****/
int key = -1;
unsigned long keyPressTimeMs = 0;
unsigned long nowMs;
int keyPressRepeats = 0; //???
long buttonTimer = 0;
long longPressTime = 250;
boolean buttonActive = false;
boolean longPressActive = false;
// from https://www.instructables.com/id/Arduino-Dual-Function-Button-Long-PressShort-Press/
enum {
MODE_NORMAL, MODE_SET_TIMER
} mode = MODE_NORMAL;
/******************************/
/****** Status Information ****/
enum playMode_t { M_SEQ, M_SHUFFLE, M_LOOP, M_EJECTED };
enum playStatus_t { S_PAUSED, S_PLAYING, S_STOPPED };
enum encMode_t { E_VOLUME, E_TRACK };
struct // contains all the running status information
{
bool needUpdate; // flag for display update required
bool initialising; // loading data from the device
bool waiting; // waiting initialisation response
playMode_t playMode; // playing mode
playStatus_t playStatus;// playing status
encMode_t encMode; // encoder mode
uint16_t numTracks; // number of tracks in this folder
uint16_t curTrack; // current track being played
uint16_t volume; // the current audio volume
} S;
/********** Initialize MP3 Data ************/
bool initData(bool reset = false)
// initialise data from the MP3 device.
// This needs to be measured out as the data requests will generate
// unsolicited messages to be handled in the callback and message
// sequence is must be maintained with the synchronous message processing
// stream.
// Returns true if the initilisation must keep going, fals when completed.
{
static uint8_t state = 0;
bool b = true;
if (reset) // just rest the sequencing
{
state = 0;
}
else
{
switch (state)
{
case 0: // set a default state in the devioce and then ask for first data
mp3.playSpecific(currentFolder, currentFile);
mp3.playPause();
S.playMode = M_SEQ;
S.playStatus = S_PAUSED;
if (S.volume == 0)
S.volume = (mp3.volumeMax() / 3) * 2; // 2/3 of volume to start with
mp3.volume(S.volume);
// load number of files in the folder - needs wait for response
mp3.queryFolderFiles(currentFolder);
S.waiting = true;
state++;
break;
case 1: // now load the track cplaying - needs wait for response
mp3.queryFile();
S.waiting = true;
state++;
break;
default:
// end of sequence handler
state = 0;
b = false;
break;
}
}
return(b);
}
/************ Callback Response *********/
void cbResponse(const MD_YX5300::cbData *status)
// Callback function used to process device unsolicited messages
// or responses to datya requests
{
PRINTS("\n");
switch (status->code)
{
case MD_YX5300::STS_FILE_END: // track has ended
PRINTS("STS_FILE_END");
selectNextSong();
break;
case MD_YX5300::STS_TF_INSERT: // card has been inserted
PRINTS("STS_TF_INSERT");
S.initialising = initData(true);
break;
case MD_YX5300::STS_TF_REMOVE: // card has been removed
PRINTS("STS_TF_REMOVE");
S.playMode = M_EJECTED;
S.playStatus = S_STOPPED;
S.needUpdate = true;
break;
case MD_YX5300::STS_PLAYING: // current track index
PRINTS("STS_PLAYING");
S.curTrack = status->data;
S.needUpdate = true;
break;
case MD_YX5300::STS_FLDR_FILES: // number of files in the folder
PRINTS("STS_FLDR_FILES");
S.numTracks = status->data;
S.needUpdate = true;
numberOfFiles[currentFolder-1] = S.numTracks; // #FIXME - Data type / Conversion Problem ??
Serial.println("numberOfFiles in Folder" + String(currentFolder) + " is " + String(numberOfFiles[currentFolder-1]));
break;
// unhandled cases
case MD_YX5300::STS_VOLUME: PRINTS("STS_VOLUME"); break;
case MD_YX5300::STS_TOT_FILES: PRINTS("STS_TOT_FILES"); break;
case MD_YX5300::STS_ERR_FILE: PRINTS("STS_ERR_FILE"); break;
case MD_YX5300::STS_ACK_OK: PRINTS("STS_ACK_OK"); break;
case MD_YX5300::STS_INIT: PRINTS("STS_INIT"); break;
case MD_YX5300::STS_STATUS: PRINTS("STS_STATUS"); break;
case MD_YX5300::STS_EQUALIZER: PRINTS("STS_EQUALIZER"); break;
case MD_YX5300::STS_TOT_FLDR: PRINTS("STS_TOT_FLDR"); break;
default: PRINTX("STS_??? 0x", status->code); break;
}
PRINTX(", 0x", status->data);
S.waiting = false;
}
void processPause(bool b)
// switches pause on if b == true; of if b == false
{
if (b == true) {mp3.playPause();} else mp3.playStart();
}
void handleKeyPress() {
// this function listens for keypresses and sends commands
// see attachment for complete code (above character limit for post)
}
void setup() {
#if DEBUG
Serial.begin(9600);
#endif
PRINTS("\n[MD_YX5300 Test]");
// Initialize global libraries
mp3.begin();
mp3.setSynchronous(true);
mp3.setCallback(cbResponse);
S.initialising = initData(true); // initialize data from MP3 device
// Returns true if the initilisation must keep going, fails when completed.
/*** buttons ***/
pinMode(PIN_KEY, INPUT_PULLUP);
Serial.print("Buttons ready");
}
void loop() {
long int nowMs = millis();
mp3.check(); // run the mp3 receiver
if (S.initialising && !S.waiting) S.initialising = initData();
// initialize if waiting
else {
// check buttons, act on key press
handleKeyPress();
}
}
The problem: How can I fill this array with the number of files in each folder? for example, it should look like this:
numberOfFiles[] = { 3, 5, 2, 7, 3, 2, 1, 6, 7}
This is where the problem starts, the value is stores in S.numTracks , which is defined as
uint16_t numTracks; // number of tracks in this folder
When the answer is received and interpreted, I try to store the value in the array but fail:
case MD_YX5300::STS_FLDR_FILES: // number of files in the folder
PRINTS("STS_FLDR_FILES");
S.numTracks = status->data;
S.needUpdate = true;
numberOfFiles[currentFolder-1] = S.numTracks; // *** this does not work***
break;
How can I get the number of files in each folder? The examples for the MD_YX5300 library only store all the files in one folder, but in my project I need 9 folders to keep the different audiobooks apart.
Thanks!
-Complete Code attached, also on Github:
2019-09-kidsmp3player_MD_YX5300.ino (8.96 KB)