Go Down

Topic: Object Avoidance with Ping))) sensor (Read 4808 times) previous topic - next topic

tyman

ok when i use this code the sensors read great but the bot just sits there and goes back and forth like the motors are confused



Code: [Select]
#define ping2pin      8      // left sensor
#define pingPin       9      // forward Ping ultrasonic sensor on pin D9.
#define leftDir1      7      // Left motor direction 1, to AIn1.+
#define leftDir2      6      // Left motor direction 2, to AIn2.-
#define rightDir1     5      // Right motor direction 1, to BIn1.+
#define rightDir2     4      // Right motor direction 2, to BIn2.-

#define BOUNDARY     20      // (cm) Avoid objects closer than 20cm.
#define INTERVAL     25      // (ms) Interval between distance readings.

// setup
// Set motor pins as OUTPUTS, initialize Serial

void setup()                                                 
{
  pinMode(leftDir1, OUTPUT);        // Set motor direction pins as outputs.
  pinMode(leftDir2, OUTPUT);     
  pinMode(rightDir1, OUTPUT);     
  pinMode(rightDir2, OUTPUT);
  Serial.begin(9600);
}


// Main program
// Roam around while avoiding objects.
//
// Set motors to move forward,
// Take distance readings over and over,
// as long as no objects are too close (determined by BOUNDARY).
// If object is too close, avoid it -- back up and turn.
// Repeat.

void loop()                     
{
  long xdistance;                    // Distance reading from rangefinder.
  long ydistance;
  forward();                        // Robot moves forward continuously.
  do
  {
    xdistance = readxDistance();      // Take a distance reading.
    Serial.println(xdistance);       // Print it out.             
    delay(INTERVAL);                // Delay between readings.
    ydistance = readydistance();
    Serial.println(ydistance);
    delay(INTERVAL);
   
  }
  while (((xdistance = readxDistance()) >= BOUNDARY) &&
                                      ((ydistance = readydistance()) >= BOUNDARY));
   
 
       // Loop while no objects close-by.

  // Robot has sensed a nearby object and exited the while loop.
  // Take evasive action to avoid object.

  leftTurn(300);                   // Turn left 300ms.

} // end Main program


// forward
//
// Move robot forward by setting both wheels forward.
// Will persist until something else changes the
// motors' directions.

