Halting setup

I’m currently playing around with an Adafruit Music Maker Shield and I’ve noticed in the example that the code is set up to freeze halfway through setup if the shield interface pins or the SD card are not initialised correctly.

It does this with a while(1); loop (see lines 53 and 59). It also sends a message to the serial port telling the user about the error.

Since I won’t have a computer, I was hoping to send a “message” to the user through the built-in LED. So I changed the line:

while(1);

to:

pinMode(13, OUTPUT);
while (1)
{
  digitalWrite(13, HIGH);
  delay(500);
  digitalWrite(13, LOW);
  delay(500);
}

However, the LED does not blink. Is there something obvious I’m overlooking here or can you simply not create a pseudo loop function within setup like that?

Full original code is shown below

/***************************************************

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

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); // don't do anything more
  }

  Serial.println(F("VS1053 found"));

  if (!SD.begin(CARDCS)) {
    Serial.println(F("SD failed, or not present"));
    while (1);
  }

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

  // Play one file, don't return until complete
  Serial.println(F("Playing track 001"));
  musicPlayer.playFullFile("track001.mp3");
  // Play another file in the background, REQUIRES interrupts!
  Serial.println(F("Playing track 002"));
  musicPlayer.startPlayingFile("track002.mp3");
}

void loop() {
  // File is playing in the background
  if (musicPlayer.stopped()) {
    Serial.println("Done playing music");
    while (1);
  }
  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);
      }
    }
  }

  delay(100);
}

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

try..

pinMode(13, OUTPUT); digitalWrite(13, HIGH); while(1);

then the LED will go on and stay on.

while(1); just loops on itself forever.

-jim lee

Show the altered code if that's the one that is giving you problems.

There's nothing to stop you from having a while loop and blinking an led in setup. It's just a normal function like any other. Anything that would work in any other function will work in setup. So maybe you did something else wrong when you changed it.

jimLee:
try…

pinMode(13, OUTPUT);
digitalWrite(13, HIGH);
while(1);

then the LED will go on and stay on.

while(1); just loops on itself forever.

-jim lee

I want to put it in the while loop because there are two possible error points so I would like to have two different blinking patterns.

Delta_G:
Show the altered code if that’s the one that is giving you problems.

Haha I should have known I wouldn’t get away with writing what I did. Actual code below. Tested on two separate computers and two different Unos with the same result now.

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

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?"));
    pinMode(13, OUTPUT);
    while (1)
    {
      digitalWrite(13, HIGH);
      delay(500);
      digitalWrite(13, LOW);
      delay(500);
    }
  }
  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

  // Play one file, don't return until complete
  Serial.println(F("Playing track 001"));
  musicPlayer.playFullFile("track001.mp3");
  // Play another file in the background, REQUIRES interrupts!
  Serial.println(F("Playing track 002"));
  musicPlayer.startPlayingFile("track002.mp3");
}

void loop() {
  // File is playing in the background
  if (musicPlayer.stopped()) {
    Serial.println("Done playing music");
    while (1);
  }
  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);
      }
    }
  }

  delay(100);
}


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

Do you see the error message in the Serial monitor ?

UKHeliBob: Do you see the error message in the Serial monitor ?

Yes it shows:

Adafruit VS1053 Simple Test Couldn't find VS1053, do you have the right pins defined?

Which tells me it's at least getting to the newly modified while loop but without a debugger or a good understanding of back end stuff I don't know what it is doing once it hits that line

I only see one place where you want to blink?

Further pinMode is only set if musicPlayer.begin() in setup fails. If you need that blink somewhere else and musicPlayer.begin() in setup did not fail, pin 13 is an input. Put the pinMode in setup outside any conditions.

What happens if you run the Blink example in the IDE ? Which Arduino board are you using ?

sterretje: I only see one place where you want to blink?

Further pinMode is only set if musicPlayer.begin() in setup fails. If you need that blink somewhere else and musicPlayer.begin() in setup did not fail, pin 13 is an input. Put the pinMode in setup outside any conditions.

I only put it there for testing whether it would work so I would be confident that is the only little block I have touched from the example. If/when I get it working I intend on putting pinMode somewhere smarter and putting a similar loop after the SD card check.

UKHeliBob: What happens if you run the Blink example in the IDE ? Which Arduino board are you using ?

I have tried it on a YourDuino RoboRed and a Freetronics Eleven. Both are Uno knock-offs but I especially trust the YourDuino to be as good as the real thing. Blink works on both boards from the two different computers, both of which are running different versions of the IDE.

Load the Blink example. Does the onboard LED blink on your "Arduino"s?

Yep, I tested Blink on both boards as one of the first troubleshooting steps

If you add

Serial.print("Blinking like an fool");

in the while(1) body, does that message get printed?

I can not see anything that would explain the behavior you are reporting.

PaulS: If you add

Serial.print("Blinking like an fool");

in the while(1) body, does that message get printed?

I can not see anything that would explain the behavior you are reporting.

Well how about that, it prints every second. So I guess somehow my digitalWrites are incorrect then?

saximus: Well how about that, it prints every second. So I guess somehow my digitalWrites are incorrect then?

I'm wondering if the Arduino is communicating with the board you are using using SPI. If so, that would explain why the LED on pin 13 isn't blinking.

Try connecting an LED (with current limiting resistor) to a different pin (say pin 4), and blinking that pin, instead.

Of course, a link to the board you are using, and the library, would not be amiss.

You are using SPI. SPI uses pin13, Looks like your shields are messing up your use of pin 13.

Mark

Rats got it first M

PaulS: I'm wondering if the Arduino is communicating with the board you are using using SPI. If so, that would explain why the LED on pin 13 isn't blinking.

holmes4: You are using SPI. SPI uses pin13, Looks like your shields are messing up your use of pin 13.

Mark

Rats got it first M

Thank you so much gentlemen! It absolutely uses SPI and I have no experience with SPI on Arduino so it wasn't even on my radar.

Paul, it may be moot now but this is the shield: Music Maker Shield

I've now added the SPI.end() method to the if statement which has allowed me regain control of the pin and get it working exactly as intended.

Thank you again very much.