Go Down

Topic: Uno + Waveshield + Ping Sensor problem (audio won't play) (Read 1 time) previous topic - next topic

May 01, 2012, 08:33 pm Last Edit: May 01, 2012, 08:53 pm by merkinmuffley10 Reason: 1
First time here, first time doing anything like this but I'm trying to learn. Having a problem getting the audio to play. The WAV files are all on the card. Loop and if/elseif functions all running perfectly with readings from ping sensor. Once it gets to void playfile, message displays "Couldn't Open File". Any ideas?

Code: [Select]
/* Ping))) Sensor
 
  This sketch reads a PING))) ultrasonic rangefinder and returns the
  distance to the closest object in range. To do this, it sends a pulse
  to the sensor to initiate a reading, then listens for a pulse
  to return.  The length of the returning pulse is proportional to
  the distance of the object from the sensor.
   
  The circuit:
* +V connection of the PING))) attached to +5V
* GND connection of the PING))) attached to ground
* SIG connection of the PING))) attached to digital pin 7

  http://www.arduino.cc/en/Tutorial/Ping
 
  created 3 Nov 2008
  by David A. Mellis
  modified 30 Aug 2011
  by Tom Igoe

  This example code is in the public domain.

*/

// this constant won't change.  It's the pin number
// of the sensor's output:
#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

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


// this handy function will return the number of bytes currently free in RAM, great for debugging!  
// set up serial port
const int pingPin = 11;

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() {
 
 Serial.begin(9600);

 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!
 
 //  if (!card.init(true)) { //play with 4 MHz spi if 8MHz isn't working for you
 if (!card.init(true)) {         //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 ");
 
 // 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.
 root.ls(LS_R | LS_FLAG_FRAGMENTED);

}

void loop()
{
 // establish variables for duration of the ping,
 // and the distance result in inches and centimeters:
 long duration, inches, cm;

 // The PING))) is triggered by a HIGH pulse of 2 or more microseconds.
 // Give a short LOW pulse beforehand to ensure a clean HIGH pulse:
 pinMode(pingPin, OUTPUT);
 digitalWrite(pingPin, LOW);
 delayMicroseconds(2);
 digitalWrite(pingPin, HIGH);
 delayMicroseconds(5);
 digitalWrite(pingPin, LOW);

 // The same pin is used to read the signal from the PING))): a HIGH
 // pulse whose duration is the time (in microseconds) from the sending
 // of the ping to the reception of its echo off of an object.
 pinMode(pingPin, INPUT);
 duration = pulseIn(pingPin, HIGH);

 // convert the time into a distance
 inches = microsecondsToInches(duration);
 cm = microsecondsToCentimeters(duration);
 
 Serial.print(inches);
 Serial.print("in, ");
 Serial.print(cm);
 Serial.print("cm");
 Serial.println();

if (cm >= 1){

static byte playing = -1;
 
if (cm < 10) {
   if (playing != 0) {
     playing = 0;
     playcomplete("DO.WAV");
   }
 }
 else if (cm < 20) {
   if (playing != 1) {
     playing = 1;
     playcomplete("RE.WAV");
   }
 }
 else if (cm < 30) {
   if (playing != 2) {
     playing = 2;
     playcomplete("MI.WAV");
   }  
 }
 else if (cm < 40) {
   if (playing != 3) {
     playing = 3;
     playcomplete("FA.WAV");
   }
 }
 else if (cm < 60) {
   if (playing != 4) {
     playing = 4;
     playcomplete("SO.WAV");
   }
 }
 else if (cm < 80) {
   if (playing != 5) {
     playing = 5;
     playcomplete("LA.WAV");
   }
 }

 if (! wave.isplaying) {
   playing = -1;
 }
 delay(500);
}
}

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


long microsecondsToInches(long microseconds)
{
 // According to Parallax's datasheet for the PING))), there are
 // 73.746 microseconds per inch (i.e. sound travels at 1130 feet per
 // second).  This gives the distance travelled by the ping, outbound
 // and return, so we divide by 2 to get the distance of the obstacle.
 // See: http://www.parallax.com/dl/docs/prod/acc/28015-PING-v1.3.pdf
 return microseconds / 74 / 2;
}

long microsecondsToCentimeters(long microseconds)
{
 // The speed of sound is 340 m/s or 29 microseconds per centimeter.
 // The ping travels out and back, so to find the distance of the
 // object we take half of the distance travelled.
 return microseconds / 29 / 2;
}

If it helps, here's the original wave shield code I modified (from ladyada).

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 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;
  static byte playing = -1;
 
  if (pressed[0]) {
    if (playing != 0) {
      playing = 0;
      playfile("DO.WAV");
    }
  }
  else if (pressed[1]) {
    if (playing != 1) {
      playing = 1;
      playfile("RE.WAV");
    }
  }
  else if (pressed[2]) {
    if (playing != 2) {
      playing = 2;
      playfile("MI.WAV");
    } 
  }
  else if (pressed[3]) {
    if (playing != 3) {
      playing = 3;
      playfile("FA.WAV");
    }
  }
  else if (pressed[4]) {
    if (playing != 4) {
      playing = 4;
      playfile("SO.WAV");
    }
  }
  else if (pressed[5]) {
    if (playing != 5) {
      playing = 5;
      playfile("LA.WAV");
    }
  }

  if (! wave.isplaying) {
    playing = -1;
  }
}



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

dxw00d

Yours:
Code: [Select]
  // look in the root directory and open the file
  if (!f.open(root, *name)) {


Original:
Code: [Select]
  // look in the root directory and open the file
  if (!f.open(root, name)) {


dxw00d


is this it? sorry, like i stated, i'm new to this stuff. googled arduino debugger but didn't come up with anything.

Free RAM: 636
Using partition 1, type is FAT32
DO.WAV 
FA.WAV 
LA.WAV 
MI.WAV 
RE.WAV 
SO.WAV 
TI.WAV 
0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV0in, 0cm
Couldn't open file DO.WAV

Note: in the serial output, i didn't have the ping sensor hooked up but it normally does work, read correctly, and trigger the correct file.

Here's a bit of an update:
   I removed the ping sensor code and switched all the if/ else if statements to 10 == 10, 20 == 20, ect so that the first file always triggers and there's no code discrepancies. First file plays perfectly. Somehow, the few lines of ping sensor code is causing the files not to play. Anyone have any ideas?

dxw00d

Post the output with the sensor connected. Leaving out the important part makes remote debugging really hard.

Go Up