Big Mouth Billy Bass and Motor Shield

For other supported Arduino products from Adafruit: Shields, accessories, etc.

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
cjb41183
 
Posts: 18
Joined: Sun Mar 03, 2013 12:25 pm

Re: Big Mouth Billy Bass and Motor Shield

Post by cjb41183 »

adafruit_support wrote:
Measure the voltage on the body motor when the motor is supposed to be running.
I measured the voltage of all the motors in the working motor test sketch and it hits about 5.5 volts or right around there. So I ran it with the wave shield sketch and it didn't even register any voltage. I knew there had to be something because I could hear a high pitched noise like the motor was trying to run. So I turned down the volt meter to 2000mV. I tested each motor and they all hit around .008V! So it is getting no juice for some reason.

Is it possible that there are still pin conflicts? Everything works independently, but now that I am trying to make them work together, maybe the pin conflict issues are manifesting themselves? The only thing about that is I ran a test sketch in which I just combined the example sketches for the wave shield and the Motor Party and was able to get everything working at the same time. The motors would operate while it played a sound. Maybe I will try that again just to see what happens. Any other suggestions?

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: Big Mouth Billy Bass and Motor Shield

Post by adafruit_support_bill »

The only thing about that is I ran a test sketch in which I just combined the example sketches for the wave shield and the Motor Party and was able to get everything working at the same time.
That would seem to indicate that there are no pin conflicts. Try that one again and post the code if it works. One possibility is that some pin(s) are not being set to the correct mode (INPUT vs. OUTPUT). A likely suspect would be pin2.

cjb41183
 
Posts: 18
Joined: Sun Mar 03, 2013 12:25 pm

Re: Big Mouth Billy Bass and Motor Shield

Post by cjb41183 »

Well I tried to mimic what I did before and it didn't work. Same thing with no voltage on the motors. And of course I didn't save the sketch from that previous test (what was I thinking?).

In other research, however, it seems as if trying to use the wave shield and the motor shield libraries together can cause a timer conflict. I have no idea what a timer conflict is, but do you think that is what is happening here and is there any way to rectify it?

cjb41183
 
Posts: 18
Joined: Sun Mar 03, 2013 12:25 pm

Re: Big Mouth Billy Bass and Motor Shield

Post by cjb41183 »

Well, here is the daphc code that comes with the wave shield with the motor test that worked integrated into it. Both the audio and the movement work in this sketch...but not simultaneously. I'm afraid I don't know how to do that yet! It plays every file on the SD card and then runs each motor. But this is at least better than my last sketch where it wouldn't even run the motor.

Code: Select all

/*
 * This example plays every .WAV file it finds on the SD card in a loop
 */
#include <WaveHC.h>
#include <WaveUtil.h>
#include <AFMotor.h>

SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the volumes root directory
WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

uint8_t dirLevel; // indent level for file/dir names    (for prettyprinting)
dir_t dirBuf;     // buffer for directory reads


/*
 * Define macro to put error messages in flash memory
 */
#define error(msg) error_P(PSTR(msg))

  AF_DCMotor mouth(2, MOTOR12_64KHZ);
  AF_DCMotor body(3, MOTOR34_64KHZ);
  AF_DCMotor tail(4, MOTOR34_64KHZ);

// Function definitions (we define them here, but the code is below)
void play(FatReader &dir);

//////////////////////////////////// SETUP
void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps for debugging
  
  putstring_nl("\nWave test!");  // say we woke up!
  
  putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
  Serial.println(FreeRam());

  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
  if (!card.init()) {         //play with 8 MHz spi (default faster!)  
    error("Card init. failed!");  // Something went wrong, lets print out why
  }
  
  // enable optimize read - some cards may timeout. Disable if you're having problems
  card.partialBlockRead(true);
  
  // Now we will look for a FAT partition!
  uint8_t part;
  for (part = 0; part < 5; part++) {   // we have up to 5 slots to look in
    if (vol.init(card, part)) 
      break;                           // we found one, lets bail
  }
  if (part == 5) {                     // if we ended up not finding one  :(
    error("No valid FAT partition!");  // Something went wrong, lets print out why
  }
  
  // Lets tell the user about what we found
  putstring("Using partition ");
  Serial.print(part, DEC);
  putstring(", type is FAT");
  Serial.println(vol.fatType(), DEC);     // FAT16 or FAT32?
  
  // Try to open the root directory
  if (!root.openRoot(vol)) {
    error("Can't open root dir!");      // Something went wrong,
  }
  
  // Whew! We got past the tough parts.
  putstring_nl("Files found (* = fragmented):");

  // Print out all of the files in all the directories.
  root.ls(LS_R | LS_FLAG_FRAGMENTED);
  
  mouth.setSpeed(255);
  body.setSpeed(255);
  tail.setSpeed(255);
  
  BANNED(RELEASE);
  body.run(RELEASE);
  tail.run(RELEASE);
}

//////////////////////////////////// LOOP
void loop() {
  root.rewind();
  play(root);
  
  Serial.println("Moving mouth");
  
  BANNED(FORWARD);
  delay(10);
  BANNED(RELEASE);
  delay(10);
  BANNED(FORWARD);
  delay(2000);
  BANNED(RELEASE);
  
  Serial.println("Moving tail");
  
  tail.run(FORWARD);
  delay(10);
  tail.run(RELEASE);
  delay(10);
  tail.run(FORWARD);
  delay(2000);
  tail.run(RELEASE);
  
  Serial.println("Moving body");
  
  body.run(FORWARD);
  delay(10);
  body.run(RELEASE);
  delay(10);
  body.run(FORWARD);
  delay(2000);
  body.run(RELEASE);
  
 
  Serial.println("All's quiet on the western front...");
  
}

/////////////////////////////////// HELPERS
/*
 * print error message and halt
 */
void error_P(const char *str) {
  PgmPrint("Error: ");
  SerialPrint_P(str);
  sdErrorCheck();
  while(1);
}
/*
 * print error message and halt if SD I/O error, great for debugging!
 */
