Wave Shield code problems

Adafruit Ethernet, Motor, Proto, Wave, Datalogger, GPS Shields - etc!

Moderators: adafruit_support_bill, adafruit

Please be positive and constructive with your questions and comments.
Locked
III
 
Posts: 5
Joined: Sat Mar 17, 2012 11:45 am

Wave Shield code problems

Post by III »

Hello all,

I recently assembled a Wave Shield for an art project, I was doing well until I fell into a code abyss.

My project is essentially a box. I need to be able to push a button which will cause two LEDs to light up (daisy-chained to a single pin right now), plus play an audio track (wave file). The LEDs should remain lit for the duration the audio is playing.

This is my first time using Arduino, please assume I know nothing, no coding.
The other problem is that this project has to be completed in the next 48 hrs.
I realize that I have taken on something way out of my circle of expertise, I'm pretty desperate for help.
Any information would be helpful. Many, many thanks in advance.

Here is the code I have assembled so far.
I think there is superfluous code in there...please be patient with me!

[Edit - moderator - use code button when submitting code]

Code: Select all

#include <AF_Wave.h>
#include <avr/pgmspace.h>
#include "util.h"
#include "wave.h"

AF_Wave card;
File f;
Wavefile wave;      // only one!

#define redled 9

uint16_t samplerate;

const int buttonPin = 2;     // the number of the pushbutton pin
const int ledPin =  13;      // the number of the LED pin

// variables will change:
int buttonState = 0;         // variable for reading the pushbutton status

void setup() {
  Serial.begin(9600);           // set up Serial library at 9600 bps
  Serial.println("Wave test!");
  // initialize the LED pin as an output:
  pinMode(ledPin, OUTPUT);      
  // initialize the pushbutton pin as an input:
  pinMode(buttonPin, INPUT); 
  
 /* pinMode(9, OUTPUT);//led 
  pinMode(13, INPUT);//button
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT);
  pinMode(redled, OUTPUT);*/
  
  if (!card.init_card()) {
    putstring_nl("Card init. failed!"); return;
  }
  if (!card.open_partition()) {
    putstring_nl("No partition!"); return;
  }
  if (!card.open_filesys()) {
    putstring_nl("Couldn't open filesys"); return;
  }

 if (!card.open_rootdir()) {
    putstring_nl("Couldn't open dir"); return;
  }

  putstring_nl("Files found:");
  ls();//above debugging
}

void ls() {
  char name[13];
  int ret;
  
  card.reset_dir();
  putstring_nl("Files found:");
  while (1) {
    ret = card.get_next_name_in_dir(name);
    if (!ret) {
       card.reset_dir();
       return;
    }
    Serial.println(name);//files found, things ok
  }
}

uint8_t tracknum = 0;

void loop() { 
   uint8_t i, r;
   char c, name[15];
  buttonState = digitalRead(buttonPin);

   card.reset_dir();
   // scroll through the files in the directory
   for (i=0; i<tracknum+1; i++) {
     r = card.get_next_name_in_dir(name);
     if (!r) {
       // ran out of tracks! start over
       tracknum = 0;
       return;
     }
   }
   putstring("\n\rPlaying "); Serial.print(name);
   // reset the directory so we can find the file
   card.reset_dir();
   playcomplete(name);
   tracknum++;
   
   //names
}

void playcomplete(char *name) {
  uint16_t potval;
  uint32_t newsamplerate;
  
  playfile(name);
  samplerate = wave.dwSamplesPerSec;
    if (buttonState == HIGH) {     
    // turn LED on:    
    digitalWrite(ledPin, HIGH);  
  } 
  else {
    // turn LED off:
    digitalWrite(ledPin, LOW); 
  }
  while (wave.isplaying) {     
	// you can do stuff here!
	delay(500);//ms
   }
  card.close_file(f);
}

void playfile(char *name) {
   f = card.open_file(name);
   if (!f) {
      putstring_nl(" Couldn't open file"); return;
   }
   if (!wave.create(f)) {
     putstring_nl(" Not a valid WAV"); return;
   }
   // ok time to play!
   wave.play();
}

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

Re: Wave Shield code problems

Post by adafruit_support_bill »

Does the current code work at all? If you explain what works and what doesn't, it will make it easier for us to help out.

III
 
Posts: 5
Joined: Sat Mar 17, 2012 11:45 am

Re: Wave Shield code problems

Post by III »

I may be on the cusp of getting the wave shield working with the button.
I scrapped the code above (was hashed together by a friend) and started to use the adafruit
example code here.

I am currently between home and studio. I'll post new code with results after I've had a chance to test it.

Thanks for your offer to help!

III
 
Posts: 5
Joined: Sat Mar 17, 2012 11:45 am

Re: Wave Shield code problems

Post by III »

Ok, the push-button code works but I have not uploaded it to my arduino yet.
I wanted to confirm that my wires are in the right place before hooking it up to my computer.
I modeled it on a diagram for a button to turn on LED lights, not sure if the same applies to turning on a speaker.
What worries me is the packaging for the button I bought reads 125V, and I have a wire hooked up to a pin that says 5v.

Also, which # pin should I connect my button wire to if I use this code for my wave shield?
The only Wave file I want to use is called "BD.WAV", I dont need the "re, mi, fa, etc..".

Thank you!

Code: Select all

#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[] = {14, 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("BD.WAV");
  }
  if (justpressed[1]) {
      justpressed[1] = 0;
      playcomplete("RE.WAV");
  }
  if (justpressed[2]) {
      justpressed[2] = 0;
      playcomplete("MI.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();
}

Image

III
 
Posts: 5
Joined: Sat Mar 17, 2012 11:45 am

Re: Wave Shield code problems

Post by III »

I tried attaching one of my button wires to the ground pin, and the other to pin 0 (Analogue In).
No audio came from my speaker.

I also tried the configuration in the picture above.
Nothing.

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

Re: Wave Shield code problems

Post by adafruit_support_bill »

First. The wiring you have there will create a direct short between 5v and GND when you press the button. This will overload (and possibly damage) the voltage regulator. Remove the yellow and purple jumpers.

Second. The code you are using enables the internal pullup resistors in the microprocessor and uses inverse logic for the buttons. This means that you should connect your button between the input pin (brown jumper) and GND (grey jumper).

Next, open the serial monitor and see what is printed there when you run the sketch.

III
 
Posts: 5
Joined: Sat Mar 17, 2012 11:45 am

Re: Wave Shield code problems

Post by III »

I got everything sorted out in the end.

Once I finally got the Wave file to play, I had a problem with a test-run Wave file playing instead of the audio file I wanted, even though I had deleted the test file from the SD card.
I realized afterwards that I had uploaded a copy of my original Wave file, not the one I had converted to 16KHz, 16 bit mono.
I reformatted my SD, uploaded the proper Wave file, the speaker worked, I added some code to sync my LEDs with the audio, and I was done.

I'm impressed by how hearty the Wave Shield is, it put up with a lot of abuse from a novice like me...


Thank you for your help.

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

Return to “Arduino Shields from Adafruit”