Go Down

Topic: Paid Arduino coding project - probably easy for you but not for me (Read 1 time) previous topic - next topic

Mpstuart

I have a project that I want to make happen that has been a dream of mine since 2001. 

Here are the basics:  I have a mechanical electronic toggle switch.  When that switch is toggled to "on," I want one specific song to instantly play through a car stereo amplifier.  I want anything else that is playing to be overridden and for the selected song to play immediately.
 
What I have:  An Arduino Uno to which I have soldered an Adafruit MP3 shield with a micro-usb containing the track I need it to play.  I also have a 4 relay module that I planned to use to have the amplifier switch immediately to the channel through which the song will play.

I have tried to figure out how to write a code for this but I have absolutely no idea what I am doing.

I feel like this is probably a fairly easy project for someone who knows how to write code.

Thanks for any replies,
Matt



patduino

Sooo...  

I assume you are comfortable with the stereo hardware part of this?  Have you figured out how and where to power the Arduino and relays yet?

I'd start by installing the relays first.  Make sure the "normal" input path goes through the NC (normally closed) path through the relays.  Then we can give you a script to control the relays with a switch and trigger the MP3 player.

- Pat

Actually, I'm trying to find out what song's been stuck in your head for this long!?  Maybe something from 'N Sync or Britney Spears ?!   8)
There are 10 types of people in the world, those who understand binary, and those that don't.

Mpstuart

I am gathering pieces that I need to do the stereo part of this project.  I have not figured out how to power the Arduino yet off of the 12 volt car battery, I assumed that there would be some sort of converter to bring it down to the 5v arduino power source that the arduino needs.  I have a friend who is an electrical engineer that I was hoping would help me figure this part out along with the relays.

I am a real novice with all of this but have been figuring it out along the way.

So my brilliant/ ridiculous idea that I had years ago came to me when I bought this 1967 toyota landcruiser (looks like a Jeep) that I rebuilt.  There are a ton of old toggle switches in there that were probably used to raise plows and stuff.  I had the idea to have one labeled with the name of a single song and when you flip that switch, that song plays instantly.  I originally had AC/DC's Back in Black in mind, but I have decided that the label will say "Turbo" because it seems car related, and the switch will trigger an instant playing of Judas Priest's Turbo Lover.  I know, awesome right?

I am a 42 year old grown man, but I have a dream here, and the technology exists to make it happen now.

Thanks for your help,
Matt

patduino

Hi Matt,

That sounds like an excellent project!  And I approve of your music taste.  (No offense intended to any of the Britney Spears fans out there, however...)

There are numerous 12V -> 5V converters available for automotive use.  Your can Google them or have your EE friend make some recommendations.

Lean on him as well for the connection of the MP3 player to the audio amplifier input.  Depending on the output level of the player, you might need to create a small circuit to convert the output to "line level" to input to your amplifier.

Also - I wouldn't limit myself to a single audio clip.  It sounds like you might have a real rock-and-rollin' jukebox automobile there !

Pat.

PS- a rocket launcher sound clip might come in handy during rush hour traffic, if you've got a "launch" button.  Check this out.
There are 10 types of people in the world, those who understand binary, and those that don't.

Mpstuart

That launcher toggle cover is pretty great.

So, I have been trying to write some code with the help of a slightly more knowledgeable friend and loaded the following code tonight as a test of concept.  I have track001.mp3 on the sd card and I have played it sucessfully with the simple player test sketch.  I have wires going to a toggle from the two GP02 terminals, but completing that circuit with the toggle does not seem to be making it play track001.mp3 like I thought it would.  The code loads fine and the relays which I have also wired for power all light up (I do not have any sources going to them yet though)  Any thoughts?

Code: [Select]

// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

//Defining constants and varibles
// These are the UNO pins used for the music maker shield
const int SHIELD_RESET = -1;      // VS1053 reset pin (unused!)
const int SHIELD_CS = 7;      // VS1053 chip select pin (output)
const int SHIELD_DCS = 6;      // VS1053 Data/command select pin (output)

// These are common pins between UNO breakout and shield
const int CARDCS = 4;     // Card chip select pin
const int DREQ = 3;       // VS1053 Data request, ideally an Interrupt pin

