0

Music Player with Adafruit VS1053 or WAV Shield?
Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.

Music Player with Adafruit VS1053 or WAV Shield?

by ygreq on Fri Apr 30, 2021 6:47 am

Hi there!

I am looking for a simple music player tutorial featuring either the Adafruit VS1053 or the WAV Shield as I have both.

I would like to have 3 buttons in total. Button 1 and 2 would act as Previous and Next buttons and the 3rd one as Start Play Once.
Any suggestions or links?

Thank you so much!!

ygreq
 
Posts: 54
Joined: Mon May 02, 2011 11:17 am

Re: Music Player with Adafruit VS1053 or WAV Shield?

by ygreq on Fri Apr 30, 2021 5:11 pm

Ok, so I found this project that is using a VS1053: https://gist.github.com/hz37/ed35f715b928f03d8fa2d522fc05ce58
I modified it to suit my needs. For now I am trying to change the songs by pressing 2 out of 4 buttons from a RF remote. But I have a problem with the interrupts. It seems it does not let me switch song while a song is playing. It does work in the second code where I use serial.Read to change songs. So I am guessing it has something to do with RCSwitch library for RF devices. And maybe to the way I ordered the code or to the way mySwitch.resetAvailable() is functioning.

Any help is truely appreciated.

The first code using RCSwitch:
Code: Select all | TOGGLE FULL SIZE
// https://gist.github.com/hz37/ed35f715b928f03d8fa2d522fc05ce58

// *********************************************************************
// Merry-go-round using Arduino Uno en Adafruit VS1053 shield.
// H.Zimmerman, 13-10-2018, Weesp.
// Code based on Adafruit examples:
// https://github.com/adafruit/Adafruit_VS1053_Library
// *********************************************************************

#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
// *********************************************************************

// Switch debug and release modes.

#define DEBUGGING

// 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 6     // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 2       // VS1053 Data request, ideally an Interrupt pin

// Instance of Adafruit_VS1053_FilePlayer.
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);
 
// Def volume at startup.
#define DEF_VOLUME 20

// Max song.
#define MAX_SONG 4

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


// Global vars, bad practice but easy in this case.

uint16_t song = 0;
char songBuffer[8];

uint16_t volume = 0;

//long buttonA = 6286817;
//long buttonB = 6286818;
//long buttonC = 6286820;
//long buttonD = 6286824;

// constants won't change. They're used here to set pin numbers:
//const int pirPin = 5;     // the number of the pushbutton pin
//const int relayPin = 4;      // the number of the LED pin

// Variables will change:
//int relayState = LOW;     // the current state of the output pin
//int pirState;             // the current reading from the input pin
// *********************************************************************
 
void setup()
{
mySwitch.enableReceive(1);  // RF Receiver on interrupt 1 => that is pin #3
// initialize the PIR pin as an input and the Relay pin as output:
//pinMode(pirPin, INPUT);
//pinMode (relayPin, OUTPUT);


#ifdef DEBUGGING 
  Serial.begin(9600);
  Serial.println("Pufarici start.");
#endif

// Initialise the music player shield.

  if (!musicPlayer.begin())
  {
#ifdef DEBUGGING
     Serial.println(F("musicPlayer.begin() error."));
#endif
     while(true);
  }

#ifdef DEBUGGING
  Serial.println(F("VS1053 found"));
#endif
 
  if (!SD.begin(CARDCS))
  {
#ifdef DEBUGGING
      Serial.println(F("SD failed, or not present"));
#endif
      while(true);
  }

#ifdef DEBUGGING
  // List files.
 
  printDirectory(SD.open("/"), 0);
#endif

  // Set GPIO pins to input.

  for(uint8_t idx = 0; idx < 8; ++idx)
  {
    musicPlayer.GPIO_pinMode(idx, INPUT);
  }
 
  // Set volume for left, right channels. lower numbers == louder volume!.

  volume = DEF_VOLUME;
  musicPlayer.setVolume(volume, volume);

  // Do background audio playing.
 
#ifdef DEBUGGING
  if(!musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT))
  {
    Serial.println(F("DREQ pin is not an interrupt pin."));
  }
#else
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);
#endif

  // Play file in the background.

  song = 0;

  NextSong();
}

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

void loop()
{
 if (mySwitch.available()) {
  //Serial.println( mySwitch.getReceivedValue() );
  long buttons = mySwitch.getReceivedValue();

  switch(buttons)
  {
    case 6:
      //Serial.println( mySwitch.getReceivedValue() );
      // Play current song.
      PlayCurrent();
      break;
    case 6286824:
      //Serial.println( mySwitch.getReceivedValue());
      // Next song.
      NextSong();
      break;
    case 6286820:
      //Serial.println( mySwitch.getReceivedValue());
      // Previous song.
      PreviousSong();
      break;
    case 6286818:
      // Higher volume.
      if(volume > 0)
      {
        volume -= 2;
      }
      musicPlayer.setVolume(volume, volume);
      Serial.print ("Volume ");
      Serial.println (volume);
      mySwitch.resetAvailable();
      delay(100);
      break;
    case 6286817:
      // Lower volume.
      if(volume < 127)
      {
        volume += 2;
      }
      musicPlayer.setVolume(volume, volume);
      Serial.print ("Volume ");
      Serial.println (volume);
      mySwitch.resetAvailable();
      delay(100);
      break;
  }

  delay(50);
  }
}

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

// File listing helper function.

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

void printDirectory(File dir, int numTabs)
{
   while(true)
   {
     File entry =  dir.openNextFile();
     
     if (!entry)
     {
       break;
     }
     
     for (uint8_t idx = 0; idx < numTabs; ++idx)
     {
       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();
   }
}

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

void PreviousSong()
{
  song -= 1;

  if(song < 1)
  {
    song = MAX_SONG;
  }
  Serial.print ("Song no. ");
  Serial.println (song);
  delay(100);
  PlayCurrent();
  mySwitch.resetAvailable();
}


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

void NextSong()
{
 
  song += 1;

  if(song > MAX_SONG)
  {
    song = 1;
  }
  Serial.print ("Song no. ");
  Serial.println (song);
  delay(100);
  PlayCurrent();
  mySwitch.resetAvailable();
 
}

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

void PlayCurrent()
{
  musicPlayer.stopPlaying();

  //You have to rename the tracks 01.mp3, 02.mp3 etc. in order to be seen by VS1053
  sprintf(songBuffer, "%.02d.mp3", song);   
  musicPlayer.startPlayingFile(songBuffer);
  Serial.print ("Song name ");
  Serial.println (songBuffer);

  delay(10);
}

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


Second code using serial.Read and sending 1 for Previous and 2 for Next
Code: Select all | TOGGLE FULL SIZE
// https://gist.github.com/hz37/ed35f715b928f03d8fa2d522fc05ce58

//Pin Mappings
//pin 1  -
//-pin 2  - DREQ VS1053 Data request, ideally an Interrupt pin
//pin 3  - RF Receiver
//pin 4  - Relay
//pin 5  - PIR
//-pin 6  - CARDCS Card chip select pinSDCS SHIELD_DCS VS1053 Data/command select pin (output)
//pin 7  - SHIELD_CS VS1053 chip select pin (output)
//-pin 8  - XDCS BREAKOUT_DCS VS1053 Data/command select pin (output)
//-pin 9  - RST (BREAKOUT_RESET) VS1053 reset pin (output)
//-pin 10 - CS (BREAKOUT_CS) VS1053 chip select pin (output)
//-pin 11 - MOSI VS1053 Output data, to VS1053/SD card
//-pin 12 - MISO VS1053 Input data, from VS1053/SD card
//-pin 13 - CLK VS1053 SPI Clock, shared with SD card

// *********************************************************************
// Merry-go-round using Arduino Uno en Adafruit VS1053 shield.
// H.Zimmerman, 13-10-2018, Weesp.
// Code based on Adafruit examples:
// https://github.com/adafruit/Adafruit_VS1053_Library
// *********************************************************************

#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

#include <RCSwitch.h>
RCSwitch mySwitch = RCSwitch();
// *********************************************************************

// Switch debug and release modes.

#define DEBUGGING

// 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 6     // Card chip select pin
// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt
#define DREQ 2       // VS1053 Data request, ideally an Interrupt pin

// Instance of Adafruit_VS1053_FilePlayer.
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);
 
// Def volume at startup.
#define DEF_VOLUME 20

// Max song.
#define MAX_SONG 4

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


// Global vars, bad practice but easy in this case.
int incomingByte = 0; // for incoming serial data
uint16_t song = 0;
char songBuffer[8];

uint16_t volume = 0;

//long buttonA = 6286817;
//long buttonB = 6286818;
//long buttonC = 6286820;
//long buttonD = 6286824;

// constants won't change. They're used here to set pin numbers:
//const int pirPin = 5;     // the number of the pushbutton pin
//const int relayPin = 4;      // the number of the LED pin

// Variables will change:
//int relayState = LOW;     // the current state of the output pin
//int pirState;             // the current reading from the input pin
// *********************************************************************
 
