// include SPI, MP3 and SD libraries
#define TEST
#ifdef TEST
// Do not use the swpcific hardware to play sound
// use Serial.println() instead
#else
#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);
#endif
// Structure that holds the relevant playlist data
// It provides the functions to increment the index
// and to restart from the beginning
struct PlayListType {
String Name; // Name of the playlist (for humans)
int StartFileNo; // The number of the first file in the list
int MaxFiles; // The numbers of sequential files in the list
int LastFilePlayed; // The last index (offset to StartFileNo) played
void Increment(); // Function that increments the index and avoids "overflow"
void Restart(); // Function to reset the index to zero
};
// This defines what the Increment() function does
// Inside this function the variables of the struct
// can be used directly
void PlayListType::Increment() {
LastFilePlayed += 1;
if (LastFilePlayed >= MaxFiles) {
LastFilePlayed = 0;
};
}
// Just to avoid that you have to cope with struct content
// in your sketch directly.
// MainTitle.Reset();
// is identical to
// MainTitle.LastFilePlayed = 0;
void PlayListType::Restart() {
LastFilePlayed = 0;
}
// Now the declaration of the playlists with
// PlayListType PlayListName {"Name", StartFileNo, MaxFiles, LastFilePlayed};
PlayListType ShieldsKlingon {"ShieldsKlingon", 8, 2, 0};
PlayListType ViewScreen {"ViewScreen", 1, 2, 0};
PlayListType Astrogator {"Astrogator", 3, 2, 0};
PlayListType SensorTrack {"SensorTrack", 17, 4, 0};
PlayListType SickbayTrack {"SickbayTrack", 21, 4, 0};
PlayListType EngineeringTrack {"EngineeringTrack", 31, 4, 0};
PlayListType TransporterTrack {"TransporterTrack", 25, 3, 0};
PlayListType DestructTrack {"DestructTrack", 35, 4, 0};
PlayListType MainTitle {"MainTitle", 28, 3, 0};
PlayListType MusicTrack {"MusicTrack", 39, 22, 0};
PlayListType BridgeTrack {"BridgeTrack", 9, 8, 0};
// This function takes one of those playlist structures and
// creates the appropriate filename "online"
// and uses the common function startPlayingFile()
void playList(PlayListType &pl, boolean restart) {
if (restart) pl.Restart();
playFile(pl.StartFileNo + pl.LastFilePlayed);
pl.Increment();
}
// Begin of Struct to handle the switches
struct SwitchType {
byte No;
byte pin;
boolean state = false;
void setPin(byte aPin);
boolean changed();
unsigned long lastChange = 0;
byte lastState;
bool changeOk = false;
};
//define the Switch Type
void SwitchType::setPin(byte aPin) {
pin = aPin;
pinMode(pin, INPUT_PULLUP);
lastState = digitalRead(pin);
}
//Define the SwitchType changed
boolean SwitchType::changed() {
byte actState = digitalRead(pin);
if (lastState != actState) {
lastState = actState;
lastChange = millis();
changeOk = true;
}
if (millis() - lastChange > 30 && changeOk) {
changeOk = false;
state = lastState;
return true;
} else return false;
}
// End of Struct to handle the switches
// Definition of Switches
const byte NoOfSwitches = 8;
SwitchType Switch[NoOfSwitches]; // Declaration of the switches
byte SwitchPin[NoOfSwitches] = {31, 33, 35, 37, 39, 41, 43, 45}; // pins of the switches
enum {Red, Yellow, Blue, White, LtBlue, Green, Gray, Black}; // Enumeration that keeps track of the human switch naming
// Variable for the LEDs used
int leds[9] = {26, 28, 30, 32, 34, 36, 38, 40, 42};
int OPStatus = LOW;
void setup() {
Serial.begin(115200);
Serial.println("Adafruit VS1053 Simple Test");
#ifdef TEST
// No musicplayer, no SD card required
#else
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"));
if (!SD.begin(CARDCS)) {
Serial.println(F("SD failed, or not present"));
while (1); // don't do anything more
}
if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT))
Serial.println(F("DREQ pin is not an interrupt pin"));
#endif
// put your setup code here, to run once:
// setup Pin Modes
for (int i = 0; i < NoOfSwitches; i++) {
Switch[i].No = i + 1;
Switch[i].setPin(SwitchPin[i]);
}
for (int jj; jj < sizeof(leds) / sizeof(int); jj++) {
pinMode(leds[jj], OUTPUT);
delay(10);
}
}
void loop() {
handleSwitchRed();
handleSwitchYellow();
handleSwitchBlue();
handleSwitchWhite();
handleSwitchLtBlue();
handleSwitchGreen();
handleSwitchGray();
handleSwitchBlack();
if (Switch[Red].state) blinkLEDs();
else setLEDsTo(HIGH);
}
void setLEDsTo(byte state) {
for (int i = 0; i < sizeof(leds) / sizeof(int); i++)
digitalWrite(leds[i], state);
}
void blinkLEDs() {
static long int delayTime = 0;
static long int lastSwitchTime = 0;
static byte state = HIGH;
if (millis() - lastSwitchTime > delayTime) {
lastSwitchTime = millis();
delayTime = random(25, 1000);
digitalWrite(leds[random(0, sizeof(leds) / sizeof(int))], state);
state = !state;
}
}
void playFile(int Number) {
char aFilename[80];
sprintf(aFilename, "track%03d.mp3", Number);
#ifdef TEST
Serial.print("Playing ");
Serial.println(aFilename);
#else
if (musicPlayer.playingMusic) musicPlayer.stopPlaying();
musicPlayer.startPlayingFile(aFilename);
musicPlayer.setVolume(1, 1);
#endif
}
void playFullFile(int Number) {
char aFilename[80];
sprintf(aFilename, "track%03d.mp3", Number);
#ifdef TEST
Serial.print("Playing Fullfile ");
Serial.println(aFilename);
delay(5000); // Simulates a playbacktime of 5 seconds ...
#else
musicPlayer.playFullFile(aFilename);
#endif
}
void Reaction(uint16_t aSwitch) {
if (Switch[Red].state) {
// If Red is On
switch (aSwitch) {
case Red : playFullFile(61);
break;
case Yellow : playList(ViewScreen, false);
break;
case Blue : playList(Astrogator, false);
break;
case White : playList(SensorTrack, false);
break;
case LtBlue : playList(SickbayTrack, false);
break;
case Green : playList(TransporterTrack, false);
break;
case Gray : playList(MusicTrack, false);
break;
}
} else {
// If Red is Off
switch (aSwitch) {
case Red : playFile(62);
break;
case Yellow : playList(ShieldsKlingon, false);
break;
case Blue : playFile(5);
break;
case White : playFile(6);
break;
case LtBlue : playList(EngineeringTrack, false);
break;
case Green : playList(DestructTrack, false);
break;
case Gray : playList(MainTitle, false);
break;
}
}
}
void handleSwitchRed() {
if (Switch[Red].changed()) Reaction(Red);
}
void handleSwitchYellow() {
if (Switch[Yellow].changed()) {
if (Switch[Yellow].state) Reaction(Yellow);
else playFile(62);
}
}
void handleSwitchBlue() {
if (Switch[Blue].changed()) {
if (Switch[Blue].state) Reaction(Blue);
else playFile(62);
}
}
void handleSwitchWhite() {
if (Switch[White].changed()) {
if (Switch[White].state) Reaction(White);
else playFile(62);
}
}
void handleSwitchLtBlue() {
if (Switch[LtBlue].changed()) {
if (Switch[LtBlue].state) Reaction(LtBlue);
else playFile(62);
}
}
void handleSwitchGreen() {
if (Switch[Green].changed()) {
if (Switch[Green].state) Reaction(Green);
else playFile(62);
}
}
void handleSwitchGray() {
if (Switch[Gray].changed()) {
if (Switch[Gray].state) Reaction(Gray);
else playFile(62);
}
}
void handleSwitchBlack() {
if (Switch[Black].changed()) {
if (Switch[Black].state) playList(BridgeTrack, false);
else playFile(62);
}
}