void sdErrorCheck(void) {
  if (!card.errorCode()) return;
  PgmPrint("\r\nSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  PgmPrint(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}
/*
 * play recursively - possible stack overflow if subdirectories too nested
 */
void play(FatReader &dir) {
  FatReader file;
  while (dir.readDir(dirBuf) > 0) {    // Read every file in the directory one at a time
  
    // Skip it if not a subdirectory and not a .WAV file
    if (!DIR_IS_SUBDIR(dirBuf)
         && strncmp_P((char *)&dirBuf.name[8], PSTR("WAV"), 3)) {
      continue;
    }

    Serial.println();            // clear out a new line
    
    for (uint8_t i = 0; i < dirLevel; i++) {
       Serial.write(' ');       // this is for prettyprinting, put spaces in front
    }
    if (!file.open(vol, dirBuf)) {        // open the file in the directory
      error("file.open failed");          // something went wrong
    }
    
    if (file.isDir()) {                   // check if we opened a new directory
      putstring("Subdir: ");
      printEntryName(dirBuf);
      Serial.println();
      dirLevel += 2;                      // add more spaces
      // play files in subdirectory
      play(file);                         // recursive!
      dirLevel -= 2;    
    }
    else {
      // Aha! we found a file that isnt a directory
      putstring("Playing ");
      printEntryName(dirBuf);              // print it out
      if (!wave.create(file)) {            // Figure out, is it a WAV proper?
        putstring(" Not a valid WAV");     // ok skip it
      } else {
        Serial.println();                  // Hooray it IS a WAV proper!
        wave.play();                       // make some noise!
        
        uint8_t n = 0;
        while (wave.isplaying) {// playing occurs in interrupts, so we print dots in realtime
          putstring(".");
          if (!(++n % 32))Serial.println();
          delay(100);
        }       
        sdErrorCheck();                    // everything OK?
        // if (wave.errors)Serial.println(wave.errors);     // wave decoding errors
      }
    }
  }
}

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: Big Mouth Billy Bass and Motor Shield

Post by adafruit_support_bill »

In other research, however, it seems as if trying to use the wave shield and the motor shield libraries together can cause a timer conflict.
There is a timer conflict with the wave shield and the servo library. But you aren't using the servos, so I don't think that is it.
Both the audio and the movement work in this sketch...but not simultaneously.
What happens if you leave a motor running while you start the sound playback, as in:

Code: Select all

void loop()
 {
  BANNED(FORWARD);
  delay(1000);  // run for a second before starting playback
  Serial.println("Moving mouth");

  root.rewind();
  play(root);
  
  BANNED(RELEASE);  // stop when done

cjb41183
 
Posts: 18
Joined: Sun Mar 03, 2013 12:25 pm

Re: Big Mouth Billy Bass and Motor Shield

Post by cjb41183 »

Ok, so that works. So maybe there is something wrong with that other code. I will work off of this code and work in the button to start it. Also I need to sync up the movements of the mouth with the words. But at least I have something to start with.

cjb41183
 
Posts: 18
Joined: Sun Mar 03, 2013 12:25 pm

Re: Big Mouth Billy Bass and Motor Shield

Post by cjb41183 »

Next problem...for the life of me, as I am trying to write my own code, I cannot get the wave shield to open a file on my SD card. When I run my sketch it does all of the movements that I have programmed but does not play a sound. The serial monitor says "couldn't open file ..." and then names each file as it comes up. Now, since I am a n00b with this whole coding thing, I have borrowed heavily from other sketches. Just can't figure this one out.

Here is my code:

Code: Select all

/*
*This sketch plays a random sound file at the push of a button and syncs up the motors with the sounds.
*/

//include the appropriate libraries
#include <WaveHC.h>
#include <WaveUtil.h>
#include <AFMotor.h>
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>


//not sure if I need these, but they are in the example sketch...
SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the volumes root directory
FatReader f;      // This holds the information for the file we're going to play
WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

uint8_t dirLevel; // indent level for file/dir names    (for prettyprinting)
dir_t dirBuf;     // buffer for directory reads

#define DEBOUNCE 100 //button debouncer

//define motors and names
  AF_DCMotor mouth(2, MOTOR12_64KHZ);
  AF_DCMotor body(3, MOTOR34_64KHZ);
  AF_DCMotor tail(4, MOTOR34_64KHZ);

//don't know if I need this...
void play(FatReader &dir);


//setup
void setup()
  {
     Serial.begin(9600);
   
   mouth.setSpeed(255);
   body.setSpeed(255);
   tail.setSpeed(255);
  
   BANNED(RELEASE);
   body.run(RELEASE);
   tail.run(RELEASE);
   
    // Set the output pins for the DAC control. This pins are defined in the library
   pinMode(17, OUTPUT);
   pinMode(16, OUTPUT);
   pinMode(15, OUTPUT);
   pinMode(14, OUTPUT);

   
   //denable pull-up resistors on switch pins (analog)
   digitalWrite(18, HIGH);
    
  
  }
  
//loop

void loop()
  {
  switch (check_switches()) //see if the button is pressed
    {
      case 5:                //if it is pressed
      playSound();      //play a random Pauliism and move motors
      break;
    }
  }
  
  //check switch function coding
 byte check_switches()
{
  static byte previous[6];
  static long time[6];
  byte reading;
  byte pressed;
  byte index;
  pressed = 0;

  for (byte index = 0; index < 6; ++index) {
    reading = digitalRead(14 + index);
    if (reading == LOW && previous[index] == HIGH && millis() - time[index] > DEBOUNCE)
    {
      // switch pressed
      time[index] = millis();
      pressed = index + 1;
      break;
    }
    previous[index] = reading;
  }
  // return switch number (1 - 6)
  return (pressed);
}

//code for playSound function
void playSound()
{
  int Sound = random(1, 4);
    //pick a random sound and move the motors to match
    switch (Sound)
    {
      
      case 1:
      playcomplete("12.WAV");
      body.run(FORWARD);
      BANNED(FORWARD);
      delay(1000);
      body.run(RELEASE);
      BANNED(RELEASE);
      break;
    
    
      case 2:
      playcomplete("17.WAV");
      BANNED(FORWARD);
      delay(1000);
      BANNED(RELEASE);
      break;
      
      case 3:
      playcomplete("5.WAV");
      BANNED(FORWARD);
      delay(1000);
      BANNED(RELEASE);
      break;
    }
}


// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
  while (wave.isplaying) {
  // do nothing while its playing
  }
  // now its done playing
}

void playfile(char *name) {
  // see if the wave object is currently doing something
  if (wave.isplaying) {// already playing something, so stop it!
    wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file "); Serial.print(name); return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); return;
  }
  
  // ok time to play! start playback
  wave.play();
    
}


Now, here is code that works for the audio only. Can't get the motors to run on this one for some reason. I just modified the 6 button example sketch and got it to work for the audio. The different between this code and my code is that I am trying to randomize the files that are played (I have the library for True Random but have yet to integrate it). So here is the working code for audio:

Code: Select all

#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.h"
#include <AFMotor.h>

  AF_DCMotor mouth(2, MOTOR12_64KHZ);
  AF_DCMotor body(3, MOTOR34_64KHZ);
  AF_DCMotor tail(4, MOTOR34_64KHZ);

SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the filesystem on the card
FatReader f;      // This holds the information for the file we're play

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

#define DEBOUNCE 100  // button debouncer

// this handy function will return the number of bytes currently free in RAM, great for debugging!   
int freeRam(void)
{
  extern int  __bss_end; 
  extern int  *__brkval; 
  int free_memory; 
  if((int)__brkval == 0) {
    free_memory = ((int)&free_memory) - ((int)&__bss_end); 
  }
  else {
    free_memory = ((int)&free_memory) - ((int)__brkval); 
  }
  return free_memory; 
} 

void sdErrorCheck(void)
{
  if (!card.errorCode()) return;
  putstring("\n\rSD I/O error: ");
  Serial.print(card.errorCode(), HEX);
  putstring(", ");
  Serial.println(card.errorData(), HEX);
  while(1);
}

void setup() {
  // set up serial port
  Serial.begin(9600);
  putstring_nl("WaveHC with 6 buttons");
  
   putstring("Free RAM: ");       // This can help with debugging, running out of RAM is bad
  Serial.println(freeRam());      // if this is under 150 bytes it may spell trouble!
  
  // Set the output pins for the DAC control. This pins are defined in the library
  pinMode(17, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(15, OUTPUT);
  pinMode(14, OUTPUT);

 
  // enable pull-up resistors on switch pins (analog inputs)
    digitalWrite(18, HIGH);
  
 
  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
  if (!card.init()) {         //play with 8 MHz spi (default faster!)  
    putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
    sdErrorCheck();
    while(1);                            // then 'halt' - do nothing!
  

    mouth.setSpeed(255);
    body.setSpeed(255);
    tail.setSpeed(255);
  
    BANNED(RELEASE);
    body.run(RELEASE);
    tail.run(RELEASE);

}
  
  // enable optimize read - some cards may timeout. Disable if you're having problems
  card.partialBlockRead(true);
 
// Now we will look for a FAT partition!
  uint8_t part;
  for (part = 0; part < 5; part++) {     // we have up to 5 slots to look in
    if (vol.init(card, part)) 
      break;                             // we found one, lets bail
  }
  if (part == 5) {                       // if we ended up not finding one  :(
    putstring_nl("No valid FAT partition!");
    sdErrorCheck();      // Something went wrong, lets print out why
    while(1);                            // then 'halt' - do nothing!
  }
  
  // Lets tell the user about what we found
  putstring("Using partition ");
  Serial.print(part, DEC);
  putstring(", type is FAT");
  Serial.println(vol.fatType(),DEC);     // FAT16 or FAT32?
  
  // Try to open the root directory
  if (!root.openRoot(vol)) {
    putstring_nl("Can't open root dir!"); // Something went wrong,
    while(1);                             // then 'halt' - do nothing!
  }
  
  // Whew! We got past the tough parts.
  putstring_nl("Ready!");
}

void loop() {
  //putstring(".");            // uncomment this to see if the loop isnt running
  switch (check_switches()) {
        case 5:
        BANNED(FORWARD);
        body.run(FORWARD);
        delay(1000);
        BANNED(RELEASE);
        body.run(RELEASE);
        playcomplete("12.WAV");
        
        break;
    
  }
}

byte check_switches()
{
  static byte previous[6];
  static long time[6];
  byte reading;
  byte pressed;
  byte index;
  pressed = 0;

  for (byte index = 0; index < 6; ++index) {
    reading = digitalRead(14 + index);
    if (reading == LOW && previous[index] == HIGH && millis() - time[index] > DEBOUNCE)
    {
      // switch pressed
      time[index] = millis();
      pressed = index + 1;
      break;
    }
    previous[index] = reading;
  }
  // return switch number (1 - 6)
  return (pressed);
}


// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
  while (wave.isplaying) {
  // do nothing while its playing
  }
  // now its done playing
}

void playfile(char *name) {
  // see if the wave object is currently doing something
  if (wave.isplaying) {// already playing something, so stop it!
    wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file "); Serial.print(name); return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); return;
  }
  
  // ok time to play! start playback
  wave.play();
 
  
  
}

Can you see any obvious reasons why my code is not working? Thank you!

cjb41183
 
Posts: 18
Joined: Sun Mar 03, 2013 12:25 pm

Re: Big Mouth Billy Bass and Motor Shield

Post by cjb41183 »

I answered my own question. I never included the code to initialize the SD card, etc. I looked at ladyada's walk through of the 6 button sketch and she says what is optional and what is not optional. I omitted most of that stuff because I was trying to save room in the sketch as I am going to hit the wall really quickly, I think.

But it is all working well, randomizing, motors are working and audio is working...except for one thing...

How do I get the motors to sync up with the audio? I need to code the motors to run while the audio file plays. As I have it now, either the audio file plays and then the motor runs or the motor runs and then the audio file plays. I suspect it has something to do with my use of the delay function. What other option do I have for timing the motor movements?

Thank you for all of your help!

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: Big Mouth Billy Bass and Motor Shield

Post by adafruit_support_bill »

I suspect it has something to do with my use of the delay function. What other option do I have for timing the motor movements?
Yup. Delays are a quick and easy solution when you are trying to get one thing to work. But they are fundamentally incompatible with getting more than one thing to run concurrently.

If you record the time when a motor starts, you can compare that to the current time while playing the wave so you know when to turn it off. For example:

Code: Select all

    bodyStartTime = millis();  // remember when the motor started
    bodyMotor.run(FORWARD);
And then later in your loop:

Code: Select all

    if((millis() - bodyStartTime) > bodyRunTime)  // has it run long enough?
    {
        bodyMotor.run(RELEASE);
    }

cjb41183
 
Posts: 18
Joined: Sun Mar 03, 2013 12:25 pm

Re: Big Mouth Billy Bass and Motor Shield

Post by cjb41183 »

Well the millis function was a bit daunting for me, so I found a way to use the delay function to work for me. I now have a working hacked Big Mouth Billy Bass and I am so excited! There was a statement from the playcomplete function that said "while(wave.isplaying){}" which meant don't do anything while the wave file is playing. That was why I couldn't get the motors and the file to work at the same time. I commented out that line and voila! I also used the "TrueRandom" library which I found online. It requires pin 0 to be free, so I moved my LAT pin on the wave shield to pin 5 and adjusted the library as necessary. It works really well and I never get the same sequence twice.

So all that is left is to finish coding the movements (I will ultimately have around 240 sounds...let's see if the Uno's memory holds up! If not, I will go until it can't hold any more!

Thank you SO MUCH for all of your help! I am posting the code that is working for me in case anyone else wants to try and do their own hacked Big Mouth Billy Bass.

I guess I've graduated form this forum...until the next project!

Code: Select all

/*
*This sketch plays a random sound file at the push of a button and syncs up the motors with the sounds.
*/

//include the appropriate libraries
#include "WaveHC.h"
#include "WaveUtil.h"
#include <AFMotor.h>
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include <TrueRandom.h>


//not sure if I need these, but they are in the example sketch...
SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the volumes root directory
FatReader f;      // This holds the information for the file we're going to play
WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

uint8_t dirLevel; // indent level for file/dir names    (for prettyprinting)
dir_t dirBuf;     // buffer for directory reads

#define DEBOUNCE 100 //button debouncer

//define motors and names
  AF_DCMotor mouth(2, MOTOR12_64KHZ);
  AF_DCMotor body(3, MOTOR34_64KHZ);
  AF_DCMotor tail(4, MOTOR34_64KHZ);

//don't know if I need this...
void play(FatReader &dir);


//setup
void setup()
  {
     Serial.begin(9600);
   
   mouth.setSpeed(255);
   body.setSpeed(255);
   tail.setSpeed(255);
  
   BANNED(RELEASE);
   body.run(RELEASE);
   tail.run(RELEASE);
   
    // Set the output pins for the DAC control. This pins are defined in the library
   pinMode(17, OUTPUT);
   pinMode(16, OUTPUT);
   pinMode(15, OUTPUT);
   pinMode(19, OUTPUT);

   
   //enable pull-up resistors on switch pins (analog)
   digitalWrite(18, HIGH);
    
  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
    if (!card.init())
    {         //play with 8 MHz spi (default faster!)  
        putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
        while(1);                            // then 'halt' - do nothing!
    }
    
   // Now we will look for a FAT partition!
    uint8_t part;
      for (part = 0; part < 5; part++){     // we have up to 5 slots to look in
      if (vol.init(card, part)) 
      break;                             // we found one, lets bail
      }
      if (part == 5) {                       // if we ended up not finding one  :(
      putstring_nl("No valid FAT partition!");
      while(1);                            // then 'halt' - do nothing!
      }
    
   // Try to open the root directory
    if (!root.openRoot(vol)) {
    putstring_nl("Can't open root dir!"); // Something went wrong,
    while(1);                             // then 'halt' - do nothing!
    }
    
    
 }
  
//loop

void loop()
  {
  switch (check_switches()) //see if the button is pressed
    {
      case 5:                //if it is pressed
      playSound();      //play a random sound and move motors
      break;
    }
  }
  
  
  
  
  
  //check switch function coding
 byte check_switches()
{
  static byte previous[6];
  static long time[6];
  byte reading;
  byte pressed;
  byte index;
  pressed = 0;

  for (byte index = 0; index < 6; ++index) {
    reading = digitalRead(14 + index);
    if (reading == LOW && previous[index] == HIGH && millis() - time[index] > DEBOUNCE)
    {
      // switch pressed
      time[index] = millis();
      pressed = index + 1;
      break;
    }
    previous[index] = reading;
  }
  // return switch number (1 - 6)
  return (pressed);
}

//code for playSound function
void playSound()
{
  int Sound = TrueRandom.random(0,41);
    //pick a random sound and move the motors to match
    switch (Sound)
    {
      
      case 1:
      body.run(FORWARD);        //move the body of the BMBB
      playcomplete("1.WAV");    //play the sound
      delay(700);               //wait for the sound to start
      speak(100,100,100,100,100,100,300,200,0,0);  //call the speak function which controls the mouth movements...change these values to change the mouth movement
      delay(1000);              //this keeps the body pointed outward
      body.run(RELEASE);        //body to resting position
      break;
      
      case 2:
      body.run(FORWARD);
      playcomplete("2.WAV");
      delay(700);
      speak(600,0,0,0,0,0,0,0,0,0);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    
      case 3:
      body.run(FORWARD);
      playcomplete("3.WAV");
      delay(600);
      speak(200,100,100,100,200,0,0,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 4:
      body.run(FORWARD);
      playcomplete("4.WAV");
      delay(700);
      speak(100,100,100,100,100,100,300,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      tail.run(RELEASE);
      break; 
    
      case 5:
      body.run(FORWARD);
      playcomplete("5.WAV");
      delay (200);
      speak(300,200,100,0,0,0,0,0,0,0);
      tailwag(200,200,200,200,200,200,200,200);
      delay(800);
      body.run(RELEASE);
      break;
      
      case 6:
      body.run(FORWARD);
      playcomplete("6.WAV");
      delay(600);
      speak(100,100,100,100,100,100,300,200,0,0);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      break;
      
      case 7:
      body.run(FORWARD);
      playcomplete("7.WAV");
      delay(600);
      speak(100,0,100,100,300,0,0,0,0,0);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    
      case 8:
      body.run(FORWARD);
      playcomplete("8.WAV");
      delay(700);
      speak(200,100,100,100,300,200,0,0,0,0);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      break;
      
      case 9:
      body.run(FORWARD);
      playcomplete("9.WAV");
      delay(600);
      speak2(100,100,100,100,100,100,100,100,100,100,400,100,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      tail.run(RELEASE);
      break; 
    
      case 10:
      body.run(FORWARD);
      playcomplete("10.WAV");
      delay(800);
      speak(50,100,100,100,100,100,100,100,200,200);
      delay(800);
      body.run(RELEASE);
      break;
      
      case 11:
      body.run(FORWARD);
      playcomplete("11.WAV");
      delay(700);
      speak(100,100,100,100,100,100,200,200,100,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 12:
      body.run(FORWARD);
      playcomplete("12.WAV");
      delay(700);
      speak(600,0,0,0,0,0,0,0,0,0);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    
      case 13:
      body.run(FORWARD);
      playcomplete("13.WAV");
      delay(600);
      speak(200,100,100,100,200,0,0,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 14:
      body.run(FORWARD);
      playcomplete("14.WAV");
      delay(700);
      speak(100,100,100,100,100,100,300,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      tail.run(RELEASE);
      break; 
    
      case 15:
      body.run(FORWARD);
      playcomplete("15.WAV");
      delay (800);
      speak(50,100,1000,100,0,0,0,0,0,0);
      body.run(RELEASE);
      break;
      
      case 16:
      body.run(FORWARD);
      playcomplete("16.WAV");
      delay(700);
      speak(100,100,100,100,100,100,300,200,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 17:
      body.run(FORWARD);
      playcomplete("17.WAV");
      delay(700);
      speak(600,0,0,0,0,0,0,0,0,0);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    
      case 18:
      body.run(FORWARD);
      playcomplete("18.WAV");
      delay(600);
      speak(200,100,100,100,200,0,0,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 19:
      body.run(FORWARD);
      playcomplete("19.WAV");
      delay(700);
      speak(100,100,100,100,100,100,300,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      tail.run(RELEASE);
      break; 
    
      case 20:
      body.run(FORWARD);
      playcomplete("20.WAV");
      delay (800);
      speak(50,100,1000,100,0,0,0,0,0,0);
      body.run(RELEASE);
      break; 
      
      case 21:
      body.run(FORWARD);
      playcomplete("21.WAV");
      delay(700);
      speak(100,100,100,100,100,100,300,200,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 22:
      body.run(FORWARD);
      playcomplete("22.WAV");
      delay(700);
      speak(600,0,0,0,0,0,0,0,0,0);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    
      case 23:
      body.run(FORWARD);
      playcomplete("23.WAV");
      delay(600);
      speak(200,100,100,100,200,0,0,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 24:
      body.run(FORWARD);
      playcomplete("24.WAV");
      delay(700);
      speak(100,100,100,100,100,100,300,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      tail.run(RELEASE);
      break; 
    
      case 25:
      body.run(FORWARD);
      playcomplete("25.WAV");
      delay (800);
      speak(50,100,1000,100,0,0,0,0,0,0);
      body.run(RELEASE);
      break;
      
      case 26:
      body.run(FORWARD);
      playcomplete("26.WAV");
      delay(700);
      speak(100,100,100,100,100,100,300,200,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 27:
      body.run(FORWARD);
      playcomplete("27.WAV");
      delay(700);
      speak(600,0,0,0,0,0,0,0,0,0);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    
      case 28:
      body.run(FORWARD);
      playcomplete("28.WAV");
      delay(600);
      speak(200,100,100,100,200,0,0,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 29:
      body.run(FORWARD);
      playcomplete("29.WAV");
      delay(700);
      speak(100,100,100,100,100,100,300,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      tail.run(RELEASE);
      break; 
    
      case 30:
      body.run(FORWARD);
      playcomplete("30.WAV");
      delay (800);
      speak(50,100,1000,100,0,0,0,0,0,0);
      body.run(RELEASE);
      break;
      
      case 31:
      body.run(FORWARD);
      playcomplete("31.WAV");
      delay(700);
      speak(100,100,100,100,100,100,300,200,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 32:
      body.run(FORWARD);
      playcomplete("32.WAV");
      delay(700);
      speak(600,0,0,0,0,0,0,0,0,0);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    
      case 33:
      body.run(FORWARD);
      playcomplete("33.WAV");
      delay(600);
      speak(200,100,100,100,200,0,0,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 34:
      body.run(FORWARD);
      playcomplete("14.WAV");
      delay(700);
      speak(100,100,100,100,100,100,300,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      tail.run(RELEASE);
      break; 
    
      case 35:
      body.run(FORWARD);
      playcomplete("35.WAV");
      delay (800);
      speak(50,100,1000,100,0,0,0,0,0,0);
      body.run(RELEASE);
      break;
      
      case 36:
      body.run(FORWARD);
      playcomplete("36.WAV");
      delay(700);
      speak(100,100,100,100,100,100,300,200,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 37:
      body.run(FORWARD);
      playcomplete("37.WAV");
      delay(700);
      speak(600,0,0,0,0,0,0,0,0,0);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    
      case 38:
      body.run(FORWARD);
      playcomplete("38.WAV");
      delay(600);
      speak(200,100,100,100,200,0,0,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 39:
      body.run(FORWARD);
      playcomplete("19.WAV");
      delay(700);
      speak(100,100,100,100,100,100,300,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      tail.run(RELEASE);
      break; 
    
      case 40:
      body.run(FORWARD);
      playcomplete("40.WAV");
      delay (800);
      speak(50,100,1000,100,0,0,0,0,0,0);
      body.run(RELEASE);
      break; 
    }
}

//code for the speak function...note that there must be 10 values to call the function
void speak(int longDelay, int shortDelay, int longDelay2, int shortDelay2, int longDelay3, int shortDelay3, int longDelay4, int shortDelay4, int longDelay5, int shortDelay5)
{
BANNED(FORWARD);
delay(longDelay);
BANNED(RELEASE);
delay(shortDelay);
BANNED(FORWARD);
delay(longDelay2);
BANNED(RELEASE);
delay(shortDelay2);
BANNED(FORWARD);
delay(longDelay3);
BANNED(RELEASE);
delay(shortDelay3);
BANNED(FORWARD);
delay(longDelay4);
BANNED(RELEASE);
delay(shortDelay4);
BANNED(FORWARD);
delay(longDelay5);
BANNED(RELEASE);
delay(shortDelay5);
}

//in case I have a longer sentence to play...note that there must be 14 values
void speak2(int longDelay, int shortDelay, int longDelay2, int shortDelay2, int longDelay3, int shortDelay3, int longDelay4, int shortDelay4, int longDelay5, int shortDelay5, int longDelay6, int shortDelay6, int longDelay7, int shortDelay7)
{
BANNED(FORWARD);
delay(longDelay);
BANNED(RELEASE);
delay(shortDelay);
BANNED(FORWARD);
delay(longDelay2);
BANNED(RELEASE);
delay(shortDelay2);
BANNED(FORWARD);
delay(longDelay3);
BANNED(RELEASE);
delay(shortDelay3);
BANNED(FORWARD);
delay(longDelay4);
BANNED(RELEASE);
delay(shortDelay4);
BANNED(FORWARD);
delay(longDelay5);
BANNED(RELEASE);
delay(shortDelay5);
BANNED(FORWARD);
delay(longDelay6);
BANNED(RELEASE);
delay(shortDelay6);
BANNED(FORWARD);
delay(longDelay7);
BANNED(RELEASE);
delay(shortDelay7);
}

//a function for wagging the tail...note that there must be 8 values
void tailwag(int longDelay, int shortDelay, int longDelay2, int shortDelay2, int longDelay3, int shortDelay3, int longDelay4, int shortDelay4)
{
tail.run(FORWARD);
delay(longDelay);
tail.run(RELEASE);
delay(shortDelay);
tail.run(FORWARD);
delay(longDelay2);
tail.run(RELEASE);
delay(shortDelay2);
tail.run(FORWARD);
delay(longDelay3);
tail.run(RELEASE);
delay(shortDelay3);
tail.run(FORWARD);
delay(longDelay4);
tail.run(RELEASE);
delay(shortDelay4);
}

// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
  
   //I commented the following lines out to allow for the wave file to be played while the motor is running

   //while (wave.isplaying) {
  // do nothing while its playing
  //}
  // now its done playing
}

void playfile(char *name) {
  // see if the wave object is currently doing something
  if (wave.isplaying) {// already playing something, so stop it!
    wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file "); Serial.print(name); return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); return;
  }
  
  // ok time to play! start playback
  wave.play();
    
}
      

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: Big Mouth Billy Bass and Motor Shield

Post by adafruit_support_bill »

Congratulations! Glad you got it working. :D

cjb41183
 
Posts: 18
Joined: Sun Mar 03, 2013 12:25 pm

Re: Big Mouth Billy Bass and Motor Shield

Post by cjb41183 »

So after a year of my Big Mouth Billy Bass working great, I have a new idea for the singing fish and I can't seem to execute. Essentially, I want to add a toggle switch so that the fish would have two modes. My only free pin, as far as I can tell, is 9 on the Arduino. So I have wired up a toggle switch with two poles, the center pole going to 5v through a 1Kohm resistor and the outside pole going to pin 9 and ground.

When I upload the following code, it does nothing and I can't figure out why! Here it is:

Code: Select all

/*
*This sketch plays a random sound file at the push of a button and syncs up the motors with the sounds.
*/

//include the appropriate libraries
#include "WaveHC.h"
#include "WaveUtil.h"
#include <AFMotor.h>
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include <TrueRandom.h>
int togglePin = 9;




SdReader card;    // This object holds the information for the card
FatVolume vol;    // This holds the information for the partition on the card
FatReader root;   // This holds the information for the volumes root directory
FatReader f;      // This holds the information for the file we're going to play
WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

uint8_t dirLevel; // indent level for file/dir names    (for prettyprinting)
dir_t dirBuf;     // buffer for directory reads

#define DEBOUNCE 100 //button debouncer

//define motors and names
  AF_DCMotor mouth(2, MOTOR12_64KHZ);
  AF_DCMotor body(3, MOTOR34_64KHZ);
  AF_DCMotor tail(4, MOTOR34_64KHZ);


void play(FatReader &dir);


//setup
void setup()
  {
     Serial.begin(9600);
   
   mouth.setSpeed(255);
   body.setSpeed(255);
   tail.setSpeed(255);
  
   BANNED(RELEASE);
   body.run(RELEASE);
   tail.run(RELEASE);
   
    // Set the output pins for the DAC control. This pins are defined in the library
   pinMode(17, OUTPUT);
   pinMode(16, OUTPUT);
   pinMode(15, OUTPUT);
   pinMode(19, OUTPUT);
   
  //make pin 9 an input enable pull up resistor on toggle switch pin   
   pinMode(togglePin, INPUT);
   
   digitalWrite(togglePin, HIGH);
   

   
   //enable pull-up resistors on switch pins (analog)
   digitalWrite(18, HIGH);

    
  //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
    if (!card.init())
    {         //play with 8 MHz spi (default faster!)  
        putstring_nl("Card init. failed!");  // Something went wrong, lets print out why
        while(1);                            // then 'halt' - do nothing!
    }
    
   // Now we will look for a FAT partition!
    uint8_t part;
      for (part = 0; part < 5; part++){     // we have up to 5 slots to look in
      if (vol.init(card, part)) 
      break;                             // we found one, lets bail
      }
      if (part == 5) {                       // if we ended up not finding one  :(
      putstring_nl("No valid FAT partition!");
      while(1);                            // then 'halt' - do nothing!
      }
    
   // Try to open the root directory
    if (!root.openRoot(vol)) {
    putstring_nl("Can't open root dir!"); // Something went wrong,
    while(1);                             // then 'halt' - do nothing!
    }
    
    
 }
  
//loop


 void loop() {
  
  int switchValue = digitalRead(togglePin); //read toggle pin state
 
  if (switchValue == HIGH) //if switch is off
  {
  normal; //do everything in normal function (defined below)
  }
  else
  {
  fortune; //if not, do everything in fortune function (defined below)
  }
  }


 void normal()
  {
  switch (check_switches()) //see if the button is pressed
    {
      case 5:                //if it is pressed
      playSound();      //play a random sound and move motors
      break;
    }
  }
 
  
 void fortune()
  {
  switch (check_switches()) //see if the button is pressed
    {
      case 5:                //if it is pressed
      playFortune();      //play a random sound and move motors
      break;
    }
  }
 
  
  
  
  
  //check switch function coding
 byte check_switches()
{
  static byte previous[6];
  static long time[6];
  byte reading;
  byte pressed;
  byte index;
  pressed = 0;

  for (byte index = 0; index < 6; ++index) {
    reading = digitalRead(14 + index);
    if (reading == LOW && previous[index] == HIGH && millis() - time[index] > DEBOUNCE)
    {
      // switch pressed
      time[index] = millis();
      pressed = index + 1;
      break;
    }
    previous[index] = reading;
  }
  // return switch number (1 - 6)
  return (pressed);
}


//code for playSound function
void playSound()
{
  int Sound = TrueRandom.random(15);
    //pick a random sound and move the motors to match
    switch (Sound)
    {
      
      case 1:                   
      body.run(FORWARD);        //move the body of the BMBB
      delay(300);
      playcomplete("1.WAV");    //play the sound
      delay(200);               //wait for the sound to start
      speak(200,300,100,100,100,100,100,100,200,100);  //call the speak function which controls the mouth movements...change these values to change the mouth movement
      speak(100,100,200,0,0,0,0,0,0,0);
      delay(500);              //this keeps the body pointed outward
      body.run(RELEASE);        //body to resting position
      break;
      
      case 2:                     
      body.run(FORWARD);
      delay(300);
      playcomplete("2.WAV");
      delay(100);
      speak(600,0,0,0,0,0,0,0,0,0);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    
      case 3:                   
      body.run(FORWARD);
      delay(300);
      playcomplete("3.WAV");
      delay(100);
      speak(200,100,100,100,200,0,0,0,0,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 4:                   
      body.run(FORWARD);
      delay(300);
      playcomplete("4.WAV");
      delay(100);
      speak(50,100,50,100,100,100,100,50,200,0);
      //overall delay for body
      delay(500);
      body.run(RELEASE);
      tail.run(RELEASE);
      break; 
    
      case 5:                        
      body.run(FORWARD);
      delay(300);
      playcomplete("5.WAV");
      delay (100);
      speak(300,200,100,0,0,0,0,0,0,0);
      tailwag(100,100,100,100,100,100,100,100);
      body.run(RELEASE);
      break;
      
      case 6:                         
      body.run(FORWARD);
      delay(300);
      playcomplete("6.WAV");
      delay(100);
      speak(100,100,100,100,100,100,100,150,250,100);
      speak(50,100,100,100,200,0,0,0,0,0);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      break;
      
      case 7:                    
      body.run(FORWARD);
      delay(300);
      playcomplete("7.WAV");
      delay(100);
      speak(50,50,100,100,300,0,0,0,0,0);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    
      case 8:                      
      body.run(FORWARD);
      delay(300);
      playcomplete("8.WAV");
      delay(200);
      speak(100,100,100,100,300,200,0,0,0,0);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      break;
      
      case 9:                    
      body.run(FORWARD);
      delay(300);
      playcomplete("9.WAV");
      delay(100);
      speak(50,100,100,100,50,100,100,100,50,100);
      speak(100,100,250,50,0,0,0,0,0,0);
      //overall delay for body
      delay(300);
      body.run(RELEASE);
      break; 
    
      case 10:                      
      body.run(FORWARD);
      delay(300);
      playcomplete("10.WAV");
      delay(100);
      speak(100,100,100,100,100,100,100,100,50,100);
      speak(300,0,0,0,0,0,0,0,0,0);
      tailwag(100,100,100,100,100,200,0,0);
      delay(800);
      body.run(RELEASE);
      break;
      
      case 11:                        
      body.run(FORWARD);
      delay(300);
      playcomplete("11.WAV");
      delay(100);
      speak(100,100,100,100,100,100,200,200,100,100);
      speak(50,0,0,0,0,0,0,0,0,0);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      break;
      
      case 12:                        
      body.run(FORWARD);
      delay(300);
      playcomplete("12.WAV");
      delay(100);
      speak(100,100,100,100,100,100,50,50,400,0);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    
      case 13:                        
      body.run(FORWARD);
      delay(300);
      playcomplete("13.WAV");
      delay(150);
      speak(150,100,50,100,50,100,50,100,200,0);
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 14:                      
      body.run(FORWARD);
      delay(300);
      playcomplete("14.WAV");
      delay(200);
      speak(100,100,100,100,200,0,0,0,0,0);
      delay(300);
      body.run(RELEASE);
      delay(100);
      tailwag(2000,0,0,0,0,0,0,0);
      break; 
               
    }
}



void playFortune()
{
  int Sound = TrueRandom.random(14);
    //pick a random sound and move the motors to match
    switch (Sound)
    {
      
      case 1:      
      body.run(FORWARD);        //move the body of the BMBB
      delay(300);
      playcomplete("93.WAV");    //play the sound
      delay(100);               //wait for the sound to start
      speak(200,100,100,100,100,100,100,200,300,100);  //call the speak function which controls the mouth movements...change these values to change the mouth movement
      delay(500);              //this keeps the body pointed outward
      body.run(RELEASE);        //body to resting position
      break;
      
      case 2:                      
      body.run(FORWARD);
      delay(300);
      playcomplete("94.WAV");
      delay(400);
      speak(100,100,100,100,100,100,100,100,50,50);
      speak(50,100,100,100,200,0,0,0,0,0); 
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      break;
    
      case 3:                    
      body.run(FORWARD);
      delay(300);
      playcomplete("95.WAV");
      delay(100);
      speak(200,50,100,100,100,100,100,100,100,0);
      //overall delay for body
      delay(1000);
      body.run(RELEASE);
      break;
      
      case 4:                   
      body.run(FORWARD);
      delay(300);
      playcomplete("96.WAV");
      delay(100);
      speak(50,100,50,100,100,100,100,50,200,0);
      //overall delay for body
      delay(500);
      body.run(RELEASE);
      tail.run(RELEASE);
      break; 
    
      case 5:                        
      body.run(FORWARD);
      delay(300);
      playcomplete("97.WAV");
      delay (100);
      speak(300,200,100,0,0,0,0,0,0,0);
      tailwag(100,100,100,100,100,100,100,100);
      body.run(RELEASE);
      break;
      
      case 6:                         
      body.run(FORWARD);
      delay(300);
      playcomplete("98.WAV");
      delay(100);
      speak(100,100,100,100,100,100,100,150,250,100);
      speak(50,100,100,100,200,0,0,0,0,0);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      break;
      
      case 7:                    
      body.run(FORWARD);
      delay(300);
      playcomplete("99.WAV");
      delay(100);
      speak(50,50,100,100,300,0,0,0,0,0);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    
      case 8:                      
      body.run(FORWARD);
      delay(300);
      playcomplete("100.WAV");
      delay(200);
      speak(100,100,100,100,300,200,0,0,0,0);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      break;
      
      case 9:                    
      body.run(FORWARD);
      delay(300);
      playcomplete("101.WAV");
      delay(100);
      speak(50,100,100,100,50,100,100,100,50,100);
      speak(100,100,250,50,0,0,0,0,0,0);
      //overall delay for body
      delay(300);
      body.run(RELEASE);
      break; 
    
      case 10:                      
      body.run(FORWARD);
      delay(300);
      playcomplete("102.WAV");
      delay(100);
      speak(100,100,100,100,100,100,100,100,50,100);
      speak(300,0,0,0,0,0,0,0,0,0);
      tailwag(100,100,100,100,100,200,0,0);
      delay(800);
      body.run(RELEASE);
      break;
      
     case 11:                      
      body.run(FORWARD);
      tailwag(100,100,100,100,100,100,100,100);
      playcomplete("15.WAV");
      speak(100,100,100,150,200,100,200,0,0,0);
      delay(700);
      body.run(RELEASE);
      break;
    
     case 12:                    
      body.run(FORWARD);
      delay(300);
      playcomplete("43.WAV");
      delay(100);
      speak(100,100,400,100,0,0,0,0,0,0);
      tail.run(FORWARD);
      delay(700);
      body.run(RELEASE);
      delay(1000);
      tail.run(RELEASE);
      break;
      
      case 13:                        
      body.run(FORWARD);
      delay(300);
      playcomplete("17.WAV");
      delay(100);
      //speak(0,0,0,0,0,0,0,0,0,0);
      BANNED(BACKWARD);
      tail.run(FORWARD);
      //overall delay for body
      delay(800);
      body.run(RELEASE);
      tail.run(RELEASE);
      break;
    }
}

//code for the speak function...note that there must be 8 numbers to call the function
void speak(int longDelay, int shortDelay, int longDelay2, int shortDelay2, int longDelay3, int shortDelay3, int longDelay4, int shortDelay4, int longDelay5, int shortDelay5)
{
BANNED(FORWARD);
delay(longDelay);
BANNED(RELEASE);
delay(shortDelay);
BANNED(FORWARD);
delay(longDelay2);
BANNED(RELEASE);
delay(shortDelay2);
BANNED(FORWARD);
delay(longDelay3);
BANNED(RELEASE);
delay(shortDelay3);
BANNED(FORWARD);
delay(longDelay4);
BANNED(RELEASE);
delay(shortDelay4);
BANNED(FORWARD);
delay(longDelay5);
BANNED(RELEASE);
delay(shortDelay5);
}



//a function for wagging the tail...note that there must be 8 numbers
void tailwag(int longDelay, int shortDelay, int longDelay2, int shortDelay2, int longDelay3, int shortDelay3, int longDelay4, int shortDelay4)
{
tail.run(FORWARD);
delay(longDelay);
tail.run(RELEASE);
delay(shortDelay);
tail.run(FORWARD);
delay(longDelay2);
tail.run(RELEASE);
delay(shortDelay2);
tail.run(FORWARD);
delay(longDelay3);
tail.run(RELEASE);
delay(shortDelay3);
tail.run(FORWARD);
delay(longDelay4);
tail.run(RELEASE);
delay(shortDelay4);
}

// Plays a full file from beginning to end with no pause.
void playcomplete(char *name) {
  // call our helper to find and play this name
  playfile(name);
  //while (wave.isplaying) {
  // do nothing while its playing
  //}
  // now its done playing
}

void playfile(char *name) {
  // see if the wave object is currently doing something
  if (wave.isplaying) {// already playing something, so stop it!
    wave.stop(); // stop it
  }
  // look in the root directory and open the file
  if (!f.open(root, name)) {
    putstring("Couldn't open file "); Serial.print(name); return;
  }
  // OK read the file and turn it into a wave object
  if (!wave.create(f)) {
    putstring_nl("Not a valid WAV"); return;
  }
  
  // ok time to play! start playback
  wave.play();
    
}
The "normal" function has 93 different cases in it (I deleted all but a few them for the sake of posting to here) and the "fortune" function has 13 different cases. Before, when I was just using the playSound function in the loop, the code wold be about 26,000 bytes. However, as I have added the "normal" and "fortune" functions as well as the if/else statement in the loop, for some reason it is only about 7,000 bytes now. Is something getting dropped because of bad coding on my part?

The code, as I had it, worked perfectly before. The only things I have tried to change for this new project are to make the loop an if/else statement and the functions called "normal" and "fortune" which are the two cases for the if/else. What is now the "normal" function used to be the only function and it worked great.

Thank you for any help you can offer!

User avatar
Franklin97355
 
Posts: 23910
Joined: Mon Apr 21, 2008 2:33 pm

Re: Big Mouth Billy Bass and Motor Shield

Post by Franklin97355 »

So I have wired up a toggle switch with two poles, the center pole going to 5v through a 1Kohm resistor and the outside pole going to pin 9 and ground.
If you have a connection from pin 9 to ground the 5v through the 1K resistor will never be seen. You need the resistor (make it a 10K to 100K) between the ground and pin 9.

cjb41183
 
Posts: 18
Joined: Sun Mar 03, 2013 12:25 pm

Re: Big Mouth Billy Bass and Motor Shield

Post by cjb41183 »

Thank you for that. I changed the wiring around but it still did't work. I checked my code again and I realized that my if/else statement was lacking parentheses after the name of the function. I put them in and it worked.

Code: Select all

 void loop() {
  
  switchState = digitalRead(togglePin); //read toggle pin state
 
  if (switchState == HIGH) //if switch is on
  {
  normal(); //do everything in normal function (defined below)
  }
  else
  {
  fortune(); //if not, do everything in fortune function (defined below)
  }
  }
The problem I am having now is that it acts erratically and doesn't play sounds. The code takes up 25, 626 bytes. In the "normal" function there are 93 cases. When I comment out 10 of those, it drops the code to 24, 222 bytes and it works perfectly with the switch and everything. Am I running out of memory? I thought the max was 32, 256 bytes? Thank you for your help!

User avatar
adafruit_support_bill
 
Posts: 88087
Joined: Sat Feb 07, 2009 10:11 am

Re: Big Mouth Billy Bass and Motor Shield

Post by adafruit_support_bill »

Am I running out of memory? I thought the max was 32, 256 bytes?
There are several types of memory in the arduino. See this guide or details: http://learn.adafruit.com/memories-of-an-arduino

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

Return to “Other Arduino products from Adafruit”