Paul,
Wrote a second method that saved all filenames and/or pointers to filenames in an array to be used later. I moved the writing of the values both before the entry.close() call as well as after the entry.close() was issued as shown above. regardless, accessing the data stored after was garbage unless it was an integer like the file size. The name, or pointer to a char array that held the name would print normal inside the method, but when it was passed on to other parts of code, returned "garbage". I will post full code but it has all sorts of alternate methods and such tried as I cannot get past the core point that I cannot search an SD card and store off any information that would let me open a file later by referring to a variable containing the filename or pointer to the filename, rather than a specific filename. If someone could try that, perhaps they would find an elegant solution or what I am doing wrong would pop out. Here is my latest full code that sticks when trying to open the file to play. As a new user, can't upload it as a file. sorry.
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
// These are the pins used for the music maker shield
#define MP3_RESET -1 // VS1053 reset pin (unused!)
//#define SD_CS 4 // SD Card select pin ; Use the one on the grand central
#define MP3_CS 7 // VS1053 chip select pin (output)
#define DREQ 3 // VS1053 Data request, ideally an Interrupt pin, common between breakout and shield
#define MP3_DCS 6 // VS1053 Data/command select pin (output)
//The MusicMaker Shield uses dedicated pins for SPI (SCK, MISO, MOSI)
//For a mega/grandcentral m4, please jumper or solder the pads to insure the common SPI 6pin connector is used
//#define CLK 13 // SPI Clock, shared with SD card
//#define MISO 12 // Input data, from VS1053/SD card
//#define MOSI 11 // Output data, to VS1053/SD card
// Connect CLK, MISO and MOSI to hardware SPI pins or you will not get any sound output
//This is the definition needed for the OLED display using i2C protocol
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
#define OLED_ADDRESS 0x3C //OLED i2C address
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
// On an arduino UNO: A4(SDA), A5(SCL) is defined by the Wire Library
// Button press Arrays
int buttonPushCounter[7] = {0,0,0,0,0,0,0}; // counter for the number of button presses
int buttonState[7] = {0,0,0,0,0,0,0}; // current state of the button
int lastButtonState[7] = {0,0,0,0,0,0,0}; // previous state of the button
//Individual Button Press
int buttonPressCounter = 0;
int buttonCurrentState = 0;
int buttonLastState = 0;
//track & SD management variables
File root;
int numSongs = 0;
int currentSong = 0;
bool waitingForInput = false;
const char * SDSongTitle[99]; // will create an array of const char * elements for each song that hopefully won't get corrupted. Limiting to 100 songs
unsigned int songSize[99];
//Allows compatibility with MO boards for serial output
#if defined(ARDUINO_SAMD_ZERO) && defined(SERIAL_PORT_USBVIRTUAL)
// Required for Serial on Zero based boards
#define Serial SERIAL_PORT_USBVIRTUAL
#endif
//Create new objects of each item attached to Arduino
Adafruit_VS1053_FilePlayer musicPlayer = Adafruit_VS1053_FilePlayer(MP3_RESET, MP3_CS, MP3_DCS, DREQ, SDCARD_SS_PIN);
Adafruit_SSD1306 oled(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
//This is run once only and then program goes to the loop() method
void setup() {
Serial.begin(9600);
beginScreen();
beginMusicMaker();
processSDCardAlt(root);
}
//Main Code loop that is run continuously
void loop() {
checkAllButtons(currentSong); //check to see what button attached to GPIO 1 thru 7 has been pressed and take action thorugh called processButton method
updateScreen(); //Update the display
delay(100);
}
void updateScreen(){
if (!musicPlayer.playingMusic){// if no more music playing, display screen to let user know
oled.clearDisplay();
oled.setCursor(0,20);
oled.print("MP3 MUSIC MAKER");
oled.setCursor(0,30);
oled.print("WAITING FOR INPUT");
oled.setCursor(0,40);
oled.print("Songs Available: ");
oled.print(numSongs);
oled.display();
}else{ //Display Number of Songs on SD Card and current track playing
oled.clearDisplay();
oled.setCursor(0,20);
oled.print("MP3 MUSIC MAKER");
oled.setCursor(0,30);
oled.print("Playing Track: ");
oled.print(currentSong);
oled.setCursor(0,40);
oled.print("Songs Available: ");
oled.print(numSongs);
oled.display();
}
}
void beginScreen(){
if (!oled.begin(SSD1306_SWITCHCAPVCC, OLED_ADDRESS)) { //initialize the screen
Serial.println(F("SSD1306 allocation failed"));
while (true); // Don't proceed, loop forever
}
Serial.println("OLED Screen Found");
// Show initial display buffer contents on the screen --
// the library initializes this with an Adafruit splash screen.
oled.display();
delay(2000); // Pause for 2 seconds
oled.clearDisplay(); // Clear the buffer
oled.setTextSize(1); // text size
oled.setTextColor(WHITE); // text color
oled.setCursor(0, 0); // position to display
oled.println("OLED SCREEN ACTIVE!"); // text to display
oled.display(); // show on OLED
}
void beginMusicMaker(){
if (!musicPlayer.begin()) { // initialise the music player
Serial.println(F("Couldn't find VS1053, Check wiring"));
while (true); // Don't proceed, loop forever
}
Serial.println("MP3 Shield Found");
oled.setCursor(0, 20); // position to display
oled.println("MUSICMAKER ATTACHED!"); // text to display
oled.display(); // show on OLED
if (!SD.begin(SDCARD_SS_PIN)) {
Serial.println(F("SD Card failed, or not present"));
for(;;); // Don't proceed, loop forever
}
Serial.println("Micro SD Card Found");
oled.setCursor(0, 30); // position to display
oled.println("SD CARD ATTACHED!"); // text to display
oled.display();
//set the global variable for the root directory now that the serial card has begun
root = SD.open("/");
// If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background audio playing
if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT)){
Serial.println(F("DREQ pin is not an interrupt pin"));
}
Serial.println("DREQ Found. Interrupts enabled");
oled.setCursor(0,40);
oled.println("INTERRUPTS ENABLED");
oled.display();
//set the currentSong index to the first song & set WaitingForInput to TRUE
currentSong = 1;
waitingForInput = true;
// Set volume for left, right channels. lower numbers == louder volume!
musicPlayer.setVolume(1,1);
//set all 7 GPIO pins to inputs to be used as button inputs
for (uint8_t i=1; i<8; i++) {
musicPlayer.GPIO_pinMode(i, INPUT);
}
//delay for 1 seconds before getting sd card contents
delay(1000);
}
void checkAllButtons(int index){
//MusicMakeShield has 7 GPIO pins, check status of all to see if pressed
for (uint8_t i=1; i<8; i++){
// read the pushbutton input pin:
buttonState[i-1] = musicPlayer.GPIO_digitalRead(i); //read in the state of GPIO pins and shift to accomodate array starting with element 0
// compare the buttonState to its previous state
if (buttonState[i-1] != lastButtonState[i-1]) {
// if the state has changed, increment the counter
if (buttonState[i-1] == HIGH) {
oled.clearDisplay();
oled.setCursor(0, 30);
oled.print("Button :");
oled.print(i);
oled.print(" pressed ");
oled.display();
// if the current state is HIGH then the button went from off to on and lets take action
processButton(i, index);
//update the overall counter for appropriate button
buttonPushCounter[i-1] ++;
Serial.println("button :");
Serial.print(i);
Serial.print(" number of times pressed ");
Serial.print(buttonPushCounter[i-1]);
} else {
// if the current state is LOW then the button went from on to off:
Serial.println("button :");
Serial.print(i);
Serial.println(" off");
}
// Delay a little bit to avoid bouncing
delay(50);
}
// save the current state as the last state, for next time through the loop
lastButtonState[i-1] = buttonState[i-1];
}
}
void processSDCardAlt(File dir){
int j = 0;
oled.clearDisplay();
oled.setCursor(0,10);
dir.rewindDirectory();
while(true){
File entry = dir.openNextFile();
if (entry.isDirectory()){
//don't count as a file
}else{
j ++;
}
if (! entry){
j --; //Decrement Counter to correct for actual numbers of files found
// no more files
break;
}
entry.close();
SDSongTitle[j] = entry.name();
songSize[j] = entry.size();
oled.println(String(SDSongTitle[j]) + ": " + String((songSize[j], DEC)));
oled.display();
}
numSongs = j; //update global variable with the number of Songs on the card
delay(5000); //delay 5 seconds before going to main loop
}
void processSDCard(File dir){
int j = 0;
oled.clearDisplay();
oled.setCursor(0,10);
dir.rewindDirectory();
while(true){
File entry = dir.openNextFile();
if (entry.isDirectory()){
//don't count as a file
}else{
SDSongTitle[j] = entry.name();
oled.println(SDSongTitle[j]);
oled.display();
j ++;
}
if (! entry){
j --; //Decrement Counter to correct for actual numbers of files found
// no more files
break;
}
entry.close();
}
numSongs = j; //update global variable with the number of Songs on the card
delay(5000); //delay 5 seconds before going to main loop
}
char * getSong(File dir, int index){
File entry;
char *song;
int j = 0;
//int songTitleLength=0;
oled.clearDisplay();
oled.setCursor(0,20);
oled.println("Selected Track");
oled.display();
dir.rewindDirectory();
while(true){
entry = dir.openNextFile();
if (entry.isDirectory()){ //Skip directories, song will be at root directory only
entry.close();
entry = dir.openNextFile();
}
entry.close();
j++;
if (j == index){
break; //exit, pointer is now at track at requested location
}
}
song = entry.name();
oled.setCursor(0,30);
oled.println(song);
oled.display();
return song;
}
void processButton(int buttonNumber, int index ){
//char* songToPlay;
if(buttonNumber == 0){
//Do nothing. Buttons are momentary.
}
if (buttonNumber == 1 && musicPlayer.playingMusic){ //assign GPI01 to "STOP"
musicPlayer.stopPlaying();
}
if (buttonNumber == 2 && !musicPlayer.playingMusic){ //Start playing song requested
//begin playing file with interrupts active so code can continue
/*
songToPlay = getSong(root, index);
oled.setCursor(0,40);
oled.println(songToPlay);
oled.display();
oled.setCursor(0,40);
oled.println(SDSongTitle[currentSong - 1]); //indexing since array starts at position 0, i.e. song 1 is in slot 0
oled.display();
delay(10000);
*/
oled.clearDisplay();
oled.setCursor(0,0);
oled.println(SDSongTitle[currentSong -1]);
oled.setCursor(0,10);
oled.println(songSize[currentSong]);
oled.display();
//if (! musicPlayer.startPlayingFile("/TRACK002.MP3")){
if (! musicPlayer.startPlayingFile(SDSongTitle[currentSong - 1])){
Serial.println("Could not open the #");
Serial.print(String(index) + " song");
while(1);
}
currentSong++; //For current single button use. Will need to change once more buttons implemented
}
if (buttonNumber == 3 && musicPlayer.playingMusic){ //Assign GPIO2 to "PAUSE"
musicPlayer.pausePlaying(true);
}
if (buttonNumber == 4 && musicPlayer.paused()){ //Assign GPIO3 to "RESUME"
musicPlayer.pausePlaying(false);
}
if (buttonNumber == 4 && currentSong <= numSongs){ //Assing GPIO4 to "NEXT TRACK"
//UPDATE THE FILE NAME TO NEXT ONE & Increment the global variable for current track
currentSong ++;
}
if (buttonNumber ==5 && currentSong >= 2){ //Assing GPIO4 to "PREVIOUS TRACK"
//UPDATE THE FILE NAME TO Previous ONE & Decrement the global variable for current track
currentSong --;
}
}