Go Down

Topic: Need help with 2 rangefinder and waveshield.... (Read 2312 times) previous topic - next topic

gapza_v

Nov 08, 2009, 12:14 pm Last Edit: Nov 08, 2009, 02:18 pm by gapza_v Reason: 1

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,



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;

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
Serial.println(freeRam());  

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

//////////////////////////////////// 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 )
  {
 
    //playcomplete("happy.WAV");
   
  }
  if(timePassed < 3000 )
   playcomplete("fast.WAV");
 
 
 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);
while(1);
}
/*
* 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 (dir.name[i] == ' ')
      continue;         // dont print any spaces in the name
  if (i == 8)
      Serial.print('.');           // after the 8th letter, place a dot
  Serial.print(dir.name[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 (dirBuf.name[0] == '.')
    continue;
 
  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 (s.open(vol, 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) {
playfile(name);
while (wave.isplaying);
}

void playfile(char *name) {
if (wave.isplaying) {// already playing something, so stop it!
  wave.stop(); // stop it
}
if (!f.open(root, 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!
wave.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.




AWOL

#1
Nov 08, 2009, 12:59 pm Last Edit: Nov 08, 2009, 01:26 pm by AWOL Reason: 1
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.

"Pete, it's a fool (who) looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.
I speak for myself, not Arduino.

gapza_v

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

PaulS

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:
Code: [Select]
if( (state1 == 1 && state2 == 0) || (state1 == 0 && state2 == 1) )

could be changed to this:
Code: [Select]
if(state1 != state2)

This code:
Code: [Select]
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:
Code: [Select]
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?
The art of getting good answers lies in asking good questions.

gapza_v

#4
Nov 08, 2009, 02:23 pm Last Edit: Nov 08, 2009, 02:24 pm by gapza_v Reason: 1

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 ...

PaulS

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.
The art of getting good answers lies in asking good questions.

gapza_v

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?

Thanks

PaulS

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:

Quote
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.
The art of getting good answers lies in asking good questions.

gapza_v

#8
Nov 08, 2009, 03:26 pm Last Edit: Nov 08, 2009, 03:30 pm by gapza_v Reason: 1
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

PaulS

This should be a reasonable starting point:

Code: [Select]
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.
The art of getting good answers lies in asking good questions.

gapza_v

Thanks PaulS,

I will try this and see if it works

Go Up