Go Down

Topic: Wave Shield - Play Track on Button Press (Read 11618 times) previous topic - next topic

Curly

I am a newbie at Arduino.  I have a wave shield and I'm trying to play a wav file when I press a button.  I have the code below which works, but it just loops all of the files on the SD card.  How can I get it to play a certain file when I press a certain button:

Code: [Select]
/*
* This example plays every .WAV file it finds on the SD card in a loop
*/
#include <WaveHC.h>
#include <WaveUtil.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))

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

//////////////////////////////////// LOOP
void loop() {
  root.rewind();
  play(root);
}

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

xl97

Have you checked out the examples Adafruit provides for you?

examples:
http://www.ladyada.net/make/waveshield/examples.html


button interfacing:
http://www.ladyada.net/make/waveshield/libraryhcplay6.html


http://www.ladyada.net/make/waveshield/libraryhc.html

play once sketch:
http://www.ladyada.net/media/wavshield/wavehc_play6interonce.pde

Curly

Yeah I've used these but these are not woking with my wave shield their isn't enough digital pins on my wave shield, i think the code is set for a duemilanova, so i was wondering if there is a way to add to this code which loops a track so that plays 4 different wav.files for 4 different buttons.
Thanks

xl97

??  Im confused?

These default code samples dont work?

If you dont have a Duemilanova board.. hat type of board 'do' you have? I didnt see you even mention it?

Do you have a Mega or something?

Curly

yeah sorry i didnt... am using an uno, there code that I've put up works with my arduino and wave shield it loops a song, but the other ones don't probably because the code is set up for duemilanove, I've tried to change the code to suit my board but am not having much luck.


Curly

thanks for your help anyway, ill just keep trying

xl97


what happens when you say it 'doesnt work'?

Are you getting errors?

Does the code compile?

Are you just not getting audio wen you press a button?


1.) post a wiring diagram of how you have your set-up wired  (switches..etc)

2.) post the code you are trying to use.. (wrap the code inside [ code ] [ / code ] tags please.


Curly

The audio plays but without the button being pressed, if you move the wires out of the analog pins the next track will play e.g. if i take out the first wire to the button the second wav file will play for the next button but it just loops it and pressing the button has no effect.
This is the code am using, that i think is for a duemilanove, but its for 6 buttons and 6 sounds.

Code: [Select]
#include <FatReader.h>
#include <SdReader.h>
#include <avr/pgmspace.h>
#include "WaveUtil.h"
#include "WaveHC.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 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(2, OUTPUT);
  pinMode(3, OUTPUT);
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);

  // pin13 LED
pinMode(13, OUTPUT);

  // enable pull-up resistors on switch pins (analog inputs)
  digitalWrite(14, HIGH);
  digitalWrite(15, HIGH);
  digitalWrite(16, HIGH);
  digitalWrite(17, HIGH);
  digitalWrite(18, HIGH);
  digitalWrite(19, 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!
  }
 
  // 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 1:
      playcomplete("1.WAV");
      break;
    case 2:
      playcomplete("2.WAV");
      break;
    case 3:
      playcomplete("3.WAV");
      break;
    case 4:
      playcomplete("4.WAV");
      break;
    case 5:
      playcomplete("5.WAV");
      break;
    case 6:
      playcomplete("6.WAV");
  }
}

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

xl97

without code.. what is ti you want to 'do'?


you want to have .wav files on the SD card.. and .....??

how many buttons do you have/want?


what are the buttons to do when pressed?  play a certain file form the SD card?

are you sure you are using the correct sample sketch?  some let a button press interrupt the current sound with a new sound.. some do not..etc....  do you have 6 buttons?


dreadevil


Ive made a Daft Punk Guy Manuel Helmet Replica and didn't use an arduino for my sequences. I know i probably should have used an arduino, but i went the route of led chasers and the transistor board.
ahem...anyways, since then i wanted sounds in the helmet, so i bought a Duemilanova  and Waveshield. I would like to have the wave shield play a sound when i press the tactile momentary switch buttons  on my other devices (3  LED chasers, a voice changer). 
suggestions?

nytro81

absolutely no problem with ladyada wave shield and arduino uno, with all of the examples provided!

jmb1971

Hi Curly, (or at least I hope so!)

I read your post with interest as I appear to be having exactly the same problems that you are/were having.  The forum here doesn't state whether you succeeded in resolving the issue so I have to ask... Did you get it sorted?

I have an Arduino Uno R3 with Waveshield.  I want to play 7 gameshow sound effects (I am a teacher and wanted to create some sounds to accompany revision session by making it into a gameshow).  I got the DAPHC code to work without any problems and like you, the wav files on the SD card all played in rotation.  However, Adafruit's play6_HC example refuses to play despite the fact that the card initialised and was ready.  I am, of course, a newbie and wired the arcade button straight to the waveshield to receive the message:

WaveHC with 6 buttons
Free RAM: 613
Using partition 1, type is FAT32
Ready!
Couldn't open file SOUND1.WAV

Read the lesson 5 on adafruit reference the pull-up/pull-down resistors (http://www.ladyada.net/learn/arduino/lesson5.html) and created a pull-up resistor circuit that worked great with the exercises etc. 

Still no joy!

To cut a very long story short, I can't get my waveshield to play a wav file when I press the button!  All of the examples display exactly the same message...

Help?

JMB1971


Go Up