waveshield + ping
Moderators: adafruit_support_bill, adafruit

waveshield + ping

by monolyth221 on Thu Feb 25, 2010 1:00 am

I have a waveshield that I want to activate based on proximity from my parallax 28015 ping sensor. When I run the AF_wave sketch (easier than WaveHC for me to manipulate), the waveshield works fine playing all the files in a loop. When I run the PING))) sketch (http://arduino.cc/en/Tutorial/Ping?from ... oundSensor), I get a nice stream of numbers. However, I am having a hard time combining the two sketches to make them work in unison. The ping sensor only runs once and never activates a wav file. It gives me one numeric value on the serial monitor and then just stops.

I approached it by trying to use the serial numbers as a variable for a "while{_}" statement, thinking that an "if/else" statement would be activating a new wave every few milliseconds. If you're more experienced at coding, I could use a suggestion or two I'm sure. I couldn't even manipulate the wave_hc to make this work, so if that would be better, let me know what I can do.

Here is the code, I commented out unnecessary (or so I think) lines:

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

AF_Wave card;
File f;
Wavefile wave;


const int pingPin = 7;

void setup() {
Serial.begin(9600); // set up Serial library at 9600 bps
// Serial.println("Wave test!");

// set up waveshield pins
for (byte i = 2; i <= 5; ++i) {
pinMode(i, OUTPUT);
}

// open memory card
// 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;
// }
}

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

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

delay(100);

///////////wave stuff for loop

//sound files need to be named acordingly and distance ranges adjusted

while (inches >= 0 && inches <= 75) {
playfile("play1.WAV");
}
while (inches >= 100 && inches <= 175) {
playfile("play2.WAV");
}
while (inches >= 200 && inches <= 275) {
playfile("play3.WAV");
}
while (inches >= 300 && inches <= 399) {
playfile("play4.WAV");
}
return;
}

////////ping functions below

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/ac ... G-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;
//}

////wave functions below

void playfile(char *name) {
// stop any file already playing
if (wave.isplaying) {
wave.stop();
}
// close file if open
if (f) {
card.close_file(f);
}
// play specified file
f = card.open_file(name);
if (f && wave.create(f)) {
wave.play();
}
}
monolyth221
 
Posts: 6
Joined: Sat Feb 06, 2010 12:42 am

Re: waveshield + ping

by dy-wen on Tue Mar 09, 2010 4:46 am

Hey


with a little help from hackerfriends I got the ping running with the waveshield

the code spelling is a bit scruffy - but scroll to copy paste fro my blog post

http://www.capacitor.constantvzw.org/?p=219

hope it works out for you too :-)
dy-wen
 
Posts: 30
Joined: Wed Sep 16, 2009 11:31 am

Re: waveshield + ping

by adafruit_support_bill on Tue Mar 09, 2010 7:18 am

Code: Select all | TOGGLE FULL SIZE
//sound files need to be named acordingly and distance ranges adjusted

while (inches >= 0 && inches <= 75) {
playfile("play1.WAV");
}
while (inches >= 100 && inches <= 175) {
playfile("play2.WAV");
}
while (inches >= 200 && inches <= 275) {
playfile("play3.WAV");
}
while (inches >= 300 && inches <= 399) {
playfile("play4.WAV");
}


Your "inches" will never change once you go into one of those 'while' loops. You will get stuck trying to play the same file forever. Change all the 'while's to 'if's.
User avatar
adafruit_support_bill
 
Posts: 31900
Joined: Sat Feb 07, 2009 10:11 am

Re: waveshield + ping

by monolyth221 on Thu Mar 11, 2010 9:35 pm

I tried your code, dy-wen, but it keeps getting hung up on the AF_wave card; before the setup. No idea why, our codes are similar and that's a standard function of the AF library. Arduwino, I think that when I had "if" statements, it was trying to activate the sound file every single time there was a reading so I used "while" to allow time to play the files. Since then I have revised my code since the parallax ping sensor is kind of erratic, so I have added a smoothing function. This sketch reads distance but never activates the sound and I'm not sure why. Is there something I should add to the cases to make it play?

Code: Select all | TOGGLE FULL SIZE
#include <AF_Wave.h>
#include <avr/pgmspace.h>
#include "util.h"
#include "wave.h"

AF_Wave card;
File f;
Wavefile wave;   

const int pingPin = 7;
const int sensorMin = 0;     
const int sensorMax = 70;
const int numReadings = 10;      //this is the number of sensor readings to average
int readings[numReadings];      // the readings from the analog input
int index = 0;                  // the index of the current reading
int total = 0;                  // the running total
int average = 0; 



void setup() {

  Serial.begin(9600);

  /////////////////////     SMOOTHING Initialize     //////////////////////
 
    for (int thisReading = 0; thisReading < numReadings; thisReading++){
    readings[thisReading] = 0;
  }
 
////////////////////////////////////////////////////////////////////////
 
 //waveshield setup
  for (byte i = 2; i <= 5; ++i) {
    pinMode(i, OUTPUT);
  }
 
 
}


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

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

  ////////////////    USE A SWITCH STATEMENT TO TRIGGER SENSOR ZONES //////////////////////////
 
  inches = constrain(inches, sensorMin, sensorMax); //make sure inches stays between min and max
 
  //int sensorReading = inches;
 
    //////////////////////////////////////      SMOOTHING Averaging Formulas   //////////////////
  // subtract the last reading:
  total= total - readings[index];         
  // read from the sensor: 
  readings[index] = inches;
  // add the reading to the total:
  total= total + readings[index];       
  // advance to the next position in the array: 
  index = index + 1;                   

  // if we're at the end of the array...
  if (index >= numReadings)             
    // ...wrap around to the beginning:
    index = 0;                           

  // calculate the average:
  average = total / numReadings;         
  // send it to the computer (as ASCII digits)

////////////////////////////////////////////////////////////////////////////////////////////////////////
 
  // map the sensor range to a range of four options:
  int range = map(inches, sensorMin, sensorMax, 0, 10);

  // do something different depending on the
  // range value:
  switch (range) {

  case 0:    // your hand is on the sensor
    playfile("play1.WAV");
    delay(2000);      //////all delays are adjustable, they help keep settle flicker between zones
                      //////or can allow for zone "on" overlaps
    break;
  case 1:    // your hand is close to the sensor
   playfile("play2.WAV");
    delay(2000);
    break;
  case 2:   
   playfile("play3.WAV");
    delay(2000);
    break;
  case 3: 
   playfile("play4.WAV");
    delay(2000);
    break;
  case 4:   
   playfile("play5.WAV");
    delay(2000);
    break;
  case 5:   
   playfile("play6.WAV");
    delay(2000);
    break;
  case 6: 
   playfile("play7.WAV");
    delay(2000);
    break;
  case 7:   
   playfile("play8.WAV");
    delay(2000);
    break;
  case 8:   
   playfile("play9.WAV");
    delay(2000);
    break;
  case 9: 
   playfile("play10.WAV");
    delay(2000);
    break;

  }



}

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


//STOP PLAYER
void playfile(char *name) {
  // stop any file already playing
  if (wave.isplaying) {
    wave.stop();
  }
  // close file if open
  if (f) {
    card.close_file(f);
  }
  // play specified file
  f = card.open_file(name);
  if (f && wave.create(f)) {
    wave.play();
  }
}
monolyth221
 
Posts: 6
Joined: Sat Feb 06, 2010 12:42 am

Re: waveshield + ping

by dy-wen on Wed May 12, 2010 12:20 pm

sorry - my coding is too scruffy to solve your problem - I got help from code friends ....
:oops:
Don't give up - I also got help on the Arduino forum...
dy-wen
 
Posts: 30
Joined: Wed Sep 16, 2009 11:31 am

Re: waveshield + ping

by nsylianteng on Sat Jan 26, 2013 10:45 am

Did this ever get resolved? I'm trying to do something similar. I'm making a 3 foot dome, and attaching the ping sensor to the perimeter on the inside of the dome. I want it to start playing the sound file when the dome gets lowered over someone's head.
nsylianteng
 
Posts: 16
Joined: Sun Dec 16, 2012 11:19 am

Re: waveshield + ping

by xl97 on Wed Jan 30, 2013 3:37 pm

I dont think AF_Wave lib is used/suported anymore.. the newer WaveHC and WaveRP are the latest I believe..

also.. I would work on getting the PING sensor working the way you want.. maybe triggering an LED or something for now.. make sue its dialed in and works when/how you want..

after that.. implementing the WaveHC code and trigger a file to play should be easy...
xl97
 
Posts: 144
Joined: Mon Jul 27, 2009 12:51 pm