Music Maker Code

Post here about your Arduino projects, get help - for Adafruit customers!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
User avatar
augydoggy
 
Posts: 64
Joined: Mon Jun 06, 2016 6:36 am

Music Maker Code

Post by augydoggy »

I'm using a Mega 2560 with a Music Maker and a Motor Shield to create sound and animation for a model railroad project. The sketch involves six "scenes" that all involve mp3 sound while four of them also drive DC motors. You guys have been a huge help to me in getting this going.

I've gotten the scenes with the sound and motors to work just fine and have been able to synchronize them easily. My problem is with the two scenes that have sound only. I cant get them to run the sound file. I've tried swapping sound files with others that do run but this makes no difference. I'm using an RTC and this has worked well with the scenes that have DC motors. I've tried using both the RTC commands and also just a delay() command for the sound only scenes but still can't get them to run. I'll attach the sketch below. Would you please take a look and see if there's something I'm doing wrong here?

- Tom

Code: Select all

// Model railroad animations sketch with RTC




// include SPI, MP3 and SD libraries

#include <SPI.h>

#include <Adafruit_VS1053.h>

#include <SD.h>

#include <Wire.h>

#include <Adafruit_MotorShield.h>

#include "utility/Adafruit_MS_PWMServoDriver.h"

#include "RTClib.h"




// define the pins used

//#define CLK 13       // SPI Clock, shared with SD card

//#define MISO 12      // Input data, from VS1053/SD card

//#define MOSI 11      // Output data, to VS1053/SD card

// Connect CLK, MISO and MOSI to hardware SPI pins.

// See http://arduino.cc/en/Reference/SPI "Connections"




// These are the pins used for the music maker shield

#define SHIELD_RESET  -1      // VS1053 reset pin (unused!)

#define SHIELD_CS     7      // VS1053 chip select pin (output)

#define SHIELD_DCS    6      // VS1053 Data/command select pin (output)




// These are common pins between breakout and shield

#define CARDCS 4     // Card chip select pin

// DREQ should be an Int pin, see http://arduino.cc/en/Reference/attachInterrupt

#define DREQ 3       // VS1053 Data request, ideally an Interrupt pin




Adafruit_VS1053_FilePlayer musicPlayer =

  // create shield-example object!

  Adafruit_VS1053_FilePlayer(SHIELD_RESET, SHIELD_CS, SHIELD_DCS, DREQ, CARDCS);




RTC_DS3231 rtc;

// These are the pins used for the RTC

#define SDA 20       // RTC I2C clock

#define SCL 21       // RTC I2C data



// Create the motor shield object with the default I2C address

Adafruit_MotorShield AFMS = Adafruit_MotorShield();




// Assign some motors.

Adafruit_DCMotor *sandChuteMotor = AFMS.getMotor(1);

Adafruit_DCMotor *coalChuteMotor = AFMS.getMotor(2);

Adafruit_DCMotor *coalBucketMotor = AFMS.getMotor(3);

Adafruit_DCMotor *waterSpoutMotor = AFMS.getMotor(4);



// interrupt for void coalBucket loop

int runXTimes = 0;



// interrupts for buttons assigned to pins

const int BUTTON_A = 21; // pin 21

const int BUTTON_B = 22; // pin 22

const int BUTTON_C = 23; // pin 23

const int BUTTON_D = 24; // pin 24

const int BUTTON_E = 25; // pin 25

const int BUTTON_F = 26; // pin 26



void setup() {

  // interrupts assigned to scenes
  
const int BUTTON_A = 21;  // ashpit

const int BUTTON_B = 22;  // sandhouse chute

const int BUTTON_C = 23;  // coaling tower chute

const int BUTTON_D = 24;  // coaling tower bucket

const int BUTTON_E = 25;  // coal pit

const int BUTTON_F = 26;  // water tank spout




 // initialize six inputs for use with pushbuttons. Normally HIGH, if pushed, goes to LOW.

  pinMode(BUTTON_A, INPUT_PULLUP);

  pinMode(BUTTON_B, INPUT_PULLUP);

  pinMode(BUTTON_C, INPUT_PULLUP);

  pinMode(BUTTON_D, INPUT_PULLUP);

  pinMode(BUTTON_E, INPUT_PULLUP);

  pinMode(BUTTON_F, INPUT_PULLUP);



  Serial.begin(9600);

  if (! musicPlayer.begin()) {
    
    // initialise the music player

     Serial.println(F("Couldn't find VS1053, do you have the right pins defined?"));

     while (1);   // Note that this loops forever if it can't find the musicPlayer.

  }
  
  SD.begin(CARDCS);  
  
  // initialise the SD card

  // Set volume for left, right channels. lower numbers == louder volume!

  musicPlayer.setVolume(40,40);




  // If DREQ is on an interrupt pin (on uno, #2 or #3) we can do background audio playing

  musicPlayer.useInterrupt(VS1053_FILEPLAYER_PIN_INT);  // DREQ int





  AFMS.begin();  // create with the default frequency (1.6KHz)

  // set motor speeds

  sandChuteMotor->setSpeed(100);

  coalChuteMotor->setSpeed(100);

  coalBucketMotor->setSpeed(100);

  waterSpoutMotor->setSpeed(100);

  
}

