Wave Shield + Buttons

by bob500000 on Tue Nov 20, 2012 10:23 am

Having followed various tutorials on this subject I'm at wits end.

I have followed the following http://www.ladyada.net/make/waveshield/libraryhcplay6.html and I can't get the wave shield to play no problems but when I want to integrate buttons to switch songs it fails to work, sometimes in the serial dialogue I get "can't open file 1.wav or 2.wav but then after pressing the buttons several times it works, I wan to make this seamless and it doesn't want to play ball.

When you press a button it opens a file and plays then when you press another it does the same with another file, Nothing to complex but when you press a button nothing happens then you press the other button and it does nothing after several presses the song will change but this isn't scripted to the button meaning that if I press one button then the other file will play and not one designated to the button and visa versa. I include a copy of the code that I am using and if you can help it will be much appreciated.

Code: Select all | TOGGLE FULL SIZE
#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 5  // button debouncer

// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {12, 15, 16, 17, 18, 19};
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'pressed' (the current state
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];

// 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() {
  byte i;
 
  // set up serial port
  Serial.begin(9600);
  putstring_nl("WaveHC with ");
  Serial.print(NUMBUTTONS, DEC);
  putstring_nl("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);
 
  // Make input & enable pull-up resistors on switch pins
  for (i=0; i< NUMBUTTONS; i++) {
    pinMode(buttons[i], INPUT);
    digitalWrite(buttons[i], 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!");
 
  TCCR2A = 0;
  TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;

  //Timer2 Overflow Interrupt Enable
  TIMSK2 |= 1<<TOIE2;


}

SIGNAL(TIMER2_OVF_vect) {
  check_switches();
}

void check_switches()
{
  static byte previousstate[NUMBUTTONS];
  static byte currentstate[NUMBUTTONS];
  byte index;

  for (index = 0; index < NUMBUTTONS; index++) {
    currentstate[index] = digitalRead(buttons[index]);   // read the button
   
    /*     
    Serial.print(index, DEC);
    Serial.print(": cstate=");
    Serial.print(currentstate[index], DEC);
    Serial.print(", pstate=");
    Serial.print(previousstate[index], DEC);
    Serial.print(", press=");
    */
   
    if (currentstate[index] == previousstate[index]) {
      if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
          // just pressed
          justpressed[index] = 1;
      }
      else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
          // just released
          justreleased[index] = 1;
      }
      pressed[index] = !currentstate[index];  // remember, digital HIGH means NOT pressed
    }
    //Serial.println(pressed[index], DEC);
    previousstate[index] = currentstate[index];   // keep a running tally of the buttons
  }
}


void loop() {
  byte i;
 
  if (justpressed[0]) {
      justpressed[0] = 0;
      playcomplete("1.WAV");
  }
  if (justpressed[1]) {
      justpressed[1] = 0;
      playcomplete("2.WAV");
  }
  if (justpressed[2]) {
      justpressed[2] = 0;
      playcomplete("l.WAV");
  }
  if (justpressed[3]) {
      justpressed[3] = 0;
      playcomplete("FA.WAV");
  }
  if (justpressed[4]) {
      justpressed[4] = 0;
      playcomplete("SO.WAV");
  }
  if (justpressed[5]) {
      justpressed[5] = 0;
      playcomplete("LA.WAV");
  }
}



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


cheers
bob500000
 
Posts: 54
Joined: Tue Nov 20, 2012 10:16 am

Re: Wave Shield + Buttons

by adafruit_support_bill on Tue Nov 20, 2012 12:17 pm

sometimes in the serial dialogue I get "can't open file 1.wav or 2.wav but then after pressing the buttons several times it works,

Does it always fail on the same files? Or does it succeed sometimes and fail others.

It could be an intermittent problem reading the SD card. If you post clear photos of the front & back of the shield we'll take a look.
User avatar
adafruit_support_bill
 
Posts: 28125
Joined: Sat Feb 07, 2009 9:11 am

Re: Wave Shield + Buttons

by xl97 on Tue Nov 20, 2012 1:23 pm

adafruit_support wrote:
sometimes in the serial dialogue I get "can't open file 1.wav or 2.wav but then after pressing the buttons several times it works,

Does it always fail on the same files? Or does it succeed sometimes and fail others.

It could be an intermittent problem reading the SD card. If you post clear photos of the front & back of the shield we'll take a look.



I have experienced this before as well.. (and not only with the WaveShield..but other soundboards, retail even that use SD cards for audio playback)

Usually a re-format of the card, and/or copying all files at once can fix this..

(if its a constant problem with the same audio file.. I would try to re-save it.. or compose it.. maybe wrong format?..corrupt..etc)
xl97
 
Posts: 144
Joined: Mon Jul 27, 2009 11:51 am

Re: Wave Shield + Buttons

by pburgess on Tue Nov 20, 2012 3:07 pm

Might try commenting out this line:

Code: Select all | TOGGLE FULL SIZE
  card.partialBlockRead(true);


Also, the serial output from the program might be helpful to see.
User avatar
pburgess
 
Posts: 2440
Joined: Sun Oct 26, 2008 1:29 am

Re: Wave Shield + Buttons

by bob500000 on Wed Nov 21, 2012 5:57 am

Sorry for the delay uk time zones

Ok, I have try the suggestions I include screenshots from the serial monitor and also shots of the soldering if you would take a look.

I have amended the code but seem to think that it has something to do with the code, and that it is not doing anything once the button is pressed.

Another thing that you will notice on the serial is that the it fails to play some files and stops dead, you cannot get it to plat again until you reset the wave board.

hope this helps.

Serial Monitor

Serial Audio.PNG
Serial Audio.PNG (54.79 KiB) Viewed 1316 times


Serial Audio 2.PNG
Serial Audio 2.PNG (52.2 KiB) Viewed 1316 times


Soldering

Solder 4.zip
(407.79 KiB) Downloaded 56 times


Code

Code: Select all | TOGGLE FULL SIZE
#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 5  // button debouncer

// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {12, 15, 16, 17, 18, 19};
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'pressed' (the current state
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];

// 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() {
  byte i;
 
  // set up serial port
  Serial.begin(9600);
  putstring_nl("WaveHC with ");
  Serial.print(NUMBUTTONS, DEC);
  putstring_nl("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);
 
  // Make input & enable pull-up resistors on switch pins
  for (i=0; i< NUMBUTTONS; i++) {
    pinMode(buttons[i], INPUT);
    digitalWrite(buttons[i], 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!");
 
  TCCR2A = 0;
  TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;

  //Timer2 Overflow Interrupt Enable
  TIMSK2 |= 1<<TOIE2;


}

SIGNAL(TIMER2_OVF_vect) {
  check_switches();
}

void check_switches()
{
  static byte previousstate[NUMBUTTONS];
  static byte currentstate[NUMBUTTONS];
  byte index;

  for (index = 0; index < NUMBUTTONS; index++) {
    currentstate[index] = digitalRead(buttons[index]);   // read the button
   
    /*     
    Serial.print(index, DEC);
    Serial.print(": cstate=");
    Serial.print(currentstate[index], DEC);
    Serial.print(", pstate=");
    Serial.print(previousstate[index], DEC);
    Serial.print(", press=");
    */
   
    if (currentstate[index] == previousstate[index]) {
      if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
          // just pressed
          justpressed[index] = 1;
      }
      else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
          // just released
          justreleased[index] = 1;
      }
      pressed[index] = !currentstate[index];  // remember, digital HIGH means NOT pressed
    }
    //Serial.println(pressed[index], DEC);
    previousstate[index] = currentstate[index];   // keep a running tally of the buttons
  }
}


void loop() {
  byte i;
 
  if (justpressed[0]) {
      justpressed[0] = 0;
      Serial.println("Button is pressed");
      playcomplete("1.WAV");
      playcomplete("2.WAV");
  }
  if (justpressed[1]) {
      justpressed[1] = 0;
      playcomplete("2.WAV");
  }
  if (justpressed[2]) {
      justpressed[2] = 0;
      playcomplete("l.WAV");
  }
  if (justpressed[3]) {
      justpressed[3] = 0;
      playcomplete("FA.WAV");
  }
  if (justpressed[4]) {
      justpressed[4] = 0;
      playcomplete("SO.WAV");
  }
  if (justpressed[5]) {
      justpressed[5] = 0;
      playcomplete("LA.WAV");
  }
}