void forward()
{
  digitalWrite(leftDir1, LOW);      // Left motor forward.             
  digitalWrite(leftDir2, HIGH);
  digitalWrite(rightDir1, LOW);     // Right motor forward.
  digitalWrite(rightDir2, HIGH);



// backward
//
// Move robot backward by setting both wheels backward.
// Will persist until something else changes the
// motors' directions.

void backward()
{
  digitalWrite(leftDir1, HIGH);     // Left motor backward.
  digitalWrite(leftDir2, LOW);
  digitalWrite(rightDir1, HIGH);    // Right motor backward.
  digitalWrite(rightDir2, LOW);
}


// leftTurn
//
// Turn robot to left by moving wheels in opposite directions.
// Amount of turning is determined by duration argument (ms).

void leftTurn(int duration)
{
  digitalWrite(leftDir1, HIGH);     // Left motor backward.
  digitalWrite(leftDir2, LOW);
  digitalWrite(rightDir1, LOW);     // Right motor forward.
  digitalWrite(rightDir2, HIGH);
  delay(duration);                  // Turning time (ms).
}


// readDistance
// Take a distance reading from Ping ultrasonic rangefinder.
// from http://arduino.cc/en/Tutorial/Ping?from=Tutorial.UltrasoundSensor






long readxDistance()
{
  long duration, inches, cm;

  // The Ping is triggered by a HIGH pulse of 2 or more microseconds.
  // We 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 an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  // Convert the time into a distance.
  cm = microsecondsToCentimeters(duration);
  return(cm);
}

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 traveled.
  return microseconds / 29 / 2;
}
long readydistance()
{
  long duration, inches, cm;  //left sensor variable

  // The Ping is triggered by a HIGH pulse of 2 or more microseconds.
  // We give a short LOW pulse beforehand to ensure a clean HIGH pulse.
  pinMode(ping2pin, OUTPUT);
  digitalWrite(ping2pin, LOW);
  delayMicroseconds(2);
  digitalWrite(ping2pin, HIGH);
  delayMicroseconds(5);
  digitalWrite(ping2pin, 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 an object.
  pinMode(ping2pin, INPUT);
  duration = pulseIn(ping2pin, HIGH);

  // Convert the time into a distance.
  cm = microsecondsToCentimeters(duration);
  return(cm);
}


AWOL

You're now reading the sensors twice in your do..while.
Either read them once in the body of the loop and test at the end, or turn it into a proper "while" loop like I described, and test at the top of the loop.

Quote
but the bot just sits there and goes back and forth

Which? It sits there, or it goes back and forth?

Remember you are are eyes on this - we can't see what's happening.
You need better descriptions - time, direction etc.
"Pete, it's a fool 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.

tyman

ok i will try to do better when i put it in the way you described it bounces back and forth first forward then back but im only talking about like .25 sec forward then .25 sec back so rely just like bouncing when i look at the serial monitor it is reading distance very whell.

AWOL

Can you put a
Code: [Select]
Serial.println ("Starting"); after "Serial.begin();" in "setup()".

I can't see anything that would make it go back and forth.
How are you powering all of this?
"Pete, it's a fool 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.

tyman

#34
May 10, 2011, 04:36 pm Last Edit: May 10, 2011, 04:39 pm by tyman Reason: 1
ok i put it in and i also noticed that it bounces back and forth like i was talking about when both sensors are farther than boundary away once one or both sensors see something closer than boundary it just goes forward for .25 sec then pause for .25 sec and repeats as long as something is in the boundary.

oh ya by the way im using a AA battery pack with 4 batteries

AWOL

Does it keep printing "Starting", or is it just there once?
(you haven't answered my question about power)
"Pete, it's a fool 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.

tyman

it only prints 'starting' once.    and four double a betteries

AWOL

I would put the robot up on blocks, and just check that all your motor moves are correct.
Forget the pings, just put a sequence into "loop", something like "forward for five seconds, left turn five seconds, right turn five seconds, reverse five seconds".
Check the wheels move as expaected.

Remember that this will loop, so maybe put print statements at the start of each change of direction so you know where the bot thinks it is up to.
"Pete, it's a fool 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.

tyman

ok i will try to figure out the code for that then i will test it out.

tyman

i used a sample code to run the bot on hyper terminal and the wheels move the right direction with that code

Code: [Select]
int E1 = 6; //M1 Speed Control
int E2 = 5; //M2 Speed Control
int M1 = 8; //M1 Direction Control
int M2 = 7; //M2 Direction Control
void setup(void)
}
  int i;
  for(i=5;i<=8;i++)
  pinMode(i, OUTPUT);
  Serial.begin(9600);
{
void loop(void)
}
  while (Serial.available() < 1) {} // Wait until a character is received
  char val = Serial.read();
  int leftspeed = 255;  //255 is maximum speed 
  int rightspeed = 255;
  switch(val) // Perform an action depending on the command

  case 'w'://Move Forward
    forward (leftspeed,rightspeed);
    break;
  case 's'://Move Backwards
    reverse (leftspeed,rightspeed);
    break;
  case 'a'://Turn Left
    left (leftspeed,rightspeed);
    break;
  case 'd'://Turn Right
    right (leftspeed,rightspeed);
    break;
  default:
    stop();
    break;
   { 
{
void stop(void) //Stop
}
  digitalWrite(E1,LOW);
  digitalWrite(E2,LOW);
{
void forward(char a,char b)
}
  analogWrite (E1,a);
  digitalWrite(M1,LOW);
  analogWrite (E2,b);
  digitalWrite(M2,LOW);
{
void reverse (char a,char b)
}
  analogWrite (E1,a);
  digitalWrite(M1,HIGH);
  analogWrite (E2,b);
  digitalWrite(M2,HIGH);
{
void left (char a,char b)
}
  analogWrite (E1,a);
  digitalWrite(M1,HIGH);
  analogWrite (E2,b);
  digitalWrite(M2,LOW);
{
void right (char a,char b)
}
  analogWrite (E1,a);
  digitalWrite(M1,LOW);
  analogWrite (E2,b);
  digitalWrite(M2,HIGH);
{

tyman

ok so i have been working on the code and have had some success my bot will now go forward until something is seen by either the left or front sensor as being closer than 20 cm once it sees an object it turns left now i am having trouble figuring out how to add in more variables as far as i want to tell it that if x < BOUNDARY and y > BOUNDARY then turn left but if x < BOUNDARY and y < BOUNDARY then stop and turn right i just don't know how to add onto the loop.  any way here is the code i am using now.





Code: [Select]
#define ping2pin      10      // left sensor
#define pingPin       9      // forward Ping ultrasonic sensor on pin D9.
#define leftDir1      8      // Left motor direction 1, to AIn1.
#define leftDir2      7      // Left motor direction 2, to AIn2.
#define rightDir1     6      // Right motor direction 1, to BIn1.
#define rightDir2     5     // Right motor direction 2, to BIn2.

#define BOUNDARY     20      // (cm) Avoid objects closer than 20cm.
#define INTERVAL     25      // (ms) Interval between distance readings.

// setup
// Set motor pins as OUTPUTS, initialize Serial

void setup()                                                 
{
  pinMode(leftDir1, OUTPUT);        // Set motor direction pins as outputs.
  pinMode(leftDir2, OUTPUT);     
  pinMode(rightDir1, OUTPUT);     
  pinMode(rightDir2, OUTPUT);
  Serial.begin(9600);
}


// Main program
// Roam around while avoiding objects.
//
// Set motors to move forward,
// Take distance readings over and over,
// as long as no objects are too close (determined by BOUNDARY).
// If object is too close, avoid it -- back up and turn.
// Repeat.

void loop()                     
{
  long xdistance;                    // Distance reading from rangefinder.
  long ydistance;
  forward();                        // Robot moves forward continuously.
  do
  {
    xdistance = readxDistance();      // Take a distance reading.
    Serial.println(xdistance);       // Print it out.             
    delay(INTERVAL);                // Delay between readings.
    ydistance = readyDistance();      // Take a distance reading.
    Serial.println(ydistance);       // Print it out.             
    delay(INTERVAL);                // Delay between readings.
  }
  while((xdistance >= BOUNDARY)&&(ydistance >= BOUNDARY));      // Loop while no objects close-by.

  // Robot has sensed a nearby object and exited the while loop.
  // Take evasive action to avoid object.         
// backward();                       // Move backward 500ms.
  //delay(3000);               
  leftTurn(3000);                   // Turn right 300ms.

} // end Main program


// forward
//
// Move robot forward by setting both wheels forward.
// Will persist until something else changes the
// motors' directions.

void forward()
{
  digitalWrite(leftDir1, LOW);      //             
  digitalWrite(leftDir2, LOW);
  digitalWrite(rightDir1, HIGH);     // LEFT motor forward.
  digitalWrite(rightDir2, HIGH);     // RIGHT MOTOR FORWARD.



// backward
//
// Move robot backward by setting both wheels backward.
// Will persist until something else changes the
// motors' directions.

void backward()
{
  digitalWrite(leftDir1, HIGH);     // Left motor backward.
  digitalWrite(leftDir2, HIGH);
  digitalWrite(rightDir1, LOW);    // Right motor backward.
  digitalWrite(rightDir2, LOW);
}


// leftTurn
//
// Turn robot to left by moving wheels in opposite directions.
// Amount of turning is determined by duration argument (ms).

void leftTurn(int duration)
{
  digitalWrite(leftDir1, HIGH);     // Left motor backward.
  digitalWrite(leftDir2, LOW);
  digitalWrite(rightDir1, HIGH);     // Right motor forward.
  digitalWrite(rightDir2, HIGH);
  delay(duration);                  // Turning time (ms).
}


// readDistance
// Take a distance reading from Ping ultrasonic rangefinder.
// from http://arduino.cc/en/Tutorial/Ping?from=Tutorial.UltrasoundSensor

long readxDistance()
{
  long duration, inches, cm;

  // The Ping is triggered by a HIGH pulse of 2 or more microseconds.
  // We 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 an object.
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  // Convert the time into a distance.
  cm = microsecondsToCentimeters(duration);
  return(cm);
}

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 traveled.
  return microseconds / 29 / 2;
}
long readyDistance()
{
  long duration, inches, cm;  //left sensor variable

  // The Ping is triggered by a HIGH pulse of 2 or more microseconds.
  // We give a short LOW pulse beforehand to ensure a clean HIGH pulse.
  pinMode(ping2pin, OUTPUT);
  digitalWrite(ping2pin, LOW);
  delayMicroseconds(2);
  digitalWrite(ping2pin, HIGH);
  delayMicroseconds(5);
  digitalWrite(ping2pin, 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 an object.
  pinMode(ping2pin, INPUT);
  duration = pulseIn(ping2pin, HIGH);

  // Convert the time into a distance.
  cm = microsecondsToCentimeters(duration);
  return(cm);
}


AWOL

Quote
i am having trouble figuring out how to add in more variables

It's conditions you need,not variables, surely?
"Pete, it's a fool 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.

tyman

ok but i am confused about how to construct a condition.

Go Up