void loop() {

  // button conditions to initiate scenes
   
  if (digitalRead(BUTTON_A) == LOW) {

    ashPit();   // button A was pressed

  }

  if (digitalRead(BUTTON_B) == LOW) {

    sandChute();    // button B was pushed

  }


  if (digitalRead(BUTTON_C) == LOW) {

    coalChute();    // button C was pressed

  } 

  if (digitalRead(BUTTON_D) == LOW) {

    coalBucket();    // button D was pressed

  } 

  if (digitalRead(BUTTON_E) == LOW) {

    coalPit();      // button E was pressed

  } 

  if (digitalRead(BUTTON_F) == LOW) {

    waterSpout();    // button F was pressed

  } 


}



// scenes to be initiated by buttons

void ashPit() {
  // play sound of fire and coals
  // sound file to drive LEDs, simulate fire and coals
  // initialize RTC start time
  musicPlayer.startPlayingFile("Track001.mp3");
  delay(3000);  // pause 30 seconds
  musicPlayer.stopPlaying();  // stop playing sound file

  }




void sandChute() {
  // play sand blowing sounds to go with chute operation
  // run motor to animate sand chute
  // initialize RTC start time
  DateTime now = rtc.now();  // defines "rtc.now()"
  uint32_t startTime = rtc.now().unixtime();  // defines startTime as "now.unixtime()", the time you enter the function
  musicPlayer.startPlayingFile("track002.mp3");  // begin soundtrack
  while(rtc.now().unixtime() - startTime < 53);  // delay motor for 53 seconds   
  sandChuteMotor ->run(FORWARD);  // start motor in forward
  while(rtc.now().unixtime() - startTime < 58);  // chute lowers to sand dome 5 seconds
  sandChuteMotor ->run(RELEASE);  // stop motor
  while(rtc.now().unixtime() - startTime < 91);  // sand flows into dome 33 seconds
  sandChuteMotor ->run(BACKWARD);  // start motor in reverse
  while(rtc.now().unixtime() - startTime < 95);  // chute raises to stored position 4 seconds
  sandChuteMotor ->run(RELEASE);  // stop motor
  while(rtc.now().unixtime() - startTime < 104);  // allow 9 seconds for soundtrack to complete
  musicPlayer.stopPlaying();  // stop playing sound file since the animation is done

}




void coalChute() {
  // play sounds of coaling tower chute operation
  // run motor to animate coal chute. Use coalChuteMotor.
  // initialize RTC start time
  DateTime now = rtc.now();  //defines "mp3.now()"
  uint32_t startTime = rtc.now().unixtime();  // defines startTime as "now.unixtime()", the time you enter the function
  musicPlayer.startPlayingFile("track003.ogg");  // begin soundtrack
  while(rtc.now().unixtime() - startTime < 5);  // starts the motor 5 seconds after startTime
  coalChuteMotor ->run(FORWARD);  // start motor in forward
  while(rtc.now().unixtime() - startTime < 15);  // chute lowers for 10 seconds
  coalChuteMotor ->run(RELEASE);  // stop motor
  while(rtc.now().unixtime() - startTime < 60);  // coal drops into tender 45 seconds
  coalChuteMotor ->run(BACKWARD);  // start motor in reverse
  while(rtc.now().unixtime() - startTime < 70);  // chute raises to stored position 10 seconds
  coalChuteMotor ->run(RELEASE);  // stop motor
  while(rtc.now().unixtime() - startTime < 76);  // allow 6 seconds for soundtrack to complete
  musicPlayer.stopPlaying();  // stop playing sound file since the animation is done

  }




void coalBucket() {
  // play sounds of coaling tower bucket operation
  // run motor to animate coal bucket.
  // initialize RTC start time
  DateTime now = rtc.now();  // defines "rtc.now()"
  uint32_t startTime = rtc.now().unixtime();  // defines startTime as "now.unixtime()", the time you enter the function
  musicPlayer.startPlayingFile("track004.mp3");  // begin soundtrack
  while(rtc.now().unixtime() - startTime < 25);  // pause 25 seconds after startTime for sound of engine starting
  for (; runXTimes < 5; runXTimes++) {  // begin bucket filling loop, repeat 5 times
  uint32_t loopStartTime = rtc.now().unixtime();  // defines loopStartTime in unixtime()
  while(rtc.now().unixtime() - loopStartTime < 14);  // pause while bucket fills, 14 seconds
  coalBucketMotor ->run(FORWARD);  // start motor in forward
  while(rtc.now().unixtime() - loopStartTime < 39);  // bucket raises to top of tower, 25 seconds
  coalBucketMotor ->run(RELEASE);  // stop motor
  while(rtc.now().unixtime() - loopStartTime < 48);  // pause while bucket dumps, 9 seconds
  coalBucketMotor ->run(BACKWARD);  // start motor in backward
  while(rtc.now().unixtime() - loopStartTime < 70);  // bucket is lowered into pit, 22 seconds
  coalBucketMotor ->run(RELEASE);}  // stop motor, end of filling loop after 8 repetitions
  while(rtc.now().unixtime() - startTime < 402);  // allow 26 seconds for sound of engine stopping
  musicPlayer.stopPlaying();  // stop playing sound file since the animation is done

  } 




void coalPit() {
  // play sounds of coal pit filling operation
  // initialize RTC start time
  DateTime now = rtc.now();  // defines "rtc.now()"
  uint32_t startTime = rtc.now().unixtime();  // defines startTime as "now.unixtime()", the time you enter the function
  musicPlayer.startPlayingFile("track005.mp3");  // begin sounds of coal pit operation
  while(rtc.now().unixtime() - startTime < 35);  // allow 35 seconds for soundtrack
  musicPlayer.stopPlaying();  // stop playing sound file since the animation is done

}



void waterSpout() {
  // play sounds of water tank chute operation
  // run motor to animate water tank spout
  // initialize RTC start time
  DateTime now = rtc.now();  // defines "rtc.now()"
  uint32_t startTime = rtc.now().unixtime();  // defines startTime as "now.unixtime()", the time you enter the function
  musicPlayer.startPlayingFile("track006.mp3");  // play sounds of filling water in tender
  while(rtc.now().unixtime() - startTime < 4);  // starts the motor 4 seconds after startTime
  waterSpoutMotor ->run(FORWARD);  // start motor in forward
  while(rtc.now().unixtime() - startTime < 14);  // spout lowers for 10 seconds
  waterSpoutMotor ->run(RELEASE);  // stop motor
  while(rtc.now().unixtime() - startTime < 126);  // sound of water flowing for 112 seconds
  waterSpoutMotor ->run(BACKWARD);  // start motor in reverse
  while(rtc.now().unixtime() - startTime < 136);  // spout raises to stored position, 10 seconds
  waterSpoutMotor ->run(RELEASE);  // stop motor
  while(rtc.now().unixtime() - startTime < 144);  // allow 8 seconds for sound track to complete
  musicPlayer.stopPlaying();  // stop playing sound file

  }   




// this scene to be added later
// need to assign button and pin in void setup
// need to modify with servo commands
// need to add servo code in voidsetup
// need to assign sound track #
void sandFurnace() {
  // door opens, sound fades in, plays for 15 seconds, sound fades out, door closes
  // sounds associated with sand drying process.
  // furnace and shoveling sounds to go with door servo operation
  // initialize RTC start time
  DateTime now = rtc.now();  // defines "rtc.now()"
  uint32_t startTime = rtc.now().unixtime();  // defines startTime as "now.unixtime()", the time you enter the function
  musicPlayer.startPlayingFile("track00?.ogg");  // begin soundtrack
  while(rtc.now().unixtime() - startTime < 15);  // allow 15 seconds for soundtrack to complete
  musicPlayer.stopPlaying();  // stop playing sound file since the animation is done

}

User avatar
augydoggy
 
Posts: 64
Joined: Mon Jun 06, 2016 6:36 am

Re: Music Maker Code

Post by augydoggy »

I forgot to mention....the two scenes that don't run are void ashPit and void coalPit.

User avatar
adafruit_support_mike
 
Posts: 67485
Joined: Thu Feb 11, 2010 2:51 pm

Re: Music Maker Code

Post by adafruit_support_mike »

I don't see anything obviously out of place in the code.. the ashPit() function has a capital 'T' in the filename, so make sure that matches the filename on the SD card.

You can try adding some Serial.print() statements to make sure the timing of the functions works the way it should. Also try checking the return value from .startPlayingFile() to make sure that isn't reporting an error.

Locked
Please be positive and constructive with your questions and comments.

Return to “Arduino”