Music Shield MP3 player

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
User avatar
doscherda
 
Posts: 5
Joined: Sat Mar 14, 2015 10:33 pm

Re: Music Shield MP3 player

Post by doscherda »

Mike,

I was able to attach the pictures once I cropped/sized them to below 800x600.... the input voltage that I tested was 5V and 12V.. I know the voltage is hitting the pins (Vin and Gnd) because I measured them...also I attached an amp meter and the board is not pulling any current. There was one solder joint that had some extra solder on it (see picture) but that has been removed and did not actually connect with the nearby Via from what I can tell by measuring.

Again, when I apply 5v to 12v to Vin I should get something at 3v/5v right ????
adafruit_20150317_141942_cropped.JPG
adafruit_20150317_141942_cropped.JPG (127.41 KiB) Viewed 568 times
adafruit_20150317_142003_cropped.JPG
adafruit_20150317_142003_cropped.JPG (62.37 KiB) Viewed 568 times

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Music Shield MP3 player

Post by adafruit_support_mike »

The Music Maker Shield is made to go on an Arduino. The Vin pin doesn't connect to anything else on the shield, but it does connect to the Arduino's 5v regulator when the shield is plugged in. Then the shield draws power from the Arduino's 5v pin.

User avatar
doscherda
 
Posts: 5
Joined: Sat Mar 14, 2015 10:33 pm

Re: Music Shield MP3 player

Post by doscherda »

Mike,

So if I apply 5V to the 5V pin on the Music Maker then the unit will power on ? Should I also apply 3V to the 3V pin ?

I am using an AVR-CAN unit and expect that I can connect the AVR to the Music Maker by mapping the appropriate pins. I will write my own software for the AVR to drive the Music Maker. The documentation is not clear on the power issues and I would like to know exactly what is required to get the unit powered on.

Thanks!
David

User avatar
stem5
 
Posts: 12
Joined: Tue Feb 24, 2015 1:01 pm

Re: Music Shield MP3 player

Post by stem5 »

Hi,
Sorry to keep bothering you, but I have a complex project idea that we have keep facing many obstacles with. The idea of the project is to have a pulse sensor control a music shield. In other words, depending on the person's heart's BPM, different tracks will be playing. To do this, I created a code that mixed your player_simple code, the pulse sensor code, and a map function. The code, however, is not working and I am not sure if it is the music shield or the pulse sensor. I wanted to know which out of all the codes that you provide are best for this sort of manipulation. I don't even know if it is possible to do such a thing, but if so, I would really like to try. If there is any advice that you can give me, I would really appreciate it. I am also attaching the code below so you can understand what I have done.

Thank you

Code:

Code: Select all

//Include Music Shield Library
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// Define everything needed for the Music Shield 
#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)
#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)
#define CARDCS 4              // Card chip select pin
#define DREQ 3                // VS1053 Data request, ideally an Interrupt pin

//Explain what musicplayer means
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);
  
//Variables for the Pulse Sensor 
int pulsePin = 0;                   // Pulse Sensor purple wire connected to analog pin 0
//These variables are volatile because they are used during the interrupt service routine!
volatile int BPM;                   // used to hold the pulse rate
volatile int Signal;                // holds the incoming raw data
volatile int IBI = 600;             // holds the time between beats, must be seeded! 
volatile boolean Pulse = false;     // true when pulse wave is high, false when it's low
volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

//Define integer range for the switchcase map function 
const int sensorMin = 40;           // sensor minimum, dicovered through research MAY CHANGE
const int sensorMax = 180;          // sensor maximum, discovered through research MAY CHANGE

//Now we are going to set up the sensor and the shield. 
//The swtichcase does not need setup because we are not using the serial monitor for it.
void setup(){
Serial.begin(115200);
  Serial.println("Adafruit VS1053 Simple Test");
  interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS 
//Now we setup the rest of the shield. 

  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(05,05);
  
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int

}                  
//Void setup is done, now we tell the arduino what to do with all this information. 

void loop(){
   // read the sensor:
  int sensorReading = analogRead(A0);
  //A0 should be BPM
  // map the sensor range to a range of four options:
  int range = map(sensorReading, sensorMin, sensorMax, 0, 4);

//In our map range 0=70-110, 1=110-150, 2=150-190, 3=190-230, 4=end(DEAD)
// do something different depending on the 
// range value:
//Track 1 is resting music, track 2 is medium beat, track 3 is fast beat, and track 4 is continous beeps. 
  switch (range) {
  case 0:    // 70BPM - 110 BPM
    Serial.println(F("Playing track 001"));
    musicPlayer.playFullFile("track001.mp3"); 
  case 1:    // 110 BPM - 150 BPM
    Serial.println(F("Playing track 002"));
    musicPlayer.startPlayingFile("track002.mp3");
  case 2:    // 150 BPM - 190 BPM
    Serial.println(F("Playing track 003"));
    musicPlayer.startPlayingFile("track003.mp3");
  case 3:    // 190 BPM - 230 BPM 
    Serial.println(F("Dangerous"));
    musicPlayer.startPlayingFile("track004.mp3");
  case 4:    // DEAD
    Serial.println(F("DEAD"));
    musicPlayer.startPlayingFile("track005.mp3");
    break;
  } 
  delay(1);        //This is the delay of the switchcase. 
                   //The Music Shield Requests 100, so this MAY CHANGE
}

This is the interrupt setting for the pulse sensor. I open it in a tab to connect the two codes:



volatile int rate[10];                    // array to hold last ten IBI values
volatile unsigned long sampleCounter = 0;          // used to determine pulse timing
volatile unsigned long lastBeatTime = 0;           // used to find IBI
volatile int P =512;                      // used to find peak in pulse wave, seeded
volatile int T = 512;                     // used to find trough in pulse wave, seeded
volatile int thresh = 512;                // used to find instant moment of heart beat, seeded
volatile int amp = 100;                   // used to hold amplitude of pulse waveform, seeded
volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM


void interruptSetup(){     
  // Initializes Timer2 to throw an interrupt every 2mS.
  TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
  TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER 
  OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
  TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
  sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED      
} 


// THIS IS THE TIMER 2 INTERRUPT SERVICE ROUTINE. 
// Timer 2 makes sure that we take a reading every 2 miliseconds
ISR(TIMER2_COMPA_vect){                         // triggered when Timer2 counts to 124
  cli();                                      // disable interrupts while we do this
  Signal = analogRead(pulsePin);              // read the Pulse Sensor 
  sampleCounter += 2;                         // keep track of the time in mS with this variable
  int N = sampleCounter - lastBeatTime;       // monitor the time since the last beat to avoid noise

    //  find the peak and trough of the pulse wave
  if(Signal < thresh && N > (IBI/5)*3){       // avoid dichrotic noise by waiting 3/5 of last IBI
    if (Signal < T){                        // T is the trough
      T = Signal;                         // keep track of lowest point in pulse wave 
    }
  }

  if(Signal > thresh && Signal > P){          // thresh condition helps avoid noise
    P = Signal;                             // P is the peak
  }                                        // keep track of highest point in pulse wave

  //  NOW IT'S TIME TO LOOK FOR THE HEART BEAT
  // signal surges up in value every time there is a pulse
  if (N > 250){                                   // avoid high frequency noise
    if ( (Signal > thresh) && (Pulse == false) && (N > (IBI/5)*3) ){        
      Pulse = true;                               // set the Pulse flag when we think there is a pulse
      IBI = sampleCounter - lastBeatTime;         // measure time between beats in mS
      lastBeatTime = sampleCounter;               // keep track of time for next pulse

      if(secondBeat){                        // if this is the second beat, if secondBeat == TRUE
        secondBeat = false;                  // clear secondBeat flag
        for(int i=0; i<=9; i++){             // seed the running total to get a realisitic BPM at startup
          rate[i] = IBI;                      
        }
      }

      if(firstBeat){                         // if it's the first time we found a beat, if firstBeat == TRUE
        firstBeat = false;                   // clear firstBeat flag
        secondBeat = true;                   // set the second beat flag
        sei();                               // enable interrupts again
        return;                              // IBI value is unreliable so discard it
      }   


      // keep a running total of the last 10 IBI values
      word runningTotal = 0;                  // clear the runningTotal variable    

      for(int i=0; i<=8; i++){                // shift data in the rate array
        rate[i] = rate[i+1];                  // and drop the oldest IBI value 
        runningTotal += rate[i];              // add up the 9 oldest IBI values
      }

      rate[9] = IBI;                          // add the latest IBI to the rate array
      runningTotal += rate[9];                // add the latest IBI to runningTotal
      runningTotal /= 10;                     // average the last 10 IBI values 
      BPM = 60000/runningTotal;               // how many beats can fit into a minute? that's BPM!
      QS = true;                              // set Quantified Self flag 
      // QS FLAG IS NOT CLEARED INSIDE THIS ISR
    }                       
  }

  if (Signal < thresh && Pulse == true){   // when the values are going down, the beat is over
    Pulse = false;                         // reset the Pulse flag so we can do it again
    amp = P - T;                           // get amplitude of the pulse wave
    thresh = amp/2 + T;                    // set thresh at 50% of the amplitude
    P = thresh;                            // reset these for next time
    T = thresh;
  }

  if (N > 2500){                           // if 2.5 seconds go by without a beat
    thresh = 512;                          // set thresh default
    P = 512;                               // set P default
    T = 512;                               // set T default
    lastBeatTime = sampleCounter;          // bring the lastBeatTime up to date        
    firstBeat = true;                      // set these to avoid noise
    secondBeat = false;                    // when we get the heartbeat back
  }

  sei();                                   // enable interrupts when youre done!
}// end isr
Last edited by adafruit_support_mike on Fri Mar 20, 2015 5:18 am, edited 1 time in total.
Reason: added CODE tags to preserve formatting