// 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
  Serial.println("Wave is 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
    Serial.println("Wave Stopped");
  }
  // 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();
  Serial.println("Next Wave is playing");
}


cheers
bob500000
 
Posts: 54
Joined: Tue Nov 20, 2012 10:16 am

Re: Wave Shield + Buttons

by adafruit_support_bill on Wed Nov 21, 2012 6:24 am

Looks like a few questionable solder joints there. Take a look at this guide and re-touch anything that looks suspicious. Pay special attention to pins 10-13, the buffer chip and the SD card holder connections.
User avatar
adafruit_support_bill
 
Posts: 28125
Joined: Sat Feb 07, 2009 9:11 am

Re: Wave Shield + Buttons

by pburgess on Wed Nov 21, 2012 11:44 am

Ah! Also, you have a button connected to pin 12. That's one of the lines used when communicating with the SD card (steer clear of pins 10-13). 2-5 are used for the DAC, and 0-1 for the Serial port. Anything else should be fair game.
User avatar
pburgess
 
Posts: 2440
Joined: Sun Oct 26, 2008 1:29 am

Re: Wave Shield + Buttons

by bob500000 on Thu Nov 22, 2012 6:56 am

Ok, so another update

I have now changed the ports so the buttons run off 16 and 17 button but now it will not interrupt the song it plays all the way through until it finishes, can you advise what I'm missing to get it change songs mid way through playback.

Code: Select all | TOGGLE FULL SIZE
#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 5  // button debouncer

// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {16, 17, 11, 17, 18, 19};
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'pressed' (the current state
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];

// 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() {
  byte i;
 
  // set up serial port
  Serial.begin(9600);
  putstring_nl("WaveHC with ");
  Serial.print(NUMBUTTONS, DEC);
  putstring_nl("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);
 
  // Make input & enable pull-up resistors on switch pins
  for (i=0; i< NUMBUTTONS; i++) {
    pinMode(buttons[i], INPUT);
    digitalWrite(buttons[i], 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!");
 
  TCCR2A = 0;
  TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;

  //Timer2 Overflow Interrupt Enable
  TIMSK2 |= 1<<TOIE2;


}

SIGNAL(TIMER2_OVF_vect) {
  check_switches();
}

void check_switches()
{
  static byte previousstate[NUMBUTTONS];
  static byte currentstate[NUMBUTTONS];
  byte index;

  for (index = 0; index < NUMBUTTONS; index++) {
    currentstate[index] = digitalRead(buttons[index]);   // read the button
   
    /*     
    Serial.print(index, DEC);
    Serial.print(": cstate=");
    Serial.print(currentstate[index], DEC);
    Serial.print(", pstate=");
    Serial.print(previousstate[index], DEC);
    Serial.print(", press=");
    */
   
    if (currentstate[index] == previousstate[index]) {
      if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
          // just pressed
          justpressed[index] = 1;
      }
      else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
          // just released
          justreleased[index] = 1;
      }
      pressed[index] = !currentstate[index];  // remember, digital HIGH means NOT pressed
    }
    //Serial.println(pressed[index], DEC);
    previousstate[index] = currentstate[index];   // keep a running tally of the buttons
  }
}


void loop() {
  byte i;
 
  if (justpressed[0]) {
      justpressed[0] = 0;
      Serial.println("Button is pressed");
      playcomplete("1.WAV");
  }
  if (justpressed[1]) {
      justpressed[1] = 0;
      Serial.println("Button 2 is pressed");
      playcomplete("3.WAV");
  }
  if (justpressed[2]) {
      justpressed[2] = 0;
      playcomplete("l.WAV");
  }
  if (justpressed[3]) {
      justpressed[3] = 0;
      playcomplete("FA.WAV");
  }
  if (justpressed[4]) {
      justpressed[4] = 0;
      playcomplete("SO.WAV");
  }
  if (justpressed[5]) {
      justpressed[5] = 0;
      playcomplete("LA.WAV");
  }
}



// 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
  Serial.println("Wave is 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
    Serial.println("Wave Stopped");
  }
  // 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();
  Serial.println("Next Wave is playing");
}
bob500000
 
Posts: 54
Joined: Tue Nov 20, 2012 10:16 am

Re: Wave Shield + Buttons

by adafruit_support_bill on Thu Nov 22, 2012 7:11 am

Code: Select all | TOGGLE FULL SIZE
if (justpressed[1]) {
      justpressed[1] = 0;
      Serial.println("Button 2 is pressed");
      playcomplete("3.WAV");
  }

Playcomplete does not return until the file has played completely. Since you are not checking buttons while it is playing, you can't interrupt the playback.

If you call "playFile()" it will let the buttons interrupt. Check the last 2 examples under "6 buttons, 6 sounds, multiple possibilities!" to see how this is done: http://www.ladyada.net/make/waveshield/examples.html
User avatar
adafruit_support_bill
 
Posts: 28125
Joined: Sat Feb 07, 2009 9:11 am

Re: Wave Shield + Buttons

by bob500000 on Thu Nov 22, 2012 7:20 am

Thanks so much for that.

Must have been my eyes not reading it right but is working now.

Just one more thing can you point me to where I can create a pause/ stop button

cheers :D
bob500000
 
Posts: 54
Joined: Tue Nov 20, 2012 10:16 am

Re: Wave Shield + Buttons

by adafruit_support_bill on Thu Nov 22, 2012 8:19 am

Just add this code for one of your buttons:
Code: Select all | TOGGLE FULL SIZE
    wave.stop(); // stop it
User avatar
adafruit_support_bill
 
Posts: 28125
Joined: Sat Feb 07, 2009 9:11 am

Re: Wave Shield + Buttons

by bob500000 on Thu Nov 22, 2012 11:42 am

Looking at the library adding the pause.wave(); doesn't seem to pause the track,

I want to pause it where it is playing then resume when I hit the play button any ideas on how to do this?

cheers
bob500000
 
Posts: 54
Joined: Tue Nov 20, 2012 10:16 am

Re: Wave Shield + Buttons

by xl97 on Thu Nov 22, 2012 11:59 am

isnt that backwards?


pause.wave()

should be....

wave.pause()..

no?

following the same format/syntax as the other commands/functions?

wave.stop();
wave.play();.........

etc..etc..etc..


read this thread: (second post by fat16lib, author of the WaveHC lib)

http://www.forums.adafruit.com/viewtopi ... 31&t=13914


quote:
For pause/resume use these calls:
Code: Select all | TOGGLE FULL SIZE
// Returns true if the player is paused else false.
uint8_t WaveHC::isPaused(void);

// Pause the player.
void WaveHC::pause(void);

// Resume a paused player.
void WaveHC::resume(void);


Use stop to skip a file. The calls to control start/stop and skip are:

Code: Select all | TOGGLE FULL SIZE
// Play a wave file.
void WaveHC::play(void);

// Stop the player.
void WaveHC::stop(void);

// Has the value true if a wave file is playing else false.
volatile uint8_t WaveHC::isplaying;



hope this helps.. :)
xl97
 
Posts: 144
Joined: Mon Jul 27, 2009 11:51 am

Re: Wave Shield + Buttons

by bob500000 on Thu Nov 22, 2012 12:57 pm

ok, well this as far I have on the project.

I have got it to skip forward and back but I am missing where to tell it that its reached the end of the available files, if you view the serial monitor it starts at 0 and loops to 4 but then when you try and reduce it, i.e. go back to 3,2,1 it starts going into minus the numbers and then just gets messy.

I have also had a go at the play pause button but this too seems to be not working, if you could advise me on where I'm going wrong, I have take a look at a lot of examples and none of them are what I am trying to do.

Code: Select all | TOGGLE FULL SIZE
#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

int currentSongcount = 0;    // Keeps track of which song to play each time the button is pressed
    int maxSongcount = 5;        // Total number of songs on the SD card
int minSongcount = 0;
#define DEBOUNCE 5  // button debouncer

// here is where we define the buttons that we'll use. button "1" is the first, button "6" is the 6th, etc
byte buttons[] = {16, 17, 18, 12, 11, 19};
// This handy macro lets us determine how big the array up above is, by checking the size
#define NUMBUTTONS sizeof(buttons)
// we will track if a button is just pressed, just released, or 'pressed' (the current state
volatile byte pressed[NUMBUTTONS], justpressed[NUMBUTTONS], justreleased[NUMBUTTONS];

