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
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;
}