// These are the pins on the MP3 Shield that will connect to the toggle switches
const int GP02_SWITCH = 1;


//Initialise a varible to store the CURRENT state of a switch
int GP02_SWITCH_STATE = LOW;


//Initialise a varible to store the LAST state of a switch
int GP02_SWITCH_LSTATE = LOW;


//Initialise a varible to store the current and last state of a audio play
int PlAY_STATE = false;
int PlAY_LSTATE = false;

//These are the pins on the UNO (through shield breakout) that will control the relay state
const int RIGHT_AUDIO_RELAY = 2;
const int LEFT_AUDIO_RELAY = 5;
const int GROUND_AUDIO_RELAY = 8;
const int AMP_RELAY = 9;



Adafruit_VS1053_FilePlayer musicPlayer =
 // create shield-example object!
 Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
 
//------------------Setup Routine-------------------------------------------------------
// the setup routine runs once when you press reset:
void setup()
 {
   // Configure toggle switch connections as Input
   musicPlayer.GPIO_pinMode(GP02_SWITCH, INPUT);


   // Configure relay ctrl lines output
   pinMode(RIGHT_AUDIO_RELAY, OUTPUT);
   pinMode(LEFT_AUDIO_RELAY, OUTPUT);
   pinMode(GROUND_AUDIO_RELAY, OUTPUT);
   pinMode(AMP_RELAY, OUTPUT);
   //Initialize state of relays to disabled
   disable_uno_audio_source();

   //Init serial coms
   Serial.begin(9600);
   Serial.println("Initial test of the Cruiser Code");

   // initialise the music player
   if (! musicPlayer.begin())
   {
     Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
     while (1); // don't do anything more
   }
   Serial.println(F("VS1053 found"));

   musicPlayer.sineTest(0x44, 500);    // Make a tone for 500ms to indicate VS1053 is working

   // initialise the SD Card
   if (!SD.begin(CARDCS))
   {
     Serial.println(F("SD failed, or not present"));
     while (1);  // don't do anything more
   }
   Serial.println("SD OK!");
   
   // list files
   printDirectory(SD.open("/"), 0);
   
   // Set volume for left, right channels. lower numbers == louder volume!  0 = loudest - 254(0xFE) = Silence
   musicPlayer.setVolume(20,20);

    if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT))
   Serial.println(F("DREQ pin is not an interrupt pin"));

 }

//------------------Main Loop-------------------------------------------------------
// This routine runs over and over again forever:
void loop()
 {
   // Read the current state of the the toggle switches
   GP02_SWITCH_STATE = musicPlayer.GPIO_digitalRead(GP02_SWITCH);


   // Store the current music state
   PlAY_STATE = musicPlayer.playingMusic;

   // If any of the toggle switch 1 transistion from low to high, play the file on SD Card named "track001.mp3"
   if (GP02_SWITCH_STATE == HIGH & GP02_SWITCH_LSTATE == LOW) play_file();

   if (GP02_SWITCH_STATE == LOW & GP02_SWITCH_LSTATE == HIGH) stop_audio();

   //If music stops from end of song or toggle switch disable the uno audio source(turn relays off)
   if (PlAY_STATE == false & PlAY_LSTATE == true) disable_uno_audio_source();

   // Set the last switch state equal to the current state
   GP02_SWITCH_LSTATE = GP02_SWITCH_STATE;

   // Store the last music state
   PlAY_LSTATE = musicPlayer.playingMusic;
 }

//--------------Play File Function------------------------------
//Start playing the file that is provided
void play_file()
 {
   enable_uno_audio_source();
   if (! musicPlayer.startPlayingFile("track001.mp3"))
     {
       Serial.println("Could not open file track001.mp3");
       disable_uno_audio_source();
      }
   Serial.println(F("Started playing"));  
 }

//--------------Stop Play Function------------------------------
//Stop playing the audio
void stop_audio()
 {
   musicPlayer.stopPlaying();
   Serial.println(F("Stop playing"));  
 }

//--------------Enable Uno Audio Function------------------------------
/* The following function sets the relay states so the audio produced by the Arduino
is sent to the Amp.  It also enable the amp (turn it on)*/
void enable_uno_audio_source()
 {
   digitalWrite(RIGHT_AUDIO_RELAY, HIGH);
   digitalWrite(LEFT_AUDIO_RELAY, HIGH);
   digitalWrite(GROUND_AUDIO_RELAY, HIGH);
   digitalWrite(AMP_RELAY, HIGH);
 }

//--------------Disable Uno Audio Function------------------------------
/* The following function sets the relay states so the auxiliary audio
is sent to the Amp.*/  
void disable_uno_audio_source()
 {
   digitalWrite(RIGHT_AUDIO_RELAY, LOW);
   digitalWrite(LEFT_AUDIO_RELAY, LOW);
   digitalWrite(GROUND_AUDIO_RELAY, LOW);
   digitalWrite(AMP_RELAY, LOW);
 }

//--------------Print Directory Function------------------------------
// File listing helper
void printDirectory(File dir, int numTabs) {
  while(true) {
   
    File entry =  dir.openNextFile();
    if (! entry) {
      // no more files
      //Serial.println("**nomorefiles**");
      break;
    }
    for (uint8_t i=0; i<numTabs; i++) {
      Serial.print('\t');
    }
    Serial.print(entry.name());
    if (entry.isDirectory()) {
      Serial.println("/");
      printDirectory(entry, numTabs+1);
    } else {
      // files have sizes, directories do not
      Serial.print("\t\t");
      Serial.println(entry.size(), DEC);
    }
    entry.close();
  }
}

CrossRoads

"Any thoughts?"
Yes, please use the code tags button, </>, next time.
Thanks - Moderator.
Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Mpstuart

"Any thoughts?"
Yes, please use the code tags button, </>, next time.
Thanks - Moderator.
Thanks.  This is my first rodeo in the world of coding.

patduino

It looks like you're approaching this the right way - are you sure you aren't a coder?

Just a few quick thoughts...

1. You have a number of printf statements in the code. What do you see on your serial output?

2.  You should also change this line: PlAY_LSTATE = musicPlayer.playingMusic   

to

 PlAY_LSTATE =  PlAY_STATE
There are 10 types of people in the world, those who understand binary, and those that don't.

Mpstuart

So, things have reached a plateau.  It is at a point right now where it will successfully  play track001.mp3 through headphones when switch 1 is triggered, but it is not set up yet to run correctly with the relays that make it switch over from the RCA input to input coming from the Arduino.  

I could use some help finishing this project.

The following is the code that I have at this point that has been written mostly by a friend.  The relays are not set up in the code to do what I want properly.  I don't think that he knew exactly how I had them set up.  I drew a picture of the way that I have them wired.

I have the 4 toggle switches wired to the GPIO terminals on the Adafruit shield.  This is what I want them to do - Switch one (gpio 2). - play track 001. Switch 2 (gpio4) - play track 002. Switch 3 (gpio5)- play random selection from a range of track 003- track 018. Switch 4 (gpio 6)- play track 019.

Eventually I might have switch 4 also be  a random selection of a range of songs that people have suggested to me as their best suggestion for a toggle switch song. But if that is figured out successfully for switch 3, that will be easy to copy.







Code: [Select]
// include SPI, MP3 and SD libraries
#include <SPI.h>
#include <Adafruit_VS1053.h>
#include <SD.h>

//Defining constants and varibles

//---------------UNO Digitial Pins---------------
// These are the UNO pins used for the music maker shield
const int SHIELD_RESET = -1;      // VS1053 reset pin (unused!)
const int SHIELD_CS = 7;      // VS1053 chip select pin (output)
const int SHIELD_DCS = 6;      // VS1053 Data/command select pin (output)

// These are common pins between UNO breakout and shield
const int CARDCS = 4;     // Card chip select pin
const int DREQ = 3;       // VS1053 Data request, ideally an Interrupt pin

//These are the pins on the UNO (through shield breakout) that will control the relay state
const int RIGHT_AUDIO_RELAY = 2;
const int LEFT_AUDIO_RELAY = 5;
const int GROUND_AUDIO_RELAY = 8;
const int AMP_RELAY = 9;

//-----------------------------------------------

