Unable to play multiple tracks on YX5300

Hi all, I hope I can get some help here

I'm trying to build a directional lock with an arduino UNO, with code downloaded from a creator on youtube

There's 3 sound bites to be triggered (and where they are located in the code, code is copied below);

  • (Lines 114 to 124) A chime when an input is detected (button pressed). This is working fine.
  • (Line 190) An unlocking sound when the correct sequence is entered (this is not working)
  • (Line 212) A sound of smashing glass when the incorrect sequence is entered (this is not working)

As suggested, only the first sound bite is triggering, it seems like I am misusing the mp3.playTrack() command but I can't actually find any tutorials on how to use that specific command.

Here is an image of the file layout on the SD card, I believe this is the correct format

image

Code:

#include <AltSoftSerial.h>
#include <Wire.h>
#include <MD_YX5300.h>

/**
 * Electronic Direction Lock
 * 
 * Players must enter the correct sequence of directional input (i.e. U/D/L/R or N/E/S/W)
 * to activate a relay, releasing a maglock or some other output.
 * 
 * The script demonstrates various customisable behaviour:
 * - The correct input sequence may be of any length
 * - Each direction entered may be accompanied by audio or visual feedback to confirm input was registered
 * - Directions may be entered using pushbuttons, touch sensors, or any other momentary inputs arranged in 4-way cardinal directions
 * - Relay may either unlock automatically as soon as the last direction in the sequence is entered,
 *   or players may have to explicity press a "submit" button to submit their input
 * - Sequence of directions input may optionally be displayed on an LCD screen
 */

// DEFINES

// If AUTOCHECK is defined, the sequence entered by the player will be automatically checked 
// against the correct solution after every direction input, and will trigger the relay as soon
// as the last direction is correctly input.
// Otherwise, players must manually press a "submit" button to check the combination entered
#define AUTOCHECK

// If USE_AUDIO is defined, a command is sent via software serial interface to play a sound effect 
// on a connected YX5300 serial MP3 player board when an input is received, and when the correct sequence
// is input. If SFX are not required and no audio player is connected, we exclude the audio code to 
// prevent the script waiting for an acknowledgement from the sound player that will never be sent
#define USE_AUDIO

// INCLUDES
// For debouncing button input. See https://github.com/thomasfredericks/Bounce2

#include <Bounce2.h>

#ifdef USE_AUDIO
  // Software emulated serial interface. See https://github.com/PaulStoffregen/AltSoftSerial
//  #include <AltSoftSerial.h>
  // Serial MP3 Player control. See https://github.com/MajicDesigns/MD_YX5300
//  #include "src/MD_YX5300/MD_YX5300.h"

#endif

// CONSTANTS
// Enumerate each of the possible directional inputs
enum Dir {Down, Right, Up, Left};
// Also create descriptive names (for debugging/visual display)
const char* dirStr[] = {"D", "R", "U", "L"};
// Specify the Arduino GPIO pins to which those directional buttons are attached
const byte dirPins[4] = {A0,A1,A2,A3};
// Define the manual submit button (if AUTOCHECK is not being used)
#ifndef AUTOCHECK
  const byte submitPin = 3;
#endif
// This pin is driven low when correct sequence entered
const byte relayPin = 2;
// The number of directional steps in the solution
const int numSteps = 8;
// The correct sequence of directions that players must enter
const byte correctSequence[numSteps] = {Up, Up, Down, Down, Left, Right, Left, Right};

// GLOBALS
// Create an array of Bounce objects for each input button
Bounce dirSwitches[4] = {Bounce(), Bounce(), Bounce(), Bounce()};
// And the manual "submit" button
#ifndef AUTOCHECK
  Bounce submitSwitch = Bounce();
#endif 
// What step of the sequence is the player currently on?
int currentStep = 0;
#ifdef USE_AUDIO
  // Initialise a software serial interface on the approriate Rx/Tx pins (8/9)
  AltSoftSerial altSerial;
  // And create an MP3 object based on the serial connection
  MD_YX5300 mp3(altSerial);
#endif

// Is the sequence of inputs the player entered correct so far?
bool inputCorrect = true;

void setup() {
  // Initialise a serial connection (used for debugging only)
  Serial.begin(115200);
  Serial.println(__FILE__ __DATE__);

  // Attach a debouncer to every direction switch
  for(int i=0; i<4; i++){
    dirSwitches[i].attach(dirPins[i], INPUT_PULLUP);
  }
  // And for the optional check button
  #ifndef AUTOCHECK
    submitSwitch.attach(submitPin, INPUT_PULLUP);
  #endif
  // Initialise the output pin
  pinMode(relayPin, OUTPUT);
  digitalWrite(relayPin, HIGH);

  #ifdef USE_AUDIO
    // Initialise the serial interface to the MP3 player
    altSerial.begin(9600);
    mp3.begin();
    // Volume is a value from 0-30
    mp3.volume(30);
  #endif


}

void loop() {

  // Loop through all the inputs
  for(int i=0; i<4; i++){    
    // Update the state of this switch
    dirSwitches[i].update();
    // ...has it just been pressed?
    if(dirSwitches[i].rose()){

      #ifdef USE_AUDIO
        // Play the first sound effect on the SD card (i.e. "001.mp3")
        mp3.playTrack(1);
      #endif

      // Print some debug information
      Serial.print(F("Step:"));
      Serial.print(currentStep);
      Serial.print(F(" Input:")); 
      Serial.print(dirStr[i]);

      // If this input was the correct next value in the sequence
      if(i == correctSequence[currentStep]){
        // Debug only
        Serial.println(F(" - Correct!"));
      }
      // If the direction entered was incorrect
      else {
        // Set flag that user has made at least one incorrect entry in the sequence
        inputCorrect = false;
        // Debug only
        Serial.print(F(" - Incorrect!"));
        if(currentStep < numSteps){
          Serial.print(F(" Should have been "));
          Serial.println(dirStr[correctSequence[currentStep]]);
        }
        else {
          Serial.println(F(" Sequence too long."));
        }
      }
      // Continue to the next element of the sequence
      currentStep++;

      // If autocheck is enabled, we check the sequence entered and unlock 
      // as soon as the final input is entered
      #ifdef AUTOCHECK
        if(currentStep == numSteps){
          if(inputCorrect){
            onSolve();
          }
          else {
            onFailure();
          }
        }
      #endif
    }
  }
  // If not using autocheck, players need to explicitly press submit button to test sequence entered
  #ifndef AUTOCHECK
    // Check if submit button was pressed
    submitSwitch.update();
    if(submitSwitch.fell()){
      if(inputCorrect && currentStep == numSteps){
        onSolve();
      }
      else {
        onFailure();
      }
    }
  #endif
}

// This function is called when players submit the correct sequence of directions
void onSolve() {
  // Debug
  Serial.println("Solved!");

  #ifdef USE_AUDIO
    // Play the second sound effect on the SD card (i.e. "002.mp3")
    mp3.playTrack(2);
  #endif

  // Release the maglock
  digitalWrite(relayPin, LOW);
  
  delay(5000);
  digitalWrite(relayPin, HIGH);

  // And reset the controller
  currentStep = 0;
  inputCorrect = true;
}


// This function is called when player's submit an incorrect sequence of directions
void onFailure() {
  // Debug
  Serial.println("Incorrect!");

  #ifdef USE_AUDIO
    // Play the third sound effect on the SD card (i.e. "003.mp3")
    mp3.playTrack(3);
  #endif

  delay(2000);

  // And reset the controller
  currentStep = 0;
  inputCorrect = true;
}

The code lines didn't display so I'm pasting them here for ease of viewing

It's probably worth mentioning that the serial monitor is functioning as it should so it seems the OnSolve and OnFailure functions are working properly

Soundbite #1 (working)

image

Soundbite #2 (not working)

image

Soundbite #3

Rename the files ###.mp3... does that make a difference?

Sparkfun says:

      /* Use the playTrack function to play a numbered track: */
      uint8_t result = MP3player.playTrack(lastTrigger);
      // An alternative here would be to use the
      //  playMP3(fileName) function, as long as you mapped
      //  the file names to trigger pins.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.