/* Created by: Michael Ross Date: 2013-04-05 Arduino Controlled MP3 Player for integration into a Vintage AM Radio This code is for use with an Arduino UNO with the Sparkfun.com MP3 Player Shield. It uses a rotary potentiometer to get position input from the radio dial then triggers a software controlled switch (Relay) to cut the input from the antenna and supply the MP3 audio through an audio transformer to the input of the radio. This allows the audio signal to be isolated from the radio but still use the tube amps of the radio for amplification of the signal and the volume control as well. The program basically plays a commercial, then plays 2 random songs and keeps repeating this until the station is changed. The station chosen picks the range of MP3 files that will be played. The file name numbering range for the mp3 files is as follows: (*** SEE NOTE BELOW REGARDING CHANGES TO THE LIBRARY FOR FILE NAME FORMAT! ***) 00001 - 02999 = 20's, 30' and 40's 03000 - 05999 = 50's and 60's 06000 - 08999 = Sci-Fi Shows 09000 - 11999 = Comedy Shows 12000 - 14999 = Mystery & Adventure Shows 15000 - 17999 = Christmas Music 18000 - 20999 = Kenyon (Personal Stuff from tapes) 21000 - 23999 = Old WWII Era News 24000 - 26999 = Favorites 27000 - 29999 = Old Commercials ****************************************************************************************** ****************************************************************************************** *** IMPORTANT NOTE!!! *** ****************************************************************************************** I made a change to the playTrack function in the SFEMP3Shield.cpp library file to allow for more than just 999 tracks on the SD card. The expected format for file names on the SD card WAS "track999.mp3". I changed this to "trk99999.mp3" since the file names need to stick with the 8.3 format. You MUST make the same change to the same function in the same file if you want to be able to use the function to play a track by track number. I ended up playing them by name instead so if you are using this code as is, then it will work without the change. But if you change any of it to play by track number and have gone above 999 tracks, then you will need to make the change!!! - Here is what was specifcally changed: CHANGED FROM: -------------------------------------- uint8_t SFEMP3Shield::playTrack(uint8_t trackNo){ //a storage place for track names char trackName[] = "track001.mp3"; uint8_t trackNumber = 1; //tack the number onto the rest of the filename sprintf(trackName, "track%03d.mp3", trackNo); //play the file return playMP3(trackName); ---------------------------------------------------- CHANGED TO:----------------------------------------- uint8_t SFEMP3Shield::playTrack(uint8_t trackNo){ //a storage place for track names char trackName[] = "trk00001.mp3"; uint8_t trackNumber = 1; //tack the number onto the rest of the filename sprintf(trackName, "trk%05d.mp3", trackNo); //play the file return playMP3(trackName); ****************************************************************************************** ****************************************************************************************** ****************************************************************************************** The possible commands for the MP3 Player are as follows: MP3player.begin() - To get the MP3 player ready to play MP3player.stopTrack() - Stop playing the current track MP3player.playTrack(#) - Play a specifically numbered track MP3player.trackTitle((char*)&title) - Get Title of the playing Track MP3player.trackArtist((char*)&artist) - Get the Artist of the playing Track MP3player.trackAlbum((char*)&album) - Get the Album name of the playing track MP3player.getVolume() - Gets the currently set volume level MP3player.setVolume(mp3_vol.byte[1], mp3_vol.byte[1]) - Set New Volume level MP3player.getPlaySpeed() - Get current play speed MP3player.setPlaySpeed(playspeed) - Set New Play speed MP3player.getState() - Get the current state of the player MP3player.pauseMusic() - Pause the MP3 Player MP3player.resumeMusic(2000) - Resume Playing MP3player.setMonoMode(1) - Set player to Mono Mode MP3player.setMonoMode(0) - Set player to Stereo Mode */ // The Arduino Libraries needed for this script #include #include #include #include int potPin = 0; // select the input pin for the potentiometer (Analog 0) int potVal = 0; // variable to store the value of the potentiometer int oldpotVal = 99999; // variable to keep track if pot has changed position int potValRange = 0; // variable to hold the station number for the range int onStation = 0; // variable to control the relay state int randNum = random(1, 1948); // variable Random number for choosing MP3 File to play int CrandNum = random(1, 190); // variable Random number for choosing commercial to play String trackname = " "; // variable to hold the File Name int tracksPlayed = 1; // variable to keep track of the number of tracks played int commercialplayed = 1; // variable to limit how often commercials are played int commTime = 1200; // varialbe for Define how often commercials are played. 1200 = 10 minutes char filename[100] = ""; // These are variables for the Low and High Ranges of each station's MP3 Files // The file name MUST stay below the high end positive Integer boundry for the // Arduinio which is 32767. So they are divided into ranges of 3000 files each. // The plus 1 is added since the random function subtracts one from the upper limit // ** These need to be specific to range of files you have for each showing the actual upper limit ** // Twenties and Thirties int stat1Low = 1; int stat1High = 1947 + 1; // Fifties and Sixties int stat2Low = 3000; int stat2High = 3719 + 1; // Sci-Fi Shows int stat3Low = 6000; int stat3High = 6216 + 1; // Comedy Shows int stat4Low = 9000; int stat4High = 9114 + 1; // Mystery and Adventure Shows int stat5Low = 12000; int stat5High = 12198 + 1; // Christmas Music int stat6Low = 15000; int stat6High = 15229 + 1; // Kenyon Music (Personal Recordings) int stat7Low = 18000; int stat7High = 18034 + 1; // WWII and other News (from the 40's) int stat8Low = 21000; int stat8High = 21354 + 1; // Favorites int stat9Low = 24000; int stat9High = 24063 + 1; // Commercials int commLow = 27000; int commHigh = 27188 + 1; SdFat sd; SFEMP3Shield MP3player; void setup() { // The serial setup is to be able to monitor the state of the program for testing // and debug purposes using the Serial Monitor window. It can be commented out when // everything is work as you want it to. Serial.begin(9600); pinMode(potPin, OUTPUT); // Set the mode of the potPin to Output mode pinMode(A3, OUTPUT); // Set the mode of the pin used for the relay control to Output digitalWrite(A3, LOW); // Set the relay pin to LOW // Start up the Sparkfun MP3 Player shield, set the mode to Mono and volume to high sd.begin(SD_SEL, SPI_HALF_SPEED); MP3player.begin(); MP3player.setMonoMode(1); MP3player.setVolume(0x00, 0x00); // Get a random number seed from the Analog 5 pin randomSeed(analogRead(5)); randNum = random(stat1Low, stat1High); // delay(10000); } void loop() { // Beging looping to watch for changes in the pot position and play stations or not based on position potVal = analogRead(potPin); // The following lines are for debugging to watch is going on in the Serial Monitor // You can use this to help target specific areas on the dial that you want the stations to // "Play". Change the potValRange numbers to limit the stations to specific areas. Serial.println("----------------------"); Serial.print("randNum - "); Serial.println(randNum); Serial.print("potVal - "); Serial.println(potVal); Serial.print("oldpotVal - "); Serial.println(oldpotVal); Serial.print("potValRange - "); Serial.println(potValRange); Serial.print("Comm - "); Serial.println(commercialplayed); Serial.print("onStation - "); Serial.println(onStation); Serial.print("trackname - "); Serial.println(trackname); Serial.print("filename - "); Serial.println(filename); Serial.print("tracksplayed - "); Serial.println(tracksPlayed); Serial.print("Player State - "); Serial.println(MP3player.getState()); // Check to see if the pot value has changed, to make up for the pot giving a range of signals // even if the position has not changed, we will check it plus or minus 5. If it falls outside // this range, then stop the current current playing track and start looking for it to be be in // one of the station ranges again. if (oldpotVal <= (potVal - 15) || oldpotVal >= (potVal + 15)) { MP3player.stopTrack(); if (onStation == 1) { onStation = 0; // Set the Relay pin to LOW digitalWrite(A3, LOW); tracksPlayed = 1; potValRange = 0; } oldpotVal = potVal; } // Check potVal to see if it is in specific ranges to set the station number to potValRange if it is // potValRange = 0; if (MP3player.getState() != 5) { if (potVal > 1 && potVal < 15) { potValRange = 1; if (onStation == 0) { // Set the Relay Pin to HIGH to switch the MP3 Input on for the radio digitalWrite(A3, HIGH); onStation = 1; } } // This is the second station if (potVal > 115 && potVal < 130) { potValRange = 2; if (onStation == 0) { // Set the Relay Pin to HIGH to switch the MP3 Input on for the radio digitalWrite(A3, HIGH); onStation = 1; } } // This is the third station if (potVal > 345 && potVal < 360) { potValRange = 3; if (onStation == 0) { // Set the Relay Pin to HIGH to switch the MP3 Input on for the radio digitalWrite(A3, HIGH); onStation = 1; } } // This is the fourth station if (potVal > 525 && potVal < 540) { potValRange = 4; if (onStation == 0) { // Set the Relay Pin to HIGH to switch the MP3 Input on for the radio digitalWrite(A3, HIGH); onStation = 1; } } // This is the fifth station if (potVal > 700 && potVal < 715) { potValRange = 5; if (onStation == 0) { // Set the Relay Pin to HIGH to switch the MP3 Input on for the radio digitalWrite(A3, HIGH); onStation = 1; } } // This is the sixth station if (potVal > 840 && potVal < 855) { potValRange = 6; if (onStation == 0) { // Set the Relay Pin to HIGH to switch the MP3 Input on for the radio digitalWrite(A3, HIGH); onStation = 1; } } // This is the seventh station if (potVal > 920 && potVal < 935) { potValRange = 7; if (onStation == 0) { // Set the Relay Pin to HIGH to switch the MP3 Input on for the radio digitalWrite(A3, HIGH); onStation = 1; } } // This is the eighth station if (potVal > 970 && potVal < 985) { potValRange = 8; if (onStation == 0) { // Set the Relay Pin to HIGH to switch the MP3 Input on for the radio digitalWrite(A3, HIGH); onStation = 1; } } // This is the ninth and last station, dial (pot) position full clockwise to the right. if (potVal > 1015) { potValRange = 9; if (onStation == 0) { // Set the Relay Pin to HIGH to switch the MP3 Input on for the radio digitalWrite(A3, HIGH); onStation = 1; } } if (potValRange == 1) { checkCommercial(); randNum = random(stat1Low, stat1High); playStation(); } else if (potValRange == 2) { checkCommercial(); randNum = random(stat2Low, stat2High); playStation(); } else if (potValRange == 3) { checkCommercial(); randNum = random(stat3Low, stat3High); playStation(); } else if (potValRange == 4) { checkCommercial(); randNum = random(stat4Low, stat4High); playStation(); } else if (potValRange == 5) { checkCommercial(); randNum = random(stat5Low, stat5High); playStation(); } else if (potValRange == 6) { checkCommercial(); randNum = random(stat6Low, stat6High); playStation(); } else if (potValRange == 7) { checkCommercial(); randNum = random(stat7Low, stat7High); playStation(); } else if (potValRange == 8) { checkCommercial(); randNum = random(stat8Low, stat8High); playStation(); } else if (potValRange == 9) { checkCommercial(); randNum = random(stat9Low, stat9High); playStation(); } } // This delay will only allow checking of dial position change every half a second delay(500); // This check is to see if the player is busy playing a song. If not, then it increments // the tracks played counter so that favorites are played at the beginning of each station // selection if (MP3player.getState() != 5) { if (onStation == 1) { tracksPlayed = tracksPlayed + 1; } } // Increment the commercial counter by 1 commercialplayed = commercialplayed + 1; // Check to see if we have passed the point to play the next commercial if (commercialplayed >= commTime) { commercialplayed = 1; } } void playStation() { // Generate the file name to be played using the random number created // before calling this function. if (randNum < 10) { trackname = "trk0000"; } else if ((randNum >= 10) && (randNum < 100)) { trackname = "trk000"; } else if ((randNum >= 100) && (randNum < 1000)) { trackname = "trk00"; } else if ((randNum >= 1000) && (randNum < 10000)) { trackname = "trk0"; } else if ((randNum >= 10000) && (randNum < 100000)) { trackname = "trk"; } trackname += randNum; trackname += ".mp3"; if (tracksPlayed < 6) { // The first 5 tracks to be played can be specified here for each station if (potValRange == 1) { // 20's, 30's, and 40's if (tracksPlayed == 1) { trackname = "trk24054.mp3"; } if (tracksPlayed == 2) { trackname = "trk24008.mp3"; } if (tracksPlayed == 3) { trackname = "trk24030.mp3"; } if (tracksPlayed == 4) { trackname = "trk24007.mp3"; } if (tracksPlayed == 5) { trackname = "trk24020.mp3"; } } if (potValRange == 2) { // 50's and 60's if (tracksPlayed == 1) { trackname = "trk03012.mp3"; } if (tracksPlayed == 2) { trackname = "trk03100.mp3"; } if (tracksPlayed == 3) { trackname = "trk03113.mp3"; } if (tracksPlayed == 4) { trackname = "trk03072.mp3"; } if (tracksPlayed == 5) { trackname = "trk03044.mp3"; } } if (potValRange == 3) { // Sci-Fi if (tracksPlayed == 1) { trackname = "trk06066.mp3"; } if (tracksPlayed == 2) { trackname = "trk06009.mp3"; } if (tracksPlayed == 3) { tracksPlayed = 5; } if (tracksPlayed == 4) { tracksPlayed = 5; } if (tracksPlayed == 5) { tracksPlayed = 5; } } if (potValRange == 4) { // Comedy if (tracksPlayed == 1) { trackname = "trk09016.mp3"; } if (tracksPlayed == 2) { trackname = "trk09013.mp3"; } if (tracksPlayed == 3) { tracksPlayed = 5; } if (tracksPlayed == 4) { tracksPlayed = 5; } if (tracksPlayed == 5) { tracksPlayed = 5; } } if (potValRange == 5) { // Mystery if (tracksPlayed == 1) { trackname = "trk12191.mp3"; } if (tracksPlayed == 2) { trackname = "trk12198.mp3"; } if (tracksPlayed == 3) { tracksPlayed = 5; } if (tracksPlayed == 4) { tracksPlayed = 5; } if (tracksPlayed == 5) { tracksPlayed = 5; } } if (potValRange == 6) { // Christmas if (tracksPlayed == 1) { trackname = "trk15009.mp3"; } if (tracksPlayed == 2) { trackname = "trk15122.mp3"; } if (tracksPlayed == 3) { trackname = "trk15006.mp3"; } if (tracksPlayed == 4) { tracksPlayed = 5; } if (tracksPlayed == 5) { tracksPlayed = 5; } } if (potValRange == 7) { // Kenyon if (tracksPlayed == 1) { trackname = "trk18018.mp3"; } if (tracksPlayed == 2) { trackname = "trk18027.mp3"; } if (tracksPlayed == 3) { trackname = "trk18019.mp3"; } if (tracksPlayed == 4) { trackname = "trk18020.mp3"; } if (tracksPlayed == 5) { trackname = "trk18033.mp3"; } } if (potValRange == 8) { // News if (tracksPlayed == 1) { trackname = "trk21065.mp3"; } if (tracksPlayed == 2) { trackname = "trk21066.mp3"; } if (tracksPlayed == 3) { trackname = "trk21000.mp3"; } if (tracksPlayed == 4) { tracksPlayed = 5; } if (tracksPlayed == 5) { tracksPlayed = 5; } } } trackname.toCharArray(filename, 100); // Play the specific File MP3player.playMP3(filename); } void checkCommercial() { if (commercialplayed <= 60) { playCommercial(); } } void playCommercial() { CrandNum = random(commLow, commHigh); trackname = "trk"; trackname += CrandNum; trackname += ".mp3"; char filename[100] = " "; trackname.toCharArray(filename, 100); if (tracksPlayed >= 6) { MP3player.playMP3(filename); } //Serial.println(filename); }