//-------MP3 Shield Pins-------------------------
// These are the GIO pins on the MP3 Shield that will connect to the toggle switches
const int SWITCH01_Pin = 2;
const int SWITCH02_Pin = 4;
const int SWITCH03_Pin = 5;
const int SWITCH04_Pin = 6;
//-----------------------------------------------

//Initialise a varible to store the CURRENT state of a switch
int SWITCH01_STATE = LOW;
int SWITCH02_STATE = LOW;
int SWITCH03_STATE = LOW;
int SWITCH04_STATE = LOW;

//Initialise a varible to store the LAST state of a switch
int SWITCH01_LSTATE = LOW;
int SWITCH02_LSTATE = LOW;
int SWITCH03_LSTATE = LOW;
int SWITCH04_LSTATE = LOW;

//Initialise a varible to store the current and last state of a audio play
int PlAY_STATE = false;
int PlAY_LSTATE = false;


Adafruit_VS1053_FilePlayer musicPlayer =
  // create shield-example object!
  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);
  
//------------------Setup Routine-------------------------------------------------------
// the setup routine runs once when you press reset:
void setup()
  {
    // Configure toggle switch connections as Input
    musicPlayer.GPIO_pinMode(SWITCH01_Pin, INPUT);
    musicPlayer.GPIO_pinMode(SWITCH02_Pin, INPUT);
    musicPlayer.GPIO_pinMode(SWITCH03_Pin, INPUT);
    musicPlayer.GPIO_pinMode(SWITCH04_Pin, INPUT);


    // Configure relay ctrl lines output
    pinMode(RIGHT_AUDIO_RELAY, OUTPUT);
    pinMode(LEFT_AUDIO_RELAY, OUTPUT);
    pinMode(GROUND_AUDIO_RELAY, OUTPUT);
    pinMode(AMP_RELAY, OUTPUT);
    //Initialize state of relays to disabled
    disable_uno_audio_source();

    //Init serial coms
    Serial.begin(9600);
    Serial.println("Initial test of the Cruiser Code");

    // initialise the music player
    if (! musicPlayer.begin())
    {
      Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));
      while (1); // don't do anything more
    }
    Serial.println(F("VS1053 found"));

    musicPlayer.sineTest(0x44, 500);    // Make a tone for 500ms to indicate VS1053 is working

    // initialise the SD Card
    if (!SD.begin(CARDCS))
    {
      Serial.println(F("SD failed, or not present"));
      while (1);  // don't do anything more
    }
    Serial.println("SD OK!");
    
    // list files
    printDirectory(SD.open("/"), 0);
    
    // Set volume for left, right channels. lower numbers == louder volume!  0 = loudest - 254(0xFE) = Silence
    musicPlayer.setVolume(20,20);

     if (! musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT))
    Serial.println(F("DREQ pin is not an interrupt pin"));

  }

//------------------Main Loop-------------------------------------------------------
// This routine runs over and over again forever:
void loop()
  {
    // Read the current state of the the toggle switches
    SWITCH01_STATE = musicPlayer.GPIO_digitalRead(SWITCH01_Pin);
    SWITCH02_STATE = musicPlayer.GPIO_digitalRead(SWITCH02_Pin);
    SWITCH03_STATE = musicPlayer.GPIO_digitalRead(SWITCH03_Pin);
    SWITCH04_STATE = musicPlayer.GPIO_digitalRead(SWITCH04_Pin);


    // Store the current music state
    PlAY_STATE = musicPlayer.playingMusic;

    // If any of the toggle switch 1 transistion from low to high, play the file on SD Card named "track001.mp3"
    if (SWITCH01_STATE == HIGH & SWITCH01_LSTATE == LOW) play_file();

    //Matt if this sketch is still not working as is try commenting out the above line and uncomment out the
    //the following line.  If this works we may have an interupt issue.  It will also be interesting to see if you can get some info from serial monitor
    //if (SWITCH01_STATE == HIGH & SWITCH01_LSTATE == LOW) musicPlayer.playFullFile("track001.mp3");

    if (SWITCH01_STATE == LOW & SWITCH01_LSTATE == HIGH) stop_audio();

    //If music stops from end of song or toggle switch disable the uno audio source(turn relays off)
    if (PlAY_STATE == false & PlAY_LSTATE == true) disable_uno_audio_source();
 
    // Set the last switch state equal to the current state
    SWITCH01_LSTATE = SWITCH01_STATE;
    SWITCH02_LSTATE = SWITCH02_STATE;
    SWITCH03_LSTATE = SWITCH03_STATE;
    SWITCH04_LSTATE = SWITCH04_STATE;

    // Store the last music state
    PlAY_LSTATE = PlAY_STATE;

    //Wait 100ms then loop again
    delay(100);
  }