User avatar
doscherda
 
Posts: 5
Joined: Sat Mar 14, 2015 10:33 pm

Re: Music Shield MP3 player

Post by doscherda »

Mike,

I would like to know exactly what is required to get the unit powered on without hooking the unit up to another shield.

Thanks!
David

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Music Shield MP3 player

Post by adafruit_support_mike »

@doscherda: You can power the Music Maker by connecting 5v to the 5v pin, but it won't do anything. You need a data connection from a microcontroller like the Arduino to tell it what to do.

See the tutorial for complete information about working with the Music Maker: https://learn.adafruit.com/adafruit-mus ... r/overview


@stem5: You're probably getting interrupt conflicts between the VS1053 and the ISR for your pulse sensor.

The ISR in the code above is far bigger than normal. The longer the CPU spends executing code in an interrupt handler, the higher the chance that it will miss some other interrupt or have timing problems with the main code. The general rule is to collect the smallest amount of information you can in the ISR, then set a flag or other data value that tells the main code to do the heavy lifting.

User avatar
stem5
 
Posts: 12
Joined: Tue Feb 24, 2015 1:01 pm

Re: Music Shield MP3 player

Post by stem5 »

Ok thank you, that makes sense... The problem is that the ISR for the pulse sensor if necessary in order to get an accurate reading of the heartbeat. I cannot shorten it without creating more conflicts. I can, however, make the interrupt routine collect data every minute instead of every 2 milliseconds. Also, is the interrupt routine for the music shield necessary? Maybe I can change the coding into a timer interrupt and then rotate between the pulse sensor interrupting and then the music shield interrupting.

Thank you

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Music Shield MP3 player

Post by adafruit_support_mike »

Your ISR can be as simple as this:

Code: Select all

int Signal;
boolean SignalReady = false;

ISR(TIMER2_COMPA_vect){
  Signal = analogRead(pulsePin);
  SignalReady = true;
}
and the rest of the code can live in your main loop inside the following condition:

Code: Select all

if ( SignalReady ) {
  SignalReady = false;
  //  rest of code
}
As long as you read the input on a controlled interval, you can do the rest of the processing a few microseconds later.

User avatar
stem5
 
Posts: 12
Joined: Tue Feb 24, 2015 1:01 pm

Re: Music Shield MP3 player

Post by stem5 »

That would be for the music shield? Sorry, I'm new to this so that sounds a bit confusing... If that is for the music shield, and it includes Timer2, would the pulse sensor work as well because it also uses Timer2...?

Thank you and sorry

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Music Shield MP3 player

Post by adafruit_support_mike »

I'm pretty sure the interrupt for the Music Maker is on TIMER1, so putting the pulse sensor interrupt on TIMER2 should be okay as long as the interrupt service routine doesn't spend too much time blocking other interrupts.

User avatar
stem5
 
Posts: 12
Joined: Tue Feb 24, 2015 1:01 pm

Re: Music Shield MP3 player

Post by stem5 »

I tried putting the ISR that you told me but this keeps coming up:
"expected unqualified-id before string constant"
I am not sure what that means or how to address it. I searched what string constants are, but nothing comes up. If you have any idea as to what that means it would be helpful.

Thank you

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Music Shield MP3 player

Post by adafruit_support_mike »

The error probably means you missed a semicolon somewhere.

Post the code you're using (between CODE tags please) and we'll see what we can find.

User avatar
stem5
 
Posts: 12
Joined: Tue Feb 24, 2015 1:01 pm

Re: Music Shield MP3 player

Post by stem5 »

Code: Select all

//Include Music Shield Library
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// Define everything needed for the Music Shield 
#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)
#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)
#define CARDCS 4              // Card chip select pin
#define DREQ 3                // VS1053 Data request, ideally an Interrupt pin

//Explain what musicplayer means
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);
  
//Variables for the Pulse Sensor 
int pulsePin = 0;                   // Pulse Sensor purple wire connected to analog pin 0
//These variables are volatile because they are used during the interrupt service routine!
volatile int BPM;                   // used to hold the pulse rate
volatile int Signal;                // holds the incoming raw data
volatile int IBI = 600;             // holds the time between beats, must be seeded! 
volatile boolean Pulse = false;     // true when pulse wave is high, false when it's low
volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

//Define integer range for the switchcase map function 
const int sensorMin = 49;           // sensor minimum, dicovered through research MAY CHANGE
const int sensorMax = 205;          // sensor maximum, discovered through research MAY CHANGE

//Now we are going to set up the sensor and the shield. 
//The swtichcase does not need setup because we are not using the serial monitor for it.
void setup(){
Serial.begin(115200);
  Serial.println("Adafruit VS1053 Simple Test");
  interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS 
//Now we setup the rest of the shield. 

  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(05,05);
  
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int

}                  
//Void setup is done, now we tell the arduino what to do with all this information. 

void loop(){
  if ( SignalReady ) {
  SignalReady = false;
  
   int sensorReading = analogRead(A0);
  //A0 should be BPM
  // map the sensor range to a range of four options:
  int range = map(sensorReading, sensorMin, sensorMax, 0, 4);

  switch (range) {
  case 0:    // 70BPM - 110 BPM
    Serial.println(F("Starting"));
    musicPlayer.playFullFile("track001.mp3"); 
  case 1:    // 110 BPM - 150 BPM
    Serial.println(F("Upbeat"));
    musicPlayer.playFullFile("track002.mp3");
  case 2:    // 150 BPM - 190 BPM
    Serial.println(F("Vigorous"));
    musicPlayer.playFullFile("track003.mp3");
  case 3:    // 190 BPM - 230 BPM 
    Serial.println(F("Dangerous"));
    musicPlayer.playFullFile("track004.mp3");
  case 4:    // DEAD
    Serial.println(F("DEAD"));
    musicPlayer.playFullFile("track005.mp3");
  default: 
     Serial.println(F("NOT WORKING"));
  
  } 
  delay(100);        //This is the delay of the switchcase. 
                   //The Music Shield Requests 100, so this MAY CHANGE
}
 
}

And the ISR changed would be:

Code: Select all


volatile int rate[10];                    // array to hold last ten IBI values
volatile unsigned long sampleCounter = 0;          // used to determine pulse timing
volatile unsigned long lastBeatTime = 0;           // used to find IBI
volatile int P =512;                      // used to find peak in pulse wave, seeded
volatile int T = 512;                     // used to find trough in pulse wave, seeded
volatile int thresh = 512;                // used to find instant moment of heart beat, seeded
volatile int amp = 100;                   // used to hold amplitude of pulse waveform, seeded
volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM


void interruptSetup(){     
  // Initializes Timer2 to throw an interrupt every 2mS.
  TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
  TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER 
  OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
  TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
  sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED      
} 


int Signal;
boolean SignalReady = false;

ISR(TIMER2_COMPA_vect){                        
  Signal = analogRead(pulsePin);
  SignalReady = true;
}

Thank you so much for all the help.

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Music Shield MP3 player

Post by adafruit_support_mike »

This compiles for me:

Code: Select all

//Include Music Shield Library
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

// Define everything needed for the Music Shield
#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)
#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)
#define CARDCS 4              // Card chip select pin
#define DREQ 3                // VS1053 Data request, ideally an Interrupt pin

//Explain what musicplayer means
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);

//Variables for the Pulse Sensor
int pulsePin = 0;                   // Pulse Sensor purple wire connected to analog pin 0
//These variables are volatile because they are used during the interrupt service routine!
volatile int BPM;                   // used to hold the pulse rate
volatile int IBI = 600;             // holds the time between beats, must be seeded!
volatile boolean Pulse = false;     // true when pulse wave is high, false when it's low
volatile boolean QS = false;        // becomes true when Arduoino finds a beat.

//Define integer range for the switchcase map function
const int sensorMin = 49;           // sensor minimum, dicovered through research MAY CHANGE
const int sensorMax = 205;          // sensor maximum, discovered through research MAY CHANGE

volatile int rate[10];                    // array to hold last ten IBI values
volatile unsigned long sampleCounter = 0;          // used to determine pulse timing
volatile unsigned long lastBeatTime = 0;           // used to find IBI
volatile int P = 512;                     // used to find peak in pulse wave, seeded
volatile int T = 512;                     // used to find trough in pulse wave, seeded
volatile int thresh = 512;                // used to find instant moment of heart beat, seeded
volatile int amp = 100;                   // used to hold amplitude of pulse waveform, seeded
volatile boolean firstBeat = true;        // used to seed rate array so we startup with reasonable BPM
volatile boolean secondBeat = false;      // used to seed rate array so we startup with reasonable BPM


void interruptSetup() {
  // Initializes Timer2 to throw an interrupt every 2mS.
  TCCR2A = 0x02;     // DISABLE PWM ON DIGITAL PINS 3 AND 11, AND GO INTO CTC MODE
  TCCR2B = 0x06;     // DON'T FORCE COMPARE, 256 PRESCALER
  OCR2A = 0X7C;      // SET THE TOP OF THE COUNT TO 124 FOR 500Hz SAMPLE RATE
  TIMSK2 = 0x02;     // ENABLE INTERRUPT ON MATCH BETWEEN TIMER2 AND OCR2A
  sei();             // MAKE SURE GLOBAL INTERRUPTS ARE ENABLED
}


volatile int Signal;                // holds the incoming raw data
boolean SignalReady = false;

ISR(TIMER2_COMPA_vect) {
  Signal = analogRead(pulsePin);
  SignalReady = true;
}

//Now we are going to set up the sensor and the shield.
//The swtichcase does not need setup because we are not using the serial monitor for it.
void setup() {
  Serial.begin(115200);
  Serial.println("Adafruit VS1053 Simple Test");
  interruptSetup();                 // sets up to read Pulse Sensor signal every 2mS
  //Now we setup the rest of the shield.

  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(05, 05);

  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int
}
//Void setup is done, now we tell the arduino what to do with all this information.

void loop() {
  if ( SignalReady ) {
    SignalReady = false;

    int sensorReading = analogRead(A0);
    //A0 should be BPM
    // map the sensor range to a range of four options:
    int range = map(sensorReading, sensorMin, sensorMax, 0, 4);

    switch (range) {
      case 0:    // 70BPM - 110 BPM
        Serial.println(F("Starting"));
        musicPlayer.playFullFile("track001.mp3");
      case 1:    // 110 BPM - 150 BPM
        Serial.println(F("Upbeat"));
        musicPlayer.playFullFile("track002.mp3");
      case 2:    // 150 BPM - 190 BPM
        Serial.println(F("Vigorous"));
        musicPlayer.playFullFile("track003.mp3");
      case 3:    // 190 BPM - 230 BPM
        Serial.println(F("Dangerous"));
        musicPlayer.playFullFile("track004.mp3");
      case 4:    // DEAD
        Serial.println(F("DEAD"));
        musicPlayer.playFullFile("track005.mp3");
      default:
        Serial.println(F("NOT WORKING"));
    }
    delay(100);        //This is the delay of the switchcase.
    //The Music Shield Requests 100, so this MAY CHANGE
  }
}
There was a duplicate declaration for 'Signal', but removing that made the compiler happy.

BTW - your switch() probably won't behave the way you expect it to.

In C, the switch() statement uses 'fall-through' syntax. As soon as the input matches a case specifier, all the code from there to the end of the switch() statement executes.

For this code:

Code: Select all

#include <stdio.h>

int main(int argc, char *argv[]) {
	int n = 1;
	
	switch ( n ) {
			case 1:
				printf( "n = 1 case.\n" );
			case 2:
				printf( "n = 2 case.\n" );
			case 3:
				printf( "n = 3 case.\n" );
			default:
				printf( "default case.\n" );
	};
}
the output is:

Code: Select all

n = 1 case.
n = 2 case.
n = 3 case.
default case.
To stop that from happening, you need to add a 'break' statement to the end of each case:

Code: Select all

#include <stdio.h>

int main(int argc, char *argv[]) {
	int n = 1;
	
	switch ( n ) {
			case 1:
				printf( "n = 1 case.\n" );
				break;
			case 2:
				printf( "n = 2 case.\n" );
				break;
			case 3:
				printf( "n = 3 case.\n" );
				break;
			default:
				printf( "default case.\n" );
	};
}

User avatar
stem5
 
Posts: 12
Joined: Tue Feb 24, 2015 1:01 pm

Re: Music Shield MP3 player

Post by stem5 »

Thank you very much for all your help, we have finally been able to get a functioning code. However, there is only one small problem which we would like to fix. Every thirty seconds, when the pulse sensor checks for our heartbeat, it will restart the track corresponding to the heart beat from the beginning, instead of continuing it from where it had left off. We wanted to know if there was any way to make it "continue" playing instead of just "start" playing. If there is no possible way, it is fine.
Thank you
Stem5

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino Shields from Adafruit”