Need help with 2 rangefinder and waveshield....

Arduino rocks

Posts: 3

2 rangefinder, with waveshield, help!!
Today at 12:00:37 | Modify | Remove
Hey there,

I need help with 2 of my ultrasonic sensors( rangefinder),

I try to calculating the time and the output will be the sound from my Wavesheild.

I got this code here,

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

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

WaveHC wave;      // This is the only wave (audio) object, since we will only play one at a time

// Function definitions (we define them here, but the code is below)

int S1 = 0;
int S2 = 0;

int state1 = 0;
int state2 = 0;
int alreadyStarted = 0;
float startTime = 0;
float stopTime = 0;
float timePassed = 0;
void lsR(FatReader &d);
void play(FatReader &dir);
int testVar =30;
int testVar2 =30;

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

 // 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);
 //  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
   while(1);                            // then 'halt' - do nothing!
 // enable optimize read - some cards may timeout. Disable if you're having problems
 // 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  Sad
   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("Files found:");
 dirLevel = 0;
 // Print out all of the files in all the directories.

//////////////////////////////////// LOOP
void loop() {

Serial.println(S1); // Read the analog value
Serial.println(("       "));
Serial.println(S2); // Read the analog value
delay (500);
 S1 = analogRead(0);
 if( S1 < testVar)  // <---- activation number here
   state1 = 1;
 S2 = analogRead(1);
 if( S2 < testVar2)
   state2 = 1;
 if( (state1 == 1 && state2 == 0) || (state1 == 0 && state2 == 1) )
   if(alreadyStarted == 0)
     startTime = millis();
   alreadyStarted = 1;
 if( state1 == 1 && state2 == 1 ){
   stopTime = millis();
   timePassed = (stopTime - startTime); // in seconds
   //velocity = distance / timePassed;
   if(timePassed > 3000 )
   if(timePassed < 3000 )
  int state1 = 0;
  int state2 = 0;
  int stopTime = 0;
  int startTime = 0;
  int alreadyStarted = 0;

/////////////////////////////////// HELPERS

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

* print error message and halt if SD I/O error, great for debugging!
void sdErrorCheck(void)
 if (!card.errorCode()) return;
 putstring("\n\rSD I/O error: ");
 Serial.print(card.errorCode(), HEX);
 putstring(", ");
 Serial.println(card.errorData(), HEX);
* print dir_t name field. The output is 8.3 format, so like SOUND.WAV or FILENAME.DAT
void printName(dir_t &dir)
 for (uint8_t i = 0; i < 11; i++) {     // 8.3 format has 8+3 = 11 letters in it
   if ([i] == ' ')
       continue;         // dont print any spaces in the name
   if (i == 8)
       Serial.print('.');           // after the 8th letter, place a dot
   Serial.print([i]);      // print the n'th digit
 if (DIR_IS_SUBDIR(dir))
   Serial.print('/');       // directories get a / at the end
* list recursively - possible stack overflow if subdirectories too nested
void lsR(FatReader &d)
 int8_t r;                     // indicates the level of recursion
 while ((r = d.readDir(dirBuf)) > 0) {     // read the next file in the directory
   // skip subdirs . and ..
   if ([0] == '.')
   for (uint8_t i = 0; i < dirLevel; i++)
     Serial.print(' ');        // this is for prettyprinting, put spaces in front
   printName(dirBuf);          // print the name of the file we just found
   Serial.println();           // and a new line
   if (DIR_IS_SUBDIR(dirBuf)) {   // we will recurse on any direcory
     FatReader s;                 // make a new directory object to hold information
     dirLevel += 2;               // indent 2 spaces for future prints
     if (, dirBuf))
       lsR(s);                    // list all the files in this directory now!
     dirLevel -=2;                // remove the extra indentation
 sdErrorCheck();                  // are we doign OK?

void playcomplete(char *name) {
 while (wave.isplaying);

void playfile(char *name) {
 if (wave.isplaying) {// already playing something, so stop it!
   wave.stop(); // stop it
 if (!, name)) {
   putstring("Couldn't open file "); Serial.print(name); return;
 if (!wave.create(f)) {
   putstring_nl("Not a valid WAV"); return;
 // ok time to play!;

Form the code above, I set the ultrasonic range like, if it below than 30, its then start calculating time from the first 1 to the second 1.

If any1 could help I will be really appreciate.

A few points: Cross posting three times isn't helpful. Please use the Code (#) button when posting code.

It would be useful to break down your problem into two or more simpler parts and test them separately.

Write simpler sketches to do your ranging, and indicate the result with prints or blinking LED. Then get your wave stuff working in response to a simple trigger, like a character received over the serial, or a button press.

It is possible, but unlikely that anyone else has exactly the same setup as you, so simply posting a block of code isn't likely to yield results, unless you've got some gross errors.

apologize about posting it 3 time

I am a newbie at this webboard and arduino,

from my code is there anyway to test if my "If" statement are running?

Thanks for your replies

I'm going to presume that your problem is not with reading from the SD card. That is, no errors are printed during setup.

In loop, you start by printing S1 and S2, and then you assign values to S1 and S2. It would certainly be more useful to assign values first, and then print them.

This test:

if( (state1 == 1 && state2 == 0) || (state1 == 0 && state2 == 1) )

could be changed to this:

if(state1 != state2)

This code:

 int state1 = 0;
 int state2 = 0;
 int stopTime = 0;
 int startTime = 0;
 int alreadyStarted = 0;

at the end of the loop function declares some local variables with the same names as the global variables, and assigns them some values.

These local variables never get used, since loop ends immediately after this code.

Assigning values to the local variables has no impact on the global variable of the same name.

You only play a song if state1 and state2 are 1, which happens only if both sensors return small values, and timePassed is less than 3000. Is that what you intended to do?

By the way, this comment:

timePassed = (stopTime - startTime); // in seconds

is wrong. The timePassed variable will contain a duration in milliseconds (1/1000 of a second).

Finally, what is the problem? Does the song not play when you intended it to? Does the wrong song play? Is the tempo too slow? Does only part of the song play? Is the volume too loud?

What part of the program do you need help with?

thanks for the reply PaulS

I'm a newbie here and I certainly donot know any arduino programming I try to use two ultrasonic sensors for my final project.

The problem is that the song isn't playing

I don't know either the codes are wrong or ...

As I said, the song is only supposed to play when both sensors return small values and the elapsed time is less than 3 seconds.

If you haven't moved the Serial.print statements after the digitalRead statements, you don't know what values are being returned by the sensors. So, you don't know if they are both small values or both large values, or one large and one small.

You can add Serial.print statements in a number of places. Print out when startTime is set, so that you know that startTime IS being set.

Print state1 and state2 so that you know they are being set correctly.

Print timePassed. That should give you an idea about how long it takes for both sensors to produce small values, if ever.

Think about how you have the sensors positioned. Is it possible for both to produce small values at the same time?

For our benefit, not having seen your hardware setup, how about providing a better description of the setup.

two ultrasonic sensors will put on two of my prototype Two of my prototype will be set up on the stair where alot of people are walking

1 will be on top of the stair another 1 will 1.5 metre away from it.

If a person pass one of the sensor form any direction it then start the timing when he reach the second sensor it then stop the timing.

if the time is less or more than 3 seconds it then play a sound from my SD card

Is this enough information for you?


If there are a lot of people, how do you know that the two sensors are responding to the same person?

Presuming that there is something in the environment that controls this, there is another problem.

If sensor 1 is measuring the distance to one person, and detects that a person is close, sensor 2 will not detect that the same person is close.

When sensor 2 detects that the person is close, sensor 1 will not detect that the person is close.

Since you only play the song when both sensors detect that the person is close, and got close within 3 seconds, I don't see that it is physically possible to ever play the song.

Perhaps the ultrasonic sensors are not the right kind of sensors to use, or perhaps you need to change the logic of when to play the song.

Perhaps something like this:

If sensor 1 or sensor 2 returns a small value, a person is near. Record the time and the sensor that returned the small value (that is, which sensor the person was near.

If sensor 1 returns a small value and the previous sensor was 2, record the time, compute the duration, and play, or not, the song.

Else, if sensor 2 returns a small value and the previous sensor was 1, record the time, compute the duration, and play, or not, the song.

This allows the person to pass the sensors going in either direction.

It still presumes that the sensors can only detect one person at a time.

Oh ok sob

can you help me create a formula?

I need to get it working these are for my master projects,USYD Australia

I just need to play sound when the values of my ultrasonic sensors are below than 50 and time of it less or greater than 2seconds

I already think that it wouldnt work if there are alot of people but anyway I need to get it working just for 1 person. The stair that i will put my prototype in aren't that wide

thanks for your help anyway

This should be a reasonable starting point:

int lowSensor = 0;
int sensor1;
int sensor2;
int started = 0;

int s1Pin = 11; // Change these to match the pins
int s2Pin = 12; // the sensors are connected to

int close = 50;
int fast = 2000;

unsigned long start, stop, time;

void loop()
   sensor1 = analogRead(s1Pin);
   sensor2 = analogRead(s2Pin);

   if(started == 0) // Neither sensor has been triggered
      if(sensor1 < close) // Person is near 1st sensor
         start = millis(); // Record start time
         lowSensor = 1; // Record triggering sensor
         started = 1;     // Record the fact that a sensor was triggered

      if(sensor2 < close) // Person is near 2nd sensor
         start = millis();
         lowSensor = 2;
         started = 1;
   else // one of the sensors was triggered
      // Make sure person didn't turn around
      // That is, make sure the person is now
      // passing the other sensor
      if(sensor1 < close && lowSensor == 2)
         stop = millis(); // Record end time
         started = 0;     // Set up to wait for the next person
         time = stop - start; // Compute the duration
         if(time < fast) // They were really moving...
            // play the file here

      // Handle the case of the person going the other way
      if(sensor2 < close && lowSensor == 1)
         stop = millis(); // Record end time
         started = 0;     // Set up to wait for the next person
         time = stop - start; // Compute the duration
         if(time < fast) // They were really moving...
            // play the file here

I haven’t tested this, because I don’t have any ultrasonic sensors, nor do I have a wave shield. If there are problems, the comments should help you figure what is supposed to be happening.

Thanks PaulS,

I will try this and see if it works