//--------------Play File Function------------------------------
//Start playing the file that is provided
void play_file()
  {
    enable_uno_audio_source();
    if (! musicPlayer.startPlayingFile("track001.mp3"))
      {
        Serial.println("Could not open file track001.mp3");
        disable_uno_audio_source();
       }
    Serial.println(F("Started playing"));  
  }

//--------------Stop Play Function------------------------------
//Stop playing the audio
void stop_audio()
  {
    musicPlayer.stopPlaying();
    Serial.println(F("Stop playing"));  
  }

//--------------Enable Uno Audio Function------------------------------
/* The following function sets the relay states so the audio produced by the Arduino
is sent to the Amp.  It also enable the amp (turn it on)*/
void enable_uno_audio_source()
  {
    digitalWrite(RIGHT_AUDIO_RELAY, HIGH);
    digitalWrite(LEFT_AUDIO_RELAY, HIGH);
    digitalWrite(GROUND_AUDIO_RELAY, HIGH);
    digitalWrite(AMP_RELAY, HIGH);
  }

//--------------Disable Uno Audio Function------------------------------
/* The following function sets the relay states so the auxiliary audio
is sent to the Amp.*/  
void disable_uno_audio_source()
  {
    digitalWrite(RIGHT_AUDIO_RELAY, LOW);
    digitalWrite(LEFT_AUDIO_RELAY, LOW);
    digitalWrite(GROUND_AUDIO_RELAY, LOW);
    digitalWrite(AMP_RELAY, LOW);
  }

//--------------Print Directory Function------------------------------
// File listing helper
void printDirectory(File dir, int numTabs) {
   while(true) {
    
     File entry =  dir.openNextFile();
     if (! entry) {
       // no more files
       //Serial.println("**nomorefiles**");
       break;
     }
     for (uint8_t i=0; i<numTabs; i++) {
       Serial.print('\t');
     }
     Serial.print(entry.name());
     if (entry.isDirectory()) {
       Serial.println("/");
       printDirectory(entry, numTabs+1);
     } else {
       // files have sizes, directories do not
       Serial.print("\t\t");
       Serial.println(entry.size(), DEC);
     }
     entry.close();
   }
}



Mpstuart

Another question I guess is how they will the toggle switches behave with each other? Will each toggle override the others? I would say, whatever is easiest to code. If switch 1 needs to be in low state before switch 2 would work, I am OK with that.


patduino

Hi Matt,

Just a few thoughts to start:

(1) unless you have pull-up or pull-down resistors wired into your circuitry, I recommend you use the internal pull-up resistors to keep the inputs from floating.  (explanation)

    musicPlayer.GPIO_pinMode(SWITCH01_Pin, INPUT_PULLUP);
    musicPlayer.GPIO_pinMode(SWITCH02_Pin, INPUT_PULLUP);
    musicPlayer.GPIO_pinMode(SWITCH03_Pin, INPUT_PULLUP);
    musicPlayer.GPIO_pinMode(SWITCH04_Pin, INPUT_PULLUP);
 
Note that this reverses your logic.  LOW means the button is PRESSED.

(2) It sounds like you are looking for rewritten code that works with your relays:

    LEFT_AUDIO_SIGNAL_RELAY
    LEFT_AUDIO_COMMON_RELAY
    RIGHT_AUDIO_SIGNAL_RELAY
    RIGHT_AUDIO_COMMON_RELAY

Can anyone comment on the audio wiring?
There are 10 types of people in the world, those who understand binary, and those that don't.


patduino

There are 10 types of people in the world, those who understand binary, and those that don't.

Go Up