Go Down

Topic: Adafruit Musik Maker Shield freezing (Read 1 time) previous topic - next topic

jkiddmd

Dear Forum,
Oh that did not sound right.
Dear members,
I recently purchased and loaded up the Musik Maker Shield. The example codes have worked fine. I modified the simple test so that I could specify which track to play by placing an input on the serial monitor. The problem I have encountered is that the player will sometimes freeze. I don't know if this is because of my admittedly amateurish code or if there is a problem inherent in the player.
Your thoughts would be helpful. I am attempting to attach the code.
Kidd
Code: [Select]
***************************************************
 * 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
 ****************************************************/
// This code modified by Kidd in order to determine if player can play a file while the
//loop continues to function and the instructions to the GPIO pins work.

// 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);

void setup() {
  Serial.begin(9600);
  Serial.println("Adafruit VS1053 Simple Test");
  Serial.println("Modified by Kidd for radio restoration");
  Serial.println("Select a track number on the keyboard and press ENTER");
 
 
 

  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"));

  SD.begin(CARDCS);    // initialise the SD card

  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(10,10);

  // 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


}

void loop() {

 
  if (Serial.available()) {
    char c = Serial.read();

    // if we get an 's' on the serial console, stop!
    if (c == 's') {
      musicPlayer.stopPlaying();
    }

    // if we get an 'p' on the serial console, pause/unpause!
    if (c == 'p') {
      if (! musicPlayer.paused()) {
        Serial.println("Paused");
        musicPlayer.pausePlaying(true);
      }
      else {
        Serial.println("Resumed");
        musicPlayer.pausePlaying(false);
      }
    }
    //Play track 001 if serial "1"input on monitor
    if (c == '1') {
      musicPlayer.stopPlaying();
      Serial.println("Player stopping.");
     
      musicPlayer.startPlayingFile("track001.mp3");
      Serial.println("Playing track 001");
      c=='0'; // Reset variable c so it is not '1' when loop swings around or track 001
      // will start repeatedly and freeze
    }
    if (c=='2') {
      musicPlayer.stopPlaying();
      Serial.println("Player stopping.");
     
      musicPlayer.startPlayingFile("track002.mp3");
      Serial.println("Playing track 002");
      c=='0';
    }
    if (c=='3') {
      musicPlayer.stopPlaying();
      Serial.println("Player stopping.");
     
      musicPlayer.startPlayingFile("track003.m4a");
      Serial.println("Playing track 003");
      c=='0';
    }
    if (c=='4') {
      musicPlayer.stopPlaying();
      Serial.println("Player stopping.");
     
      musicPlayer.startPlayingFile("track004.m4a");
      Serial.println("Playing track 004");
      c=='0';
    }
    if (c=='5') {
      musicPlayer.stopPlaying();
      Serial.println("Player stopping.");
     
      musicPlayer.startPlayingFile("track005.m4a");
      Serial.println("Playing track 005");
      c=='0';
    }
    if (c=='6') {
      musicPlayer.stopPlaying();
      Serial.println("Player stopping.");
     
      musicPlayer.startPlayingFile("track006.m4a");
      Serial.println("Playing track 006");
      c=='0';
    }
    if (c=='7') {
      musicPlayer.stopPlaying();
      Serial.println("Player stopping.");
     
      musicPlayer.startPlayingFile("track007.m4a");
      Serial.println("Playing track 007");
      c=='0';
    }
    if (c=='8') {
      musicPlayer.stopPlaying();
      Serial.println("Player stopping.");
     
      musicPlayer.startPlayingFile("track008.m4a");
      Serial.println("Playing track 008");
      c=='0';
    }

  }
}

jurs

Your thoughts would be helpful. I am attempting to attach the code.
Your board is an Arduino UNO?

When using SD card and Serial, a lot of RAM on an UNO is already in use, so it would be a good idea to save RAM while programming.

One possibility to save RAM would be, always to use the F-macro when printing constant texts like:
Code: [Select]

  Serial.println("Adafruit VS1053 Simple Test");
  Serial.println("Modified by Kidd for radio restoration");
  Serial.println("Select a track number on the keyboard and press ENTER");


Replace that (and other printing of constant text) with RAM saving F-macro like that:
Code: [Select]

  Serial.println(F("Adafruit VS1053 Simple Test"));
  Serial.println(F("Modified by Kidd for radio restoration"));
  Serial.println(F("Select a track number on the keyboard and press ENTER"));


Any difference then?

jkiddmd


jkiddmd

Jurs,
    I followed your recommendations but it did not seem to make much of a difference.  Instead, I noticed that if I stopped the player, then waited for a second before toggling the next track, the player was more stable and did not freeze.  So I added a pause after the instruction to stop the player.  The pause had to be at least 1000ms for me to see a difference in stability.  Do you know why this might be?
Kidd
Code: [Select]
***************************************************
 * 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
 ****************************************************/
// This code modified by Kidd in order to determine if player can play a file while the
//loop continues to function and the instructions to the GPIO pins work.

// 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
#define PAUSE 1000

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);

