Skip to content

Instantly share code, notes, and snippets.

@hz37
Created October 14, 2018 11:25
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hz37/ed35f715b928f03d8fa2d522fc05ce58 to your computer and use it in GitHub Desktop.
Save hz37/ed35f715b928f03d8fa2d522fc05ce58 to your computer and use it in GitHub Desktop.
Arduino Uno using asynchronous music playing in the background while handling button presses using Adafruit shield
// *********************************************************************
// 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>
// *********************************************************************
// Switch debug and release modes.
// #define DEBUGGING
// There is no VS1053 reset pin.
#define SHIELD_RESET -1
// VS1053 Data request.
#define DREQ 3
// Card chip select pin.
#define CARDCS 4
// VS1053 Data/command select pin (output).
#define SHIELD_DCS 6
// VS1053 chip select pin (output).
#define SHIELD_CS 7
// Def volume at startup.
#define DEF_VOLUME 40
// Max song.
#define MAX_SONG 44
// *********************************************************************
// Instance of Adafruit_VS1053_FilePlayer.
Adafruit_VS1053_FilePlayer musicPlayer = Adafruit_VS1053_FilePlayer
(
SHIELD_RESET,
SHIELD_CS,
SHIELD_DCS,
DREQ,
CARDCS
);
// Global vars, bad practice but easy in this case.
uint16_t song = 0;
char songBuffer[8];
uint16_t volume = 0;
// *********************************************************************
void setup()
{
#ifdef DEBUGGING
Serial.begin(9600);
Serial.println("Draaimolen 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()
{
// File is playing in the background
if (musicPlayer.stopped())
{
NextSong();
}
uint16_t buttons = musicPlayer.GPIO_digitalRead();
switch(buttons)
{
case 4:
// Skip 10 songs.
Skip10Songs();
break;
case 8:
// Next song.
NextSong();
break;
case 16:
// Previous song.
PreviousSong();
break;
case 32:
// Higher volume.
if(volume > 0)
{
volume -= 2;
}
musicPlayer.setVolume(volume, volume);
break;
case 64:
// 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()
{
song -= 1;
if(song < 1)
{
song = MAX_SONG;
}
PlayCurrent();
}
// *********************************************************************
void NextSong()
{
song += 1;
if(song > MAX_SONG)
{
song = 1;
}
PlayCurrent();
}
// *********************************************************************
void Skip10Songs()
{
song += 10;
if(song > MAX_SONG)
{
song -= MAX_SONG;
}
PlayCurrent();
}
// *********************************************************************
void PlayCurrent()
{
musicPlayer.stopPlaying();
sprintf(songBuffer, "%.02d.mp3", song);
musicPlayer.startPlayingFile(songBuffer);
delay(10);
}
// *********************************************************************
@ygreq
Copy link

ygreq commented Apr 20, 2021

Hey there, Hens! I am curious. Do you happen to have this project documented somewhere else as well? I am curious about how you connected the buttons and how the installation actually works. I believe I am trying to do something similar.

Thank you so much!

@hz37
Copy link
Author

hz37 commented Apr 21, 2021

Hi! Unfortunately there is no other documentation. But the Adafruit wav shield is very straightforward to use. You can add buttons to the GPIO and assign your own functions. Couldn't be easier, really. Also a very good shield. It has stereo playback of several kinds of sound files. I loudness normalised them all and we connected to garden variety 8 Ohm speakers. Wonderful sound

@ygreq
Copy link

ygreq commented Apr 21, 2021

Did you use the WAV shield or the VS1053? I have both. I actually have used the VS1053 on a couple of projects. Now I want to update one of the projects to have the Next and Previous buttons options. This is why I was curious about your project. I see that you code differently than how I am used to :). For example I always get confused whenever I see uint8_t being used. ;))

Anyway I will try to get inspired by your example. Maybe I will write to you in private in case you can explain a few things about what you did in this sketch. You used lots of comments so that is a good thing.

Thank you so much!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment