I'm having trouble with the programming for an obstacle avoiding robot

Hello,
I'm currently working on an obstacle avoiding robot using an Arduino Uno. The robot is built and I though I had the programming correct, but it has to drive wheels which are continuous rotation servos. Everything seems to be working fine, until it's supposed to go in a straight line, then one servo will spin in one direction and the other will spin in the other direction, making it just do circles.

Here is the code:

#include  //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 pingPin = 7;
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(11);
  leftMotor.attach(10);
  panMotor.attach(6);  //attach motors to proper pins
  panMotor.write(90);  //set PING))) pan to center
}

void loop() {
  int distanceFwd = ping();
  if (distanceFwd > dangerThresh)  //if path is clear
  {
    leftMotor.write(LForward);
    rightMotor.write(RForward);  //move forward
    delay(100);
  } else  //if path is blocked
  {
    leftMotor.write(LNeutral);
    rightMotor.write(RNeutral);
    panMotor.write(0);
    delay(500);
    rightDistance = ping();  //scan to the right
    delay(500);
    panMotor.write(180);
    delay(700);
    leftDistance = ping();  //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(LForward);
    rightMotor.write(RBackward);  //turn 180 degrees
    delay(1000);
  }
}

long ping() {
  // Send out PING))) signal pulse
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);

  //Get duration it takes to receive echo
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);

  //Convert duration into distance
  return duration / 29 / 2;
}

I've tried to do my best with showing this code. As far as I knew, I had to highlight it all and then click the button, which I did. So hopefully that's all good.

The right side continuous rotation server (right side as you're in the vehicle) is connected to pin 10.

The left side continuous rotation server is connected to pin 11

The pan motor servor (which the PING sensor is attached to) is connected to pin 6

The PING sensor is connected to pin 7

I don't know if this will help, but I've included a very shrewd representation of the connection;

I'm trying my best to make this as apporpritate for this forum as possible. If I've made any mistakes, please just let me know and I will try to fix it.

The main thing I'm looking for is to see if anyone can look at the code and see why both of the continuous servos would be operating in differnt directions when they're supposed to be going straight.

Hmmmm. I can see NO attempt you have made to debug your program. I am looking for places where you have serial.Print() the variable values used in your logic, but do not see any such code.
Best to try to debug your own program before asking someone else to do it, don;t you think?

If it came across as me trying to get others to do my work for me, I apologize. That was not the intent. I'm very new to this so there is a lot I don't know and I'm trying to teach myself. So I'm only trying to get helpful suggestions about the correct course to take.

The only method of debugging I know is to click on the "verify" tab. When I do that I get the message:

Exit status 1
Compilation error: #include expects "FILENAME" or .

So now I have two questions, if you don't mind answering them. What does the above error mean.

My second questions is when you stated "I am looking for places where you have serial.Print() the variable values used in your logic, but do not see any such code"

What do you mean by that and what can I do to remedy that?

Welcome to our forum.
Thank you for posting your code properly. Good job.

Continuous servos use the servo signal to control the speed and direction of a gear motor. Ideally a pulse duration of 1500us (90 degrees) will stop the servo, a pulse width of 2000us (180 degrees) will make the motor rotate forward at full speed and a pulse width of 1000us (0 degrees) will make the motor rotate backward at full speed.

Most servos will have a stop number near 1500us (90 degrees) but not exactly. Usually one will need to find the number (near 1500us or 90 degrees) that stops the servo by experimentation.

So to have the motors drive a robot one motor must rotate forward and the other in reverse as one is mirrored by the one on the other side. A way to do that is to have a speed variable add that to the right motor stop number and subtract from the left motor stop number.

So, something like:

speed = 50;
rightServo.write(rightStopNumber + speed);
leftServo.write(leftStopNumber - speed);

If you use the include keyword the compiler expects that something be included. In the case where you are using servos, you need to include the Servo library.

#include <Servo.h>

The best debugging tool that you have is the serial print. Insert serial prints in the code to monitor program execution and variable values to see if things are happening as you expect.

To do that you need to open the serial port. In the setup() function open the port with:
Serial.begin(115200);

Then insert some serial prints with labels.

I inserted a few to illustrate. See the // ********************



#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 pingPin = 7;
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()
{
   // open the serial port
   Serial.begin(115200); // ********************************
   
   rightMotor.attach(11);
   leftMotor.attach(10);
   panMotor.attach(6);  //attach motors to proper pins
   panMotor.write(90);  //set PING))) pan to center
}

void loop()
{
   int distanceFwd = ping();
   Serial.print("distance is ");  // print the distance with a label
   Serial.println(distanceFwd); // ********************************
   if (distanceFwd > dangerThresh)  //if path is clear
   {
      Serial.println("Moving forward"); // ************************
      leftMotor.write(LForward);
      rightMotor.write(RForward);  //move forward
      delay(100);
   }
   else    //if path is blocked
   {
      Serial.println("Path blocked"); // ****************************
      leftMotor.write(LNeutral);
      rightMotor.write(RNeutral);
      panMotor.write(0);
      delay(500);
      rightDistance = ping();  //scan to the right
      delay(500);
      panMotor.write(180);
      delay(700);
      leftDistance = ping();  //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(LForward);
      rightMotor.write(RBackward);  //turn 180 degrees
      delay(1000);
   }
}

long ping()
{
   // Send out PING))) signal pulse
   pinMode(pingPin, OUTPUT);
   digitalWrite(pingPin, LOW);
   delayMicroseconds(2);
   digitalWrite(pingPin, HIGH);
   delayMicroseconds(5);
   digitalWrite(pingPin, LOW);

   //Get duration it takes to receive echo
   pinMode(pingPin, INPUT);
   duration = pulseIn(pingPin, HIGH);

   //Convert duration into distance
   return duration / 29 / 2;
}

When you open the serial monitor to see your prints, make sure that the baud rate is set to match the begin() function (15200 in this case).

baud

Hi @ranelr2138

I recommend that you
Take a look into this tutorial:

Arduino Programming Course

It is easy to understand and has a good mixture between explaining important concepts and example-codes to get you going. So give it a try and report your opinion about this tutorial.

From your code you have defined constants that have opposite values

This means if the servos are mounted in a "mirror"-way this should work.

If your servos for leftwheel / rightwheel are mounted in the same position
(=not "mirrored") The code works exactly as the code is written.

Write a short testprogram that does nothing more than make the left servo move forward and the right servo move forward
and use serial printing to print the values to the serial monitor.
And then compare the values that were used in the
leftMotor.write() / rightMotor.write() function-calls
with wheel-rotation direction

If the wheel rotate in a way that your robot circles instead of moving straight forward you can conclude that you have to reverse one value

best regards Stefan