// 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() {
  byte i;
 
  // set up serial port
  Serial.begin(9600);
  putstring_nl("WaveHC with ");
  Serial.print(NUMBUTTONS, DEC);
  putstring_nl("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);

  // Make input & enable pull-up resistors on switch pins
  for (i=0; i< NUMBUTTONS; i++) {
    pinMode(buttons[i], INPUT);
    digitalWrite(buttons[i], 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!");
 
  TCCR2A = 0;
  TCCR2B = 1<<CS22 | 1<<CS21 | 1<<CS20;

  //Timer2 Overflow Interrupt Enable
  TIMSK2 |= 1<<TOIE2;


}

SIGNAL(TIMER2_OVF_vect) {
  check_switches();
}

void check_switches()
{
  static byte previousstate[NUMBUTTONS];
  static byte currentstate[NUMBUTTONS];
  byte index;

  for (index = 0; index < NUMBUTTONS; index++) {
    currentstate[index] = digitalRead(buttons[index]);   // read the button
   
    /*     
    Serial.print(index, DEC);
    Serial.print(": cstate=");
    Serial.print(currentstate[index], DEC);
    Serial.print(", pstate=");
    Serial.print(previousstate[index], DEC);
    Serial.print(", press=");
    */
   
    if (currentstate[index] == previousstate[index]) {
      if ((pressed[index] == LOW) && (currentstate[index] == LOW)) {
          // just pressed
          justpressed[index] = 1;
      }
      else if ((pressed[index] == HIGH) && (currentstate[index] == HIGH)) {
          // just released
          justreleased[index] = 1;
      }
      pressed[index] = !currentstate[index];  // remember, digital HIGH means NOT pressed
    }
    //Serial.println(pressed[index], DEC);
    previousstate[index] = currentstate[index];   // keep a running tally of the buttons
  }
}


void loop() {
  byte i;
  static byte playing = -1;

  if (justpressed[0]) {

        currentSongcount == currentSongcount ++;
        Serial.println(currentSongcount);

    if (currentSongcount == 1) {
    playfile("1.wav");
    }
    else if (currentSongcount == 2)  {
    playfile("2.wav");
    }
    else if (currentSongcount == 3)  {
    playfile("3.wav");
    }
    else if (currentSongcount == 4)  {
    playfile("4.wav");
    }
      if (! wave.isplaying) {
        playing = -1;
      }
        if (currentSongcount == maxSongcount)
          currentSongcount = 0;
      justpressed[0] = 0;
        }
    if (justpressed[1]) {

        currentSongcount == currentSongcount --;
        Serial.println(currentSongcount);

    if (currentSongcount == 1) {
    playfile("1.wav");
    }
    else if (currentSongcount == 2)  {
    playfile("2.wav");
    }
    else if (currentSongcount == 3)  {
    playfile("3.wav");
    }
    else if (currentSongcount == 4)  {
    playfile("4.wav");
    }
      if (! wave.isplaying) {
        playing = 0;
      }
        if (currentSongcount == maxSongcount)
          currentSongcount = 4;
      justpressed[1] = 0;
        }
       
        if (justpressed[2]){
           if (wave.isplaying) {// already playing something, so stop it!
            wave.stop(); // stop it
            Serial.println("stopped");
        }
  }
}
// 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
  Serial.println("Wave is 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
    Serial.println("Wave Stopped");
  }
  // 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();
  Serial.println("Next Wave is playing");
}



Cheers
bob500000
 
Posts: 54
Joined: Tue Nov 20, 2012 10:16 am

Re: Wave Shield + Buttons

by xl97 on Thu Nov 22, 2012 3:41 pm

without code..

explain what is you want to 'do'.


how many total buttons?

whats the function of each button?


so far I count 4 total buttons now?

1 - plays same sound
1 - plays a sound file.. then plays another in a 'list'.. if at end of total songs.. the same button will repeat the list

---new---

1- pause sound button?
1- button that does the same as above (second button)..but instead of going FORWARD in the list.. you want to go BACK?



seems like this is all just a simple 'player' project?


play/stop/pause/ff/rwd

??

Im sure this is an easy fix as well..

looking at the code though.. I dont understand some of the extra stuff you have done/added (or why)

but I havent looked at the whole sketch in large either.. maybe after some food! :)
xl97
 
Posts: 144
Joined: Mon Jul 27, 2009 11:51 am