#include #include #include #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 DREQ 3 // VS1053 Data request, ideally an Interrupt pin #define CARDCS 4 // Card chip select 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); //Adafruit_VS1053_FilePlayer musicPlayer = // Adafruit_VS1053_FilePlayer(SHIELD_CS, SHIELD_DCS, DREQ, CARDCS); // VS1053 play speed parameter #define para_playSpeed 0x1E04 // constants won't change // the number of the pin that is used for the pushbuttons const int buttonsPin = A0; // the pin of the potentiometer that is used to control the volume const int volumePin = A1; // wait before next click is recognized const int buttonPressedDelay = 1000; // variables will change byte currentFolder = 1; unsigned int currentFile = 0; unsigned int numberOfFiles[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; // the current volume level, set to min at start byte volumeState = 254; // last button that was pressed byte lastPressedButton = 0; // is the last pressed button released boolean released = true; // remember if the back button was pressed last time byte lastReleasedButton = 0; // the time at the back button was pressed last time long lastBackButtonTime = 0; char currentTrackFileName[] = "/0/current.txt"; // the setup routine runs once when you turn the device on or you press reset void setup() { // disable LED L pinMode(13, OUTPUT); digitalWrite(13, LOW); // initialize serial communication at 9600 bits per second Serial.begin(9600); // initialise the music player if (!musicPlayer.begin()) { Serial.println("VS1053 not found"); while (1); // don't do anything more } // initialise the SD card SD.begin(CARDCS); // 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 musicPlayer.sineTest(0x44, 100); // Make a tone to indicate VS1053 is working // read the number of tracks in each folder for (byte i = 0; i < 10; i++) { String temp = "/"; temp.concat(i); char filename[3]; temp.toCharArray(filename, sizeof(filename)); numberOfFiles[i] = countFiles(SD.open(filename)); //Serial.print(filename); //Serial.print(": "); //Serial.println(numberOfFiles[i]); } // read remembered track if (SD.exists(currentTrackFileName)) { File file = SD.open(currentTrackFileName, FILE_READ); if (file) { currentFolder = file.readStringUntil('\n').toInt(); currentFile = file.readStringUntil('\n').toInt() - 1; } file.close(); } delay(1000); // init delay } // counts the number of files in directory unsigned int countFiles(File dir) { unsigned int counter = 0; while (true) { File entry = dir.openNextFile(); if (!entry) { // no more files break; } counter++; entry.close(); } dir.close(); return counter; } // the loop routine runs over and over again forever void loop() { // play next song if player stopped Serial.println(musicPlayer.stopped()); if (musicPlayer.stopped()) { playNext(); } //Serial.println("Play state End"); // check the volume and set it checkVolume(); //Serial.println("Volume state End"); // check if a button is pressed and perform some action checkButtons(); //Serial.println("Button state End"); delay(1000); // delay in between reads for stability } // checks the value of the potentiometer // if it has changed by 2 then set the new volume void checkVolume() { // read the state of the volume potentiometer int read = analogRead(volumePin); // set the range of the volume from max=0 to min=254 // (limit max volume to 20 and min to 60) byte state = map(read, 0, 1023, 20, 60); // recognize state (volume) changes in steps of two if (state < volumeState - 1 || state > volumeState + 1) { // remember the new volume state volumeState = state; // set volume max=0, min=254 musicPlayer.setVolume(volumeState, 254); // print out the state of the volume Serial.print(volumePin); Serial.print(" volume "); Serial.println(volumeState); } } // check if some button is pressed // play first track, if button is not pressed last time // play next track, if a button is pressed again void checkButtons() { // get the pressed button byte pressedButton = getPressedButton(); // if a button is pressed if (pressedButton != 0) { Serial.print("Taste: "); Serial.println(pressedButton); // if a track/play list button is pressed if (pressedButton < 10 && released) { musicPlayer.stopPlaying(); if (currentFolder == pressedButton) { playNext(); Serial.print("Play music: "); Serial.println(pressedButton); } else { currentFolder = pressedButton; currentFile = 1; playCurrent(); } } // if a function button is pressed else { if (pressedButton == 10 && released) { musicPlayer.stopPlaying(); long time = millis(); // this is the second press within 1 sec., so we // got to the previous track if (lastReleasedButton == 10 && ((time - lastBackButtonTime) < buttonPressedDelay)) { playPrevious(); } else { playCurrent(); } lastBackButtonTime = time; } else if (pressedButton == 11 && released) { // increase play speed musicPlayer.sciWrite(VS1053_REG_WRAMADDR, para_playSpeed); musicPlayer.sciWrite(VS1053_REG_WRAM, 3); Serial.println("increase speed"); } } released = false; lastReleasedButton = pressedButton; } else { released = true; // reset play speed if (lastPressedButton == 11) { musicPlayer.sciWrite(VS1053_REG_WRAMADDR, para_playSpeed); musicPlayer.sciWrite(VS1053_REG_WRAM, 1); } } // remember pressed button lastPressedButton = pressedButton; } void playPrevious() { currentFile--; if (currentFile < 1) { currentFile = numberOfFiles[currentFolder]; } playCurrent(); } void playNext() { Serial.println("IN playNext loop"); currentFile++; if (currentFile > numberOfFiles[currentFolder]) { currentFile = 1; } playCurrent(); } void playCurrent() { if (numberOfFiles[currentFolder] > 0) { rememberCurrentTrack(); String temp = "/"; temp.concat(currentFolder); temp.concat("/"); temp.concat(currentFile); temp.concat(".mp3"); char filename[temp.length() + 1]; temp.toCharArray(filename, sizeof(filename)); musicPlayer.startPlayingFile(filename); Serial.print("Play "); Serial.println(filename); } } void rememberCurrentTrack() { if (SD.exists(currentTrackFileName)) { SD.remove(currentTrackFileName); } File file = SD.open(currentTrackFileName, FILE_WRITE); if (file) { file.println(currentFolder); file.println(currentFile); } file.close(); } // returns 0 if no button is pressed, // else the number of the pressed button is returned (1 - 11) byte getPressedButton() { int buttonsPinValue = analogRead(buttonsPin); byte pressedButton = 0; Serial.print("Button Volt: "); Serial.println(buttonsPinValue); if (buttonsPinValue > 1020) { // button 6 has a value of about 878 pressedButton = 6; } else if (buttonsPinValue > 897) { // button 5 has a value of about 768 pressedButton = 5; } else if (buttonsPinValue > 797) { // button 4 has a value of about 683 pressedButton = 4; } else if (buttonsPinValue > 717) { // button 3 has a value of about 614 pressedButton = 3; } else if (buttonsPinValue > 652) { // button 2 has a value of about 559 pressedButton = 2; } else if (buttonsPinValue > 596) { // button 1 has a value of about 512 pressedButton = 1; } else if (buttonsPinValue > 496) { // if no button is pressed the value is of about 473 pressedButton = 0; } else if (buttonsPinValue > 432) { // button 8 has a value of about 427 pressedButton = 11; } else if (buttonsPinValue > 357) { // button 10 has a value of about 372 pressedButton = 10; } else if (buttonsPinValue > 263) { // button 9 has a value of about 307 pressedButton = 9; } else if (buttonsPinValue > 145) { // button 8 has a value of about 228 pressedButton = 8; } else if (buttonsPinValue > 0) { // button 7 has a value of about 128 pressedButton = 7; } Serial.print("Pressed Button: "); Serial.println(pressedButton); return pressedButton; }