Advertisement
kowalyshyn_o

MP3_Trigger

Feb 22nd, 2018
86
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 10.57 KB | None | 0 0
  1. // "Trigger" example sketch for Lilypad MP3 Player
  2. // Mike Grusin, SparkFun Electronics
  3. // http://www.sparkfun.com
  4.  
  5. // This sketch (which is preloaded onto the board by default),
  6. // will play a specific audio file when one of the five trigger
  7. // inputs (labeled T1 - T5) is momentarily grounded.
  8.  
  9. // You can place up to five audio files on the micro-SD card.
  10. // These files should have the desired trigger number (1 to 5)
  11. // as the first character in the filename. The rest of the
  12. // filename can be anything you like. Long file names will work,
  13. // but will be translated into short 8.3 names. We recommend using
  14. // 8.3 format names without spaces, but the following characters
  15. // are OK: .$%'-_@~`!(){}^#&. The VS1053 can play a variety of
  16. // audio formats, see the datasheet for information.
  17.  
  18. // By default, a new trigger will interrupt a playing file, except
  19. // itself. (In other words, a new trigger won't restart an
  20. // already-playing file). You can easily change this behavior by
  21. // modifying the global variables "interrupt" and "interruptself"
  22. // below.
  23.  
  24. // This sketch can output serial debugging information if desired
  25. // by changing the global variable "debugging" to true. Note that
  26. // this will take away trigger inputs 4 and 5, which are shared
  27. // with the TX and RX lines. You can keep these lines connected to
  28. // trigger switches and use the serial port as long as the triggers
  29. // are normally open (not grounded) and remain ungrounded while the
  30. // serial port is in use.
  31.  
  32. // Uses the SdFat library by William Greiman, which is supplied
  33. // with this archive, or download from http://code.google.com/p/sdfatlib/
  34.  
  35. // Uses the SFEMP3Shield library by Bill Porter, which is supplied
  36. // with this archive, or download from http://www.billporter.info/
  37.  
  38. // License:
  39. // We use the "beerware" license for our firmware. You can do
  40. // ANYTHING you want with this code. If you like it, and we meet
  41. // someday, you can, but are under no obligation to, buy me a
  42. // (root) beer in return.
  43.  
  44. // Have fun!
  45. // -your friends at SparkFun
  46.  
  47. // Revision history:
  48. // 1.0 initial release MDG 2012/11/01
  49.  
  50.  
  51. // We'll need a few libraries to access all this hardware!
  52.  
  53. #include <SPI.h>            // To talk to the SD card and MP3 chip
  54. #include <SdFat.h>          // SD card file system
  55. #include <SFEMP3Shield.h>   // MP3 decoder chip
  56.  
  57. // Constants for the trigger input pins, which we'll place
  58. // in an array for convenience:
  59.  
  60. const int TRIG1 = A0;
  61. const int TRIG2 = A4;
  62. const int TRIG3 = A5;
  63. const int TRIG4 = 1;
  64. const int TRIG5 = 0;
  65. int trigger[5] = {TRIG1,TRIG2,TRIG3,TRIG4,TRIG5};
  66.  
  67. // And a few outputs we'll be using:
  68.  
  69. const int ROT_LEDR = 10; // Red LED in rotary encoder (optional)
  70. const int EN_GPIO1 = A2; // Amp enable + MIDI/MP3 mode select
  71. const int SD_CS = 9;     // Chip Select for SD card
  72.  
  73. // Create library objects:
  74.  
  75. SFEMP3Shield MP3player;
  76. SdFat sd;
  77.  
  78. // Set debugging = true if you'd like status messages sent
  79. // to the serial port. Note that this will take over trigger
  80. // inputs 4 and 5. (You can leave triggers connected to 4 and 5
  81. // and still use the serial port, as long as you're careful to
  82. // NOT ground the triggers while you're using the serial port).
  83.  
  84. boolean debugging = false;
  85.  
  86. // Set interrupt = false if you would like a triggered file to
  87. // play all the way to the end. If this is set to true, new
  88. // triggers will stop the playing file and start a new one.
  89.  
  90. boolean interrupt = true;
  91.  
  92. // Set interruptself = true if you want the above rule to also
  93. // apply to the same trigger. In other words, if interrupt = true
  94. // and interruptself = false, subsequent triggers on the same
  95. // file will NOT start the file over. However, a different trigger
  96. // WILL stop the original file and start a new one.
  97.  
  98. boolean interruptself = false;
  99.  
  100. // We'll store the five filenames as arrays of characters.
  101. // "Short" (8.3) filenames are used, followed by a null character.
  102.  
  103. char filename[5][13];
  104.  
  105.  
  106. void setup()
  107. {
  108.   int x, index;
  109.   SdFile file;
  110.   byte result;
  111.   char tempfilename[13];
  112.  
  113.   // Set the five trigger pins as inputs, and turn on the
  114.   // internal pullup resistors:
  115.  
  116.   for (x = 0; x <= 4; x++)
  117.   {
  118.     pinMode(trigger[x],INPUT);
  119.     digitalWrite(trigger[x],HIGH);
  120.   }
  121.  
  122.   // If serial port debugging is inconvenient, you can connect
  123.   // a LED to the red channel of the rotary encoder to blink
  124.   // startup error codes:
  125.  
  126.   pinMode(ROT_LEDR,OUTPUT);
  127.   digitalWrite(ROT_LEDR,HIGH);  // HIGH = off
  128.  
  129.   // The board uses a single I/O pin to select the
  130.   // mode the MP3 chip will start up in (MP3 or MIDI),
  131.   // and to enable/disable the amplifier chip:
  132.  
  133.   pinMode(EN_GPIO1,OUTPUT);
  134.   digitalWrite(EN_GPIO1,LOW);  // MP3 mode / amp off
  135.  
  136.  
  137.   // If debugging is true, initialize the serial port:
  138.   // (The 'F' stores constant strings in flash memory to save RAM)
  139.  
  140.   if (debugging)
  141.   {
  142.     Serial.begin(9600);
  143.     Serial.println(F("Lilypad MP3 Player trigger sketch"));
  144.   }
  145.  
  146.   // Initialize the SD card; SS = pin 9, half speed at first
  147.  
  148.   if (debugging) Serial.print(F("initialize SD card... "));
  149.  
  150.   result = sd.begin(SD_CS, SPI_HALF_SPEED); // 1 for success
  151.  
  152.   if (result != 1) // Problem initializing the SD card
  153.   {
  154.     if (debugging) Serial.print(F("error, halting"));
  155.     errorBlink(1); // Halt forever, blink LED if present.
  156.   }
  157.   else
  158.     if (debugging) Serial.println(F("success!"));
  159.  
  160.   // Start up the MP3 library
  161.  
  162.   if (debugging) Serial.print(F("initialize MP3 chip... "));
  163.  
  164.   result = MP3player.begin(); // 0 or 6 for success
  165.  
  166.   // Check the result, see the library readme for error codes.
  167.  
  168.   if ((result != 0) && (result != 6)) // Problem starting up
  169.   {
  170.     if (debugging)
  171.     {
  172.       Serial.print(F("error code "));
  173.       Serial.print(result);
  174.       Serial.print(F(", halting."));
  175.     }
  176.     errorBlink(result); // Halt forever, blink red LED if present.
  177.   }
  178.   else
  179.     if (debugging) Serial.println(F("success!"));
  180.  
  181.   // Now we'll access the SD card to look for any (audio) files
  182.   // starting with the characters '1' to '5':
  183.  
  184.   if (debugging) Serial.println(F("reading root directory"));
  185.  
  186.   // Start at the first file in root and step through all of them:
  187.  
  188.   sd.chdir("/",true);
  189.   while (file.openNext(sd.vwd(),O_READ))
  190.   {
  191.     // get filename
  192.  
  193.     file.getFilename(tempfilename);
  194.  
  195.     // Does the filename start with char '1' through '5'?      
  196.  
  197.     if (tempfilename[0] >= '1' && tempfilename[0] <= '5')
  198.     {
  199.       // Yes! subtract char '1' to get an index of 0 through 4.
  200.  
  201.       index = tempfilename[0] - '1';
  202.      
  203.       // Copy the data to our filename array.
  204.  
  205.       strcpy(filename[index],tempfilename);
  206.  
  207.       if (debugging) // Print out file number and name
  208.       {
  209.         Serial.print(F("found a file with a leading "));
  210.         Serial.print(index+1);
  211.         Serial.print(F(": "));
  212.         Serial.println(filename[index]);
  213.       }
  214.     }
  215.     else
  216.       if (debugging)
  217.       {
  218.         Serial.print(F("found a file w/o a leading number: "));
  219.         Serial.println(tempfilename);
  220.       }
  221.      
  222.     file.close();
  223.   }
  224.  
  225.   if (debugging)
  226.     Serial.println(F("done reading root directory"));
  227.  
  228.   if (debugging) // List all the files we saved:
  229.   {
  230.     for(x = 0; x <= 4; x++)
  231.     {
  232.       Serial.print(F("trigger "));
  233.       Serial.print(x+1);
  234.       Serial.print(F(": "));
  235.       Serial.println(filename[x]);
  236.     }
  237.   }
  238.  
  239.   // Set the VS1053 volume. 0 is loudest, 255 is lowest (off):
  240.  
  241.   MP3player.setVolume(10,10);
  242.  
  243.   // Turn on the amplifier chip:
  244.  
  245.   digitalWrite(EN_GPIO1,HIGH);
  246.   delay(2);
  247. }
  248.  
  249.  
  250. void loop()
  251. {
  252.   int t;              // current trigger
  253.   static int last_t;  // previous (playing) trigger
  254.   int x;
  255.   byte result;
  256.  
  257.   // Step through the trigger inputs, looking for LOW signals.
  258.   // The internal pullup resistors will keep them HIGH when
  259.   // there is no connection to the input.
  260.  
  261.   // If serial debugging is on, only check triggers 1-3,
  262.   // otherwise check triggers 1-5.
  263.  
  264.   for(t = 1; t <= (debugging ? 3 : 5); t++)
  265.   {
  266.     // The trigger pins are stored in the inputs[] array.
  267.     // Read the pin and check if it is LOW (triggered).
  268.  
  269.     if (digitalRead(trigger[t-1]) == LOW)
  270.     {
  271.       // Wait for trigger to return high for a solid 50ms
  272.       // (necessary to avoid switch bounce on T2 and T3
  273.       // since we need those free for I2C control of the
  274.       // amplifier)
  275.      
  276.       x = 0;
  277.       while(x < 50)
  278.       {
  279.         if (digitalRead(trigger[t-1]) == HIGH)
  280.           x++;
  281.         else
  282.           x = 0;
  283.         delay(1);
  284.       }
  285.        
  286.       if (debugging)
  287.       {
  288.         Serial.print(F("got trigger "));
  289.         Serial.println(t);
  290.       }
  291.  
  292.       // Do we have a valid filename for this trigger?
  293.       // (Invalid filenames will have 0 as the first character)
  294.  
  295.       if (filename[t-1][0] == 0)
  296.       {
  297.         if (debugging)
  298.           Serial.println(F("no file with that number"));
  299.       }
  300.       else // We do have a filename for this trigger!
  301.       {
  302.         // If a file is already playing, and we've chosen to
  303.         // allow playback to be interrupted by a new trigger,
  304.         // stop the playback before playing the new file.
  305.  
  306.         if (interrupt && MP3player.isPlaying() && ((t != last_t) || interruptself))
  307.         {
  308.           if (debugging)
  309.             Serial.println(F("stopping playback"));
  310.  
  311.           MP3player.stopTrack();
  312.         }
  313.  
  314.         // Play the filename associated with the trigger number.
  315.         // (If a file is already playing, this command will fail
  316.         //  with error #2).
  317.  
  318.         result = MP3player.playMP3(filename[t-1]);
  319.  
  320.         if (result == 0) last_t = t;  // Save playing trigger
  321.  
  322.         if(debugging)
  323.         {
  324.           if(result != 0)
  325.           {
  326.             Serial.print(F("error "));
  327.             Serial.print(result);
  328.             Serial.print(F(" when trying to play track "));
  329.           }
  330.           else
  331.           {
  332.             Serial.print(F("playing "));
  333.           }
  334.           Serial.println(filename[t-1]);
  335.         }
  336.       }
  337.     }
  338.   }
  339. }
  340.  
  341.  
  342. void errorBlink(int blinks)
  343. {
  344.   // The following function will blink the red LED in the rotary
  345.   // encoder (optional) a given number of times and repeat forever.
  346.   // This is so you can see any startup error codes without having
  347.   // to use the serial monitor window.
  348.  
  349.   int x;
  350.  
  351.   while(true) // Loop forever
  352.   {
  353.     for (x=0; x < blinks; x++) // Blink the given number of times
  354.     {
  355.       digitalWrite(ROT_LEDR,LOW); // Turn LED ON
  356.       delay(250);
  357.       digitalWrite(ROT_LEDR,HIGH); // Turn LED OFF
  358.       delay(250);
  359.     }
  360.     delay(1500); // Longer pause between blink-groups
  361.   }
  362. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement