VS1053 Music Maker Shield Freezing loop() thread

Hello All,
It's been a while since I played with Arduino's and it's the first time I have used this type of shield so could use a bit of help as a bit bewildered by something.
In short put together an Arduino Uno with Adafruit VS1053 music maker shield like this tutorial. Overview | Adafruit Music Maker Shield | Adafruit Learning System.

The basic player example plays as intended so I thought happy days. Adafruit_VS1053_Library/player_simple.ino at master · adafruit/Adafruit_VS1053_Library · GitHub

Now the bit I can't get my head around is there are two functions.

musicPlayer.playFullFile("/track002.mp3"); // plays the full file and code waits until the end
musicPlayer.startPlayingFile("/track002.mp3"); // plays for the file but can be interrupted

This seems to work as expected if run in the setup() loop. As an example the following sequence starts playing the first file then after 1 second plays the next file then after 1 second plays the next. This is expected design functionality.

setup() {
     musicPlayer.startPlayingFile("/track002.mp3");
     delay(1000);
     musicPlayer.startPlayingFile("/eng_2000.wav");
     delay(1000);
     musicPlayer.startPlayingFile("/eng_3000.wav");
}

If I run the above code in the loop() "loop" it waits until each file is finished, then has the 1 second delay and then plays the next file in the sequence and by debugging you can see that the code is frozen until the line playing the file is returned. This is not very useful if you want to actively control the player and not run it in a pre-defined sequence.

In short what I want to achieve is to use the loop() like a start/stop/next track etc to control the music maker but I can't because the main loop() gets frozen. I've tried running it in a different function and in other platforms I might consider running async but I can't understand why it isn't working because it should and it works fine in the setup() loop which is "theoretically" calling it in the same manner.

Any help greatly appreciated as I can't crack it at the moment.

Can you post your code? I'm trying to wrap my head around what you want to do and not getting there. The code you posted works as intended, so how to you want to start/stop/next track? By Button push? That you would need to code in there.

Hello Thanks for your reply. Sorry I haven’t replied quicker (young baby doesn’t allow much computer time!).

The end goal essentially is to use button inputs to control the sound files used and interrupt the current sound file played. I was going step by step so was starting off using the serial input to mimic button presses but that wasn’t behaving as intended so I stripped it back even further to try and understand what was going on.

The project is actually for a friend who is making a electric go-kart for his daughter but wanted it to make car sounds so it will be a mixture of button /potentiometer inputs to trigger sounds.

I think I have started to get to the bottom of it. It looks like with this uno/shield setup it is better at handling certain filetypes over others. So for example mp3’s seem to be preferred to wav files. The second part of it is it doesn’t seem to like getting commands to the musicplayer in relatively quick succession for example every second. The setup loop appears to handle this semi ok but the main loop seems to struggle if the delays are less than 2000ms. It appears to stop playing the tracks after a period of time but at least I am starting to head in the right direction.

When I get another chance I will have a bit more of a play to see if I can find out why it is struggling using a few more of the debug tools. Below is the test code I have just been using.

/*************************************************** 
  This is an example for the Adafruit VS1053 Codec Breakout

  Designed specifically to work with the Adafruit VS1053 Codec Breakout 
  ----> https://www.adafruit.com/products/1381

  Adafruit invests time and resources providing this open source code, 
  please support Adafruit and open-source hardware by purchasing 
  products from Adafruit!

  Written by Limor Fried/Ladyada for Adafruit Industries.  
  BSD license, all text above must be included in any redistribution
 ****************************************************/

// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// define the pins 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. 
// See http://arduino.cc/en/Reference/SPI "Connections"

// These are the pins used for the breakout example
#define BREAKOUT_RESET  9      // VS1053 reset pin (output)
#define BREAKOUT_CS     10     // VS1053 chip select pin (output)
#define BREAKOUT_DCS    8      // VS1053 Data/command select pin (output)
// These are the pins used for the music maker shield
#define SHIELD_RESET  -1      // VS1053 reset pin (unused!)
#define SHIELD_CS     7      // VS1053 chip select pin (output)
#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)

// These are common pins between breakout and shield
#define CARDCS 4     // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin

Adafruit_VS1053_FilePlayer musicPlayer = 
  // create breakout-example object!
  //Adafruit_VS1053_FilePlayer(BREAKOUT_RESET, BREAKOUT_CS, BREAKOUT_DCS, DREQ, CARDCS);
  // create shield-example object!
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);

// SLock variable declaration
bool engineStarted = false;
bool engineRunning = false;
bool stopEngine = true;
unsigned long turnOnTimestamp = 0;
unsigned long startUpTimestamp = 0;
unsigned long engineRunningTimestamp = 0;
unsigned long cycleTimestamp = 0;

void setup() {
  Serial.begin(9600);
  Serial.println("Adafruit VS1053 Simple Test");

  if (! musicPlayer.begin()) { // initialise the music player
     Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
     while (1);
  }
  Serial.println(F("VS1053 found"));
  
   if (!SD.begin(CARDCS)) {
    Serial.println(F("SD failed, or not present"));
    while (1);  // don't do anything more
  }

  // list files
  printDirectory(SD.open("/"), 0);
  
  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(20,20);

  // Timer interrupts are not suggested, better to use DREQ interrupt!
  //musicPlayer.useInterrupt(VS1053_FILEPLAYER_TIMER0_INT); // timer int

  // If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background
  // audio playing
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int

  // Record the timestamp of the device turning on
  turnOnTimestamp = millis();
  Serial.print("Program Started: ");
  Serial.println(turnOnTimestamp);
  musicPlayer.startPlayingFile("/track001.mp3");
  delay(1000);
  musicPlayer.startPlayingFile("/track002.mp3");
  delay(1000);
  musicPlayer.startPlayingFile("/track003.mp3");
  delay(2000);
}

// Main Loop
void loop() {
  Serial.print("Loop Started: ");
  Serial.println(millis());
  Serial.println(musicPlayer.stopped());
  musicPlayer.startPlayingFile("/track001.mp3");
  delay(2000);
  musicPlayer.startPlayingFile("/track002.mp3");
  delay(2000);
  musicPlayer.startPlayingFile("/track003.mp3");
  delay(2000);
}

/// File listing helper
void printDirectory(File dir, int numTabs) {
   while(true) {
     
     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
       //Serial.println("**nomorefiles**");
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');
     }
     Serial.print(entry.name());
     if (entry.isDirectory()) {
       Serial.println("/");
       printDirectory(entry, numTabs+1);
     } else {
       // files have sizes, directories do not
       Serial.print("\t\t");
       Serial.println(entry.size(), DEC);
     }
     entry.close();
   }
}

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.