void setup() {
  Serial.begin(9600);
  Serial.println(F("Adafruit VS1053 Simple Test"));
  Serial.println(F("Modified by Kidd for radio restoration"));
  Serial.println(F("Select a track number on the keyboard and press ENTER"));
 
 
 

  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"));

  SD.begin(CARDCS);    // initialise the SD card

  // Set volume for left, right channels. lower numbers == louder volume!
  musicPlayer.setVolume(10,10);

  // 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


}

void loop() {

 
  if (Serial.available()) {
    char c = Serial.read();

    // if we get an 's' on the serial console, stop!
    if (c == 's') {
      musicPlayer.stopPlaying();
    }

    // if we get an 'p' on the serial console, pause/unpause!
    if (c == 'p') {
      if (! musicPlayer.paused()) {
        Serial.println("Paused");
        musicPlayer.pausePlaying(true);
      }
      else {
        Serial.println("Resumed");
        musicPlayer.pausePlaying(false);
      }
    }
    //Play track 001 if serial "1"input on monitor
    if (c == '1') {
      musicPlayer.stopPlaying();
      Serial.println(F("Player stopping."));
      delay(PAUSE); //Added for stability
     
      musicPlayer.startPlayingFile("track001.mp3");
      Serial.println(F("Playing track 001"));
      c=='0'; // Reset variable c so it is not '1' when loop swings around or track 001
      // will start repeatedly and freeze
    }
    if (c=='2') {
      musicPlayer.stopPlaying();
      Serial.println(F("Player stopping."));
      delay(PAUSE);
     
      musicPlayer.startPlayingFile("track002.mp3");
      Serial.println(F("Playing track 002"));
      c=='0';
    }
    if (c=='3') {
      musicPlayer.stopPlaying();
      Serial.println(F("Player stopping."));
      delay(PAUSE);
     
      musicPlayer.startPlayingFile("track003.m4a");
      Serial.println(F("Playing track 003"));
      c=='0';
    }
    if (c=='4') {
      musicPlayer.stopPlaying();
      Serial.println(F("Player stopping."));
      delay(PAUSE);
     
      musicPlayer.startPlayingFile("track004.m4a");
      Serial.println(F("Playing track 004"));
      c=='0';
    }
    if (c=='5') {
      musicPlayer.stopPlaying();
      Serial.println(F("Player stopping."));
      delay(PAUSE);
     
      musicPlayer.startPlayingFile("track005.m4a");
      Serial.println(F("Playing track 005"));
      c=='0';
    }
    if (c=='6') {
      musicPlayer.stopPlaying();
      Serial.println(F("Player stopping."));
      delay(PAUSE);
     
      musicPlayer.startPlayingFile("track006.m4a");
      Serial.println(F("Playing track 006"));
      c=='0';
    }
    if (c=='7') {
      musicPlayer.stopPlaying();
      Serial.println(F("Player stopping."));
      delay(PAUSE);
     
      musicPlayer.startPlayingFile("track007.m4a");
      Serial.println(F("Playing track 007"));
      c=='0';
    }
    if (c=='8') {
      musicPlayer.stopPlaying();
      Serial.println(F("Player stopping."));
      delay(PAUSE);
     
      musicPlayer.startPlayingFile("track008.m4a");
      Serial.println(F("Playing track 008"));
      c=='0';
    }

  }
}

jurs

I followed your recommendations but it did not seem to make much of a difference.  Instead, I noticed that if I stopped the player, then waited for a second before toggling the next track, the player was more stable and did not freeze.  So I added a pause after the instruction to stop the player.  The pause had to be at least 1000ms for me to see a difference in stability.  Do you know why this might be?
I don't know the VS1053 and I don't know the library.

But as the library is interrupt driven and playing in the background, most likely something with the interrupt handling in the library is wrong. Perhaps some interrupt can either initiate loading data from SD after the file was closed so the data loading fails and that error is not handled. I really don't know.

So I'm more guessing. Perhaps you like to do some try and error.

Here are two suggestions what you could try:

1. softReset the VS1053 after stopping and before starting the next file
Code: [Select]

  musicPlayer.stopPlaying();
  musicPlayer.softReset();
  musicPlayer.startPlayingFile("track002.mp3");

 
2. prevent interrupts from firing while stopping the device
Code: [Select]

  noInterrupts();
  musicPlayer.stopPlaying();
  interrupts();
  musicPlayer.startPlayingFile("track002.mp3");


I'd try that, but I cannot tell if that might help.
Perhaps the library is faulty. Google tells, that you are not the only one with a freeze while changing tracks with the Adafruit VS1053 library.

jkiddmd

Thanks so much for your help.  I will work on this this weekend and let you know how it went.
Kidd

jkiddmd

Jurs,
     The softReset() technique worked beautifully.  The platform is very stable now.  Thanks so much for the help.
Kidd

grey_nold

I know this is old but I figure I would put in my 2 cents if anyone comes across a similar problem. I am using this shield as well with a handful of buttons to changes to different songs. I was running into the problem where the music maker shield getting stuck in the playingMusic loop and would not come out. It would also not take new commands even though my code was still able to issue commands when it became stuck. The solution here saved my butt with the soft reset. I guess the chip doesn't like switching songs so quickly is the only thing I can think of.

Go Up