programming help

Hi guys ! i was writing a program for an obstacle avoiding code and came across a peculiar bit of problem.

so the problem here is that the pan servo moves from 90 to 180 (right) then to 0 (left) delays according to the program then it comes at 90 and even though there is no obstacle again turns from right to left and this time stops at left and repeats the whole process again.

here’s a copy of the program

any ideas as to why this happens?? thanks

#include <Servo.h> //include Servo library

const int RForward = 0; 
const int RBackward = 180; 
const int LForward =  RBackward; 
const int LBackward = RForward; 
const int RNeutral = 90; 
const int LNeutral = 90; //constants for motor speed

const int trigPin = 12;
const int echoPin = 13;  //Sharp infrared sensor pin
const int dangerThresh = 10; //threshold for obstacles (in cm)
int leftDistance, rightDistance; //distances on either side
Servo panMotor;  
Servo leftMotor;
Servo rightMotor; //declare motors
long duration; //time it takes to recieve PING))) signal

void setup()
{
  rightMotor.attach(10);
  leftMotor.attach(9);
  panMotor.attach(6); //attach motors to proper pins
  panMotor.write(90); //SENSOR TO CENTER 
  pinMode(trigPin, OUTPUT);// set the trig pin to output (Send sound waves)
  pinMode(echoPin, INPUT);// set the echo pin to input (recieve sound waves)
}

void loop()
{
  int distanceFwd = distance();
  if (distanceFwd>dangerThresh) //if path is clear
  {
    leftMotor.write(LForward); 
    rightMotor.write(RForward); //move forward
  }
  else //if path is blocked
  {
    leftMotor.write(LNeutral);
    rightMotor.write(RNeutral); 
    panMotor.write(0); 
    delay(500);
    rightDistance = distance(); //scan to the right
    delay(500);
    panMotor.write(180);
    delay(500);
    leftDistance = distance(); //scan to the left
    delay(500);
    panMotor.write(90); //return to center
    delay(100);
    compareDistance();
  }
}
  
void compareDistance()
{
  if (leftDistance>rightDistance) //if left is less obstructed 
  {
    leftMotor.write(LBackward); 
    rightMotor.write(RForward); //turn left
    delay(500); 
  }
  else if (rightDistance>leftDistance) //if right is less obstructed
  {
    leftMotor.write(LForward);
    rightMotor.write(RBackward); //turn right
    delay(500);
  }
   else //if they are equally obstructed
  {
    leftMotor.write(180); 
    rightMotor.write(180); //turn 180 degrees
    delay(1000);
  }
}

long distance()
{
  // Send out PING))) signal pulse
   long duration, distance; // start the scan
    
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);;

   return duration / 29 / 2;
}

Why does the distance() function return a long that you store in an int?

What value does distance() return, that you store in distanceFwd?

because long is 32 bit and distance() returns the distance from the obstacle

robot_geek:
because long is 32 bit and distance() returns the distance from the obstacle

That does not explain why you then store the long in an int.

You really do need to pay attention to details like that. You also need to determine if your sensor really can measure a distance that exceeds 32767 centimeters.

That is, should the function really return a long?

We still don’t know whether the sensor is returning ANY meaningful value, regardless of whether the value is an int, a long, or a blueberry cheesecake.

You need to add some Serial.print() statements into your program so you can see what values the sensors are giving.

You have a lot of delay()s in your program and that is usually not suitable in any program that needs to be responsive. The Arduino can do nothing useful during a delay(). Have a look at how millis() is used to manage timing without blocking in Several things at a time

...R

well i'm using a HC-SRF04 so it can measure a distance that exceeds 32767 centimeters.

also i used this site http://www.instructables.com/id/How-To-Make-an-Obstacle-Avoiding-Arduino-Robot/ as a reference and it used a "long"

but i still cant understand why the pan servo moves right to left even though there isn't any obstacle..... also it tends to stop at right for longer than the delay

any ideas ?

PaulS: What value does distance() return, that you store in distanceFwd?

Yes, it is always worth reading the documentation for functions that you use:

Returns

the length of the pulse (in microseconds) or 0 if no pulse is completed before the timeout (unsigned long)

the thing that bothers me the most is that this sae program worked well a couple weeks ago and today it causes problems

well i'm using a HC-SRF04 so it can measure a distance that exceeds 32767 centimeters.

?

AWOL: ?

it seemed to work a couple of days ago !!

robot_geek: the thing that bothers me the most is that this sae program worked well a couple weeks ago and today it causes problems

Life is tough, eh?

You need to handle the case where no pulse is returned and therefore the existing code will return a zero distance. And as pointed out, if things are not working properly then write some debug statements to serial and test while connected to your PC.

robot_geek: it seemed to work a couple of days ago !!

Do you know how FAR 32 metres is?

arduarn: Life is tough, eh?

You need to handle the case where no pulse is returned and therefore the existing code will return a zero distance. And as pointed out, if things are not working properly then write some debug statements to serial and test while connected to your PC.

so um how do i handle a case where no pulse is returned

robot_geek: so um how do i handle a case where no pulse is returned

However you want, but you need to handle it. The easiest way is perhaps to return a maximum value of int 32767, or unsigned int 65535 (after having changed the function to return an int or unsigned int, as mentioned by PaulS).

here's the code for the distance

long distance()
{
  // Send out PING))) signal pulse
   long duration, distance; // start the scan
    
  digitalWrite(trigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2)/29;
}

is it okay ?

is it okay ?

You promised the compiler that you would return a value, but didn't. So, that's no, it's not OK

also where should i add Serial.print() statements ?

robot_geek: also where should i add Serial.print() statements ?

Wherever you need to know something that isn't obvious.

robot_geek:
here’s the code for the distance

long distance()

{
 // Send out PING))) signal pulse
  long duration, distance; // start the scan
   
 digitalWrite(trigPin, LOW);
 delayMicroseconds(2);
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(10);
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 distance = (duration/2)/29;
}




is it okay ?

I don’t think you are understanding me, so I’ll try again.

Your sensor has a maximum range under optimal conditions of 400cm according to this search result.
If there is no obstacle within that range, or if the sound is reflected some other direction, or if it is absorbed by a sofa cushion, or whatever, then your original distance function returned 0.
Then in the loop() you have if (distanceFwd>dangerThresh); which therefore makes if (0>10).
In other words, even though you have open space in front of the sensor, you think there is an obstacle stuck right between your eyes.

robot_geek:
also where should i add Serial.print() statements ?

Print the value of distanceFwd for starters. You need to have a little bit of initiative for this programming lark too; use your imagination.

examples from the code ??