void setup()
{
mySwitch.enableReceive(1);  // RF Receiver on interrupt 1 => that is pin #3
// initialize the PIR pin as an input and the Relay pin as output:
//pinMode(pirPin, INPUT);
//pinMode (relayPin, OUTPUT);


#ifdef DEBUGGING 
  Serial.begin(9600);
  Serial.println("Pufarici start.");
#endif

// Initialise the music player shield.

  if (!musicPlayer.begin())
  {
#ifdef DEBUGGING
     Serial.println(F("musicPlayer.begin() error."));
#endif
     while(true);
  }

#ifdef DEBUGGING
  Serial.println(F("VS1053 found"));
#endif
 
  if (!SD.begin(CARDCS))
  {
#ifdef DEBUGGING
      Serial.println(F("SD failed, or not present"));
#endif
      while(true);
  }

#ifdef DEBUGGING
  // List files.
 
  printDirectory(SD.open("/"), 0);
#endif

  // Set GPIO pins to input.

  for(uint8_t idx = 0; idx < 8; ++idx)
  {
    musicPlayer.GPIO_pinMode(idx, INPUT);
  }
 
  // Set volume for left, right channels. lower numbers == louder volume!.

  volume = DEF_VOLUME;
  musicPlayer.setVolume(volume, volume);

  // Do background audio playing.
 
#ifdef DEBUGGING
  if(!musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT))
  {
    Serial.println(F("DREQ pin is not an interrupt pin."));
  }
#else
  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);
#endif

  // Play file in the background.

  song = 0;

  NextSong();
}

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

void loop()
{
 if (Serial.available() > 0) {
  // read the incoming byte:
    incomingByte = Serial.read();
   // say what you got:
    Serial.print("I received: ");
    Serial.println(incomingByte, DEC);
   
  switch(incomingByte)
  {
    case 49:
      //Serial.println( mySwitch.getReceivedValue() );
      // Play current song.
      PlayCurrent();
      break;
    case 50:
      //Serial.println( mySwitch.getReceivedValue());
      // Next song.
      NextSong();
      break;
    case 51:
      //Serial.println( mySwitch.getReceivedValue());
      // Previous song.
      PreviousSong();
      break;
    case 52:
      // Higher volume.
      if(volume > 0)
      {
        volume -= 2;
      }
      musicPlayer.setVolume(volume, volume);
      break;
    case 5:
      // Lower volume.
      if(volume < 127)
      {
        volume += 2;
      }
      musicPlayer.setVolume(volume, volume);
      break;
  }

  delay(50);
  }
}

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

// File listing helper function.

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

void printDirectory(File dir, int numTabs)
{
   while(true)
   {
     File entry =  dir.openNextFile();
     
     if (!entry)
     {
       break;
     }
     
     for (uint8_t idx = 0; idx < numTabs; ++idx)
     {
       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();
   }
}

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

void PreviousSong()
{
  mySwitch.resetAvailable();
  //Serial.println( mySwitch.getReceivedValue());
  song -= 1;

  if(song < 1)
  {
    song = MAX_SONG;
  }
  Serial.print ("Song no. ");
  Serial.println (song);
  delay(100);
  PlayCurrent();
}


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

void NextSong()
{
  mySwitch.resetAvailable();
  //Serial.println( mySwitch.getReceivedValue());
  song += 1;

  if(song > MAX_SONG)
  {
    song = 1;
  }
  Serial.print ("Song no. ");
  Serial.println (song);
  delay(100);
  PlayCurrent();
 
}

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

void PlayCurrent()
{
  mySwitch.resetAvailable();
  //Serial.println( mySwitch.getReceivedValue() );
  musicPlayer.stopPlaying();

  //You have to rename the tracks 01.mp3, 02.mp3 etc. in order to be seen by VS1053
  sprintf(songBuffer, "%.02d.mp3", song);   
  musicPlayer.startPlayingFile(songBuffer);
  Serial.print ("Song name ");
  Serial.println (songBuffer);

  delay(10);
}

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

ygreq
 
Posts: 54
Joined: Mon May 02, 2011 11:17 am

Re: Music Player with Adafruit VS1053 or WAV Shield?

by adafruit_support_mike on Sat May 01, 2021 10:42 pm

What microcontroller are you using, and are you sure the pins you're using support interrupts?

adafruit_support_mike
 
Posts: 62790
Joined: Thu Feb 11, 2010 2:51 pm

Re: Music Player with Adafruit VS1053 or WAV Shield?

by ygreq on Sun May 02, 2021 2:57 am

Hi there, Mike!
I am using VS1053. I am using the interrupt pin #1 (meaning pin 3). So it is not this

I don't know how mySwitch.resetAvailable() is working. I know I need it present so that the RF does not send the command repeatedly. Maybe it is cutting all action so that while song is playing, because of the command, arduino does not know it can receive commands from the RF module? Just a thought.

ygreq
 
Posts: 54
Joined: Mon May 02, 2011 11:17 am

Re: Music Player with Adafruit VS1053 or WAV Shield?

by adafruit_support_mike on Sun May 02, 2021 6:04 pm

The VS1053 is an MP3 codec, not a microcontroller. You need some other device to interact with controls and read data from an SD card.

adafruit_support_mike
 
Posts: 62790
Joined: Thu Feb 11, 2010 2:51 pm

Please be positive and constructive with your questions and comments.