Using Continuous Servos to drive Obstacle Avoidance rover

Hi there,

I am trying to drive an obstacle avoidance robot (using a regular ultrasonic distance sensor) using 4 continuous rotation servos.
Is this possible? and if so how?

Thanks

Why four?
Those things are notoriously difficult to drive at a given speed.

1 Like

Yes. You drive it like any four-wheel-drive skid-steer object-avoiding car that uses DC gear motors except you use the Servo library to drive the motors instead of four H-Bridge drivers.

https://create.arduino.cc/projecthub/jojessegaming/4-wheeled-obstacle-avoiding-car-87f494

https://create.arduino.cc/projecthub/adam/obstacle-avoiding-car-a192d9

1 Like

Thank you for the reply but I am a noob to Arduino so if it would be possible for you or someone to explain it briefly and what I would have to change in the regular code I will be grateful. I also do not have a motor driver and have to make the project without it.

I was thinking of making one of those skid steers with an ESP 32 too so two things in one I guess.

Then:

I see but when I modify the code to suit my needs I get an error regarding the distance sensor(I am using a grove Ultrasonic Distance Sensor.
Here is my code:

#include <Servo.h>        //add Servo Motor library            
#include <Ultrasonic.h>      //add Ultrasonic sensor library

Ultrasonic ultrasonic(7);
#define MAX_DISTANCE 300 // sets maximum useable sensor measuring distance to 300cm
#define MAX_SPEED 160 // sets speed of DC traction motors to 150/250 or about 70% of full speed - to get power drain down.
#define MAX_SPEED_OFFSET 40 // this sets offset to allow for differences between the two DC traction motors
#define COLL_DIST 30 // sets distance at which robot stops and reverses to 30cm
#define TURN_DIST COLL_DIST+20 // sets distance at which robot veers away from object


Servo M1;
Servo M2;
Servo M3;
Servo M4;
Servo Sense;

const int FORWARD = 180;
const int BACKWARD = 0;
const int RELEASE = 90;

int leftDistance, rightDistance; //distances on either side
int curDist = 0;
String motorSet = "";
int speedSet = 0;

//-------------------------------------------- SETUP LOOP ----------------------------------------------------------------------------
void setup() {
  Sense.attach(7);
  M1.attach(10);  // attaches the servo on pin 10 (SERVO_1 on the Motor Drive Shield to the servo object 
  M2.attach(10);
  M3.attach(10);
  M4.attach(10);
  ultrasonic = ultrasonic.MeasureInCentimeters();
 }
//------------------------------------------------------------------------------------------------------------------------------------

//---------------------------------------------MAIN LOOP ------------------------------------------------------------------------------
void loop() {
  Sense.write(90);  // move eyes forward
  curDist = digitalRead(7);   // read distance
  if (curDist < COLL_DIST) {changePath();}  // if forward is blocked change direction
  moveForward();  // move forward
  delay(500);
 }
//-------------------------------------------------------------------------------------------------------------------------------------

void changePath() {
  moveStop();   // stop forward movement
  Sense.write(36);  // check distance to the right
    delay(500);
    rightDistance = readPing(); //set right distance
    delay(500);
    Sense.write(144);  // check distace to the left
    delay(700);
    leftDistance = readPing(); //set left distance
    delay(500);
    Sense.write(90); //return to center
    delay(100);
    compareDistance();
  }

  
void compareDistance()   // find the longest distance
{
  if (leftDistance>rightDistance) //if left is less obstructed 
  {
    turnLeft();
  }
  else if (rightDistance>leftDistance) //if right is less obstructed
  {
    turnRight();
  }
   else //if they are equally obstructed
  {
    turnAround();
  }
}


//-------------------------------------------------------------------------------------------------------------------------------------

int readPing() { // read the ultrasonic sensor distance
  
  delay(70);   
  unsigned int uS = ultrasonic();
  return cm;
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveStop() {M1.write(RELEASE); M2.write(RELEASE); M3.write(RELEASE); M4.write(RELEASE);}  // stop the motors.
//-------------------------------------------------------------------------------------------------------------------------------------
void moveForward() {
    motorSet = "FORWARD";
    M1.write(FORWARD);      // turn it on going forward
    M2.write(FORWARD);      // turn it on going forward
    M3.write(FORWARD);     // turn it on going forward
    M4.write(FORWARD);     // turn it on going forward
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    M1.write(speedSet);
    M2.write(speedSet);
    M3.write(speedSet); 
    M4.write(speedSet);
    delay(5);
  }
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveBackward() {
    motorSet = "BACKWARD";
    M1.write(BACKWARD);     // turn it on going backward
    M2.write(BACKWARD);     // turn it on going backward
    M3.write(BACKWARD);    // turn it on going backward
    M4.write(BACKWARD);    // turn it on going backward
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    M1.write(speedSet);
    M2.write(speedSet);
    M3.write(speedSet); 
    M4.write(speedSet); 
    delay(5);
  }
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnRight() {
  motorSet = "RIGHT";
  M1.write(FORWARD);      // turn motor 1 forward
  M2.write(FORWARD);      // turn motor 2 forward
  M3.write(BACKWARD);    // turn motor 3 backward
  M4.write(BACKWARD);    // turn motor 4 backward
  M3.write(speedSet+MAX_SPEED_OFFSET);      
  M4.write(speedSet+MAX_SPEED_OFFSET);     
  delay(1500); // write motors this way for 1500        
  motorSet = "FORWARD";
  M1.write(FORWARD);      // set both motors back to forward
  M2.write(FORWARD);
  M3.write(FORWARD);
  M4.write(FORWARD);      
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnLeft() {
  motorSet = "LEFT";
  M1.write(BACKWARD);      // turn motor 1 backward
  M2.write(BACKWARD);      // turn motor 2 backward
  M1.write(speedSet+MAX_SPEED_OFFSET);     
  M2.write(speedSet+MAX_SPEED_OFFSET);    
  M3.write(FORWARD);     // turn motor 3 forward
  M4.write(FORWARD);     // turn motor 4 forward
  delay(1500); // write motors this way for 1500  
  motorSet = "FORWARD";
  M1.write(FORWARD);      // turn it on going forward
  M2.write(FORWARD);      // turn it on going forward
  M3.write(FORWARD);     // turn it on going forward
  M4.write(FORWARD);     // turn it on going forward
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnAround() {
  motorSet = "RIGHT";
  M1.write(FORWARD);      // turn motor 1 forward
  M2.write(FORWARD);      // turn motor 2 forward
  M3.write(BACKWARD);    // turn motor 3 backward
  M4.write(BACKWARD);    // turn motor 4 backward
  M3.write(speedSet+MAX_SPEED_OFFSET);      
  M4.write(speedSet+MAX_SPEED_OFFSET);
  delay(1700); // write motors this way for 1700
  motorSet = "FORWARD";
  M1.write(FORWARD);      // set both motors back to forward
  M2.write(FORWARD);
  M3.write(FORWARD);
  M4.write(FORWARD);      
}```

I am getting the error: no match for call to '(Ultrasonic) ()' and: 'cm' was not declared in this scope
return cm;

To figure out how to use the Ultrasonic library, look at the UltrasonicSimple example that came with the library: File > Examples -> Ultrasonic -> UltrasonicSimple

Thank you, could you please review this code?

#include <Servo.h>        //add Servo Motor library            
#include <Ultrasonic.h>      //add Ultrasonic sensor library

Ultrasonic ultrasonic(7);
#define MAX_DISTANCE 300 // sets maximum useable sensor measuring distance to 300cm
#define MAX_SPEED 180// sets speed of DC traction motors to 150/250 or about 70% of full speed - to get power drain down.
#define MAX_SPEED_OFFSET 40 // this sets offset to allow for differences between the two DC traction motors
#define COLL_DIST 30 // sets distance at which robot stops and reverses to 30cm
#define TURN_DIST COLL_DIST+20 // sets distance at which robot veers away from object


Servo M1;
Servo M2;
Servo M3;
Servo M4;
Servo Sense;

const int FORWARD = 180;
const int BACKWARD = 0;
const int RELEASE = 90;

int leftDistance, rightDistance; //distances on either side
int curDist = 0;
String motorSet = "";
int speedSet = 0;

//-------------------------------------------- SETUP LOOP ----------------------------------------------------------------------------
void setup() {
  Sense.attach(11);
  M1.attach(10);  // attaches the servo on pin 10 (SERVO_1 on the Motor Drive Shield to the servo object 
  M2.attach(9);
  M3.attach(6);
  M4.attach(5);
  ultrasonic = ultrasonic.MeasureInCentimeters();
 }
//------------------------------------------------------------------------------------------------------------------------------------

//---------------------------------------------MAIN LOOP ------------------------------------------------------------------------------
void loop() {
  Sense.write(90);  // move eyes forward
  curDist = digitalRead(7);   // read distance
  if (curDist < COLL_DIST) {changePath();}  // if forward is blocked change direction
  moveForward();  // move forward
  delay(500);
 }
//-------------------------------------------------------------------------------------------------------------------------------------

void changePath() {
  moveStop();   // stop forward movement
  Sense.write(36);  // check distance to the right
    delay(500);
    rightDistance = readPing(); //set right distance
    delay(500);
    Sense.write(144);  // check distace to the left
    delay(700);
    leftDistance = readPing(); //set left distance
    delay(500);
    Sense.write(90); //return to center
    delay(100);
    compareDistance();
  }

  
void compareDistance()   // find the longest distance
{
  if (leftDistance>rightDistance) //if left is less obstructed 
  {
    turnLeft();
  }
  else if (rightDistance>leftDistance) //if right is less obstructed
  {
    turnRight();
  }
   else //if they are equally obstructed
  {
    turnAround();
  }
}


//-------------------------------------------------------------------------------------------------------------------------------------

int readPing() { // read the ultrasonic sensor distance
  delay(70);   
  unsigned int uS =  ultrasonic.MeasureInCentimeters();
  int cm = uS;
  return cm;
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveStop() {M1.write(RELEASE); M2.write(RELEASE); M3.write(RELEASE); M4.write(RELEASE);}  // stop the motors.
//-------------------------------------------------------------------------------------------------------------------------------------
void moveForward() {
    motorSet = "FORWARD";
    M1.write(FORWARD);      // turn it on going forward
    M2.write(FORWARD);      // turn it on going forward
    M3.write(FORWARD);     // turn it on going forward
    M4.write(FORWARD);     // turn it on going forward
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    M1.write(speedSet);
    M2.write(speedSet);
    M3.write(speedSet); 
    M4.write(speedSet);
    delay(5);
  }
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveBackward() {
    motorSet = "BACKWARD";
    M1.write(BACKWARD);     // turn it on going backward
    M2.write(BACKWARD);     // turn it on going backward
    M3.write(BACKWARD);    // turn it on going backward
    M4.write(BACKWARD);    // turn it on going backward
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    M1.write(speedSet);
    M2.write(speedSet);
    M3.write(speedSet); 
    M4.write(speedSet); 
    delay(5);
  }
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnRight() {
  motorSet = "RIGHT";
  M1.write(FORWARD);      // turn motor 1 forward
  M2.write(FORWARD);      // turn motor 2 forward
  M3.write(BACKWARD);    // turn motor 3 backward
  M4.write(BACKWARD);    // turn motor 4 backward
  M3.write(speedSet+MAX_SPEED_OFFSET);      
  M4.write(speedSet+MAX_SPEED_OFFSET);     
  delay(1500); // write motors this way for 1500        
  motorSet = "FORWARD";
  M1.write(FORWARD);      // set both motors back to forward
  M2.write(FORWARD);
  M3.write(FORWARD);
  M4.write(FORWARD);      
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnLeft() {
  motorSet = "LEFT";
  M1.write(BACKWARD);      // turn motor 1 backward
  M2.write(BACKWARD);      // turn motor 2 backward
  M1.write(speedSet+MAX_SPEED_OFFSET);     
  M2.write(speedSet+MAX_SPEED_OFFSET);    
  M3.write(FORWARD);     // turn motor 3 forward
  M4.write(FORWARD);     // turn motor 4 forward
  delay(1500); // write motors this way for 1500  
  motorSet = "FORWARD";
  M1.write(FORWARD);      // turn it on going forward
  M2.write(FORWARD);      // turn it on going forward
  M3.write(FORWARD);     // turn it on going forward
  M4.write(FORWARD);     // turn it on going forward
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnAround() {
  motorSet = "RIGHT";
  M1.write(FORWARD);      // turn motor 1 forward
  M2.write(FORWARD);      // turn motor 2 forward
  M3.write(BACKWARD);    // turn motor 3 backward
  M4.write(BACKWARD);    // turn motor 4 backward
  M3.write(speedSet+MAX_SPEED_OFFSET);      
  M4.write(speedSet+MAX_SPEED_OFFSET);
  delay(1700); // write motors this way for 1700
  motorSet = "FORWARD";
  M1.write(FORWARD);      // set both motors back to forward
  M2.write(FORWARD);
  M3.write(FORWARD);
  M4.write(FORWARD);      
}  ```

Does it compile for you? It doesn't for me.

sketch_may26b.ino: In function 'void setup()':
sketch_may26b:35:27: error: 'class Ultrasonic' has no member named 'MeasureInCentimeters'
   ultrasonic = ultrasonic.MeasureInCentimeters();
                           ^~~~~~~~~~~~~~~~~~~~
sketch_may26b.ino: In function 'int readPing()':
sketch_may26b:92:33: error: 'class Ultrasonic' has no member named 'MeasureInCentimeters'
   unsigned int uS =  ultrasonic.MeasureInCentimeters();
                                 ^~~~~~~~~~~~~~~~~~~~

I have the latest version of Ultrasonic (3.0.0) but the sketch uses a function that the current library doesn't have. The library instructions say to use:

ultrasonic.read()    // distance in CM
ultrasonic.read(CM)  // distance in CM
ultrasonic.read(INC) // distance in INCHES

Also, why are you calling a function that looks like it is supposed to return Centimeters and storing the result in a variable named 'uS' (microseconds).

It does compile for me and I used the examples from the library as guidance for the code, and as for the uS most of the code was copied from other sources.

Edit: I've recompiled in the web editor and ran into the same issue above. I first compiled it using a windows IDE... a problem there? Here is the reviewed code:

#include <Servo.h>        //add Servo Motor library            
#include <Ultrasonic.h>      //add Ultrasonic sensor library

Ultrasonic ultrasonic(7);
#define MAX_DISTANCE 300 // sets maximum useable sensor measuring distance to 300cm
#define MAX_SPEED 180 // sets speed of DC traction motors to 150/250 or about 70% of full speed - to get power drain down.
#define MAX_SPEED_OFFSET 40 // this sets offset to allow for differences between the two DC traction motors
#define COLL_DIST 30 // sets distance at which robot stops and reverses to 30cm
#define TURN_DIST COLL_DIST+20 // sets distance at which robot veers away from object


Servo M1;
Servo M2;
Servo M3;
Servo M4;
Servo Sense;

const int FORWARD = 180;
const int BACKWARD = 0;
const int RELEASE = 90;

int leftDistance, rightDistance; //distances on either side
int curDist = 0;
String motorSet = "";
int speedSet = 0;

//-------------------------------------------- SETUP LOOP ----------------------------------------------------------------------------
void setup() {
  Sense.attach(11);
  M1.attach(10);  // attaches the servo on pin 10 (SERVO_1 on the Motor Drive Shield to the servo object 
  M2.attach(9);
  M3.attach(6);
  M4.attach(5);
  ultrasonic = ultrasonic.read(CM);
 }
//------------------------------------------------------------------------------------------------------------------------------------

//---------------------------------------------MAIN LOOP ------------------------------------------------------------------------------
void loop() {
  Sense.write(90);  // move eyes forward
  curDist = digitalRead(7);   // read distance
  if (curDist < COLL_DIST) {changePath();}  // if forward is blocked change direction
  moveForward();  // move forward
  delay(500);
 }
//-------------------------------------------------------------------------------------------------------------------------------------

void changePath() {
  moveStop();   // stop forward movement
  Sense.write(36);  // check distance to the right
    delay(500);
    rightDistance = readPing(); //set right distance
    delay(500);
    Sense.write(144);  // check distace to the left
    delay(700);
    leftDistance = readPing(); //set left distance
    delay(500);
    Sense.write(90); //return to center
    delay(100);
    compareDistance();
  }

  
void compareDistance()   // find the longest distance
{
  if (leftDistance>rightDistance) //if left is less obstructed 
  {
    turnLeft();
  }
  else if (rightDistance>leftDistance) //if right is less obstructed
  {
    turnRight();
  }
   else //if they are equally obstructed
  {
    turnAround();
  }
}


//-------------------------------------------------------------------------------------------------------------------------------------

int readPing() { // read the ultrasonic sensor distance
  delay(70);   
  unsigned int cm =  ultrasonic.read();
  return cm;
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveStop() {M1.write(RELEASE); M2.write(RELEASE); M3.write(RELEASE); M4.write(RELEASE);}  // stop the motors.
//-------------------------------------------------------------------------------------------------------------------------------------
void moveForward() {
    motorSet = "FORWARD";
    M1.write(FORWARD);      // turn it on going forward
    M2.write(FORWARD);      // turn it on going forward
    M3.write(FORWARD);     // turn it on going forward
    M4.write(FORWARD);     // turn it on going forward
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    M1.write(speedSet);
    M2.write(speedSet);
    M3.write(speedSet); 
    M4.write(speedSet);
    delay(5);
  }
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveBackward() {
    motorSet = "BACKWARD";
    M1.write(BACKWARD);     // turn it on going backward
    M2.write(BACKWARD);     // turn it on going backward
    M3.write(BACKWARD);    // turn it on going backward
    M4.write(BACKWARD);    // turn it on going backward
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    M1.write(speedSet);
    M2.write(speedSet);
    M3.write(speedSet); 
    M4.write(speedSet); 
    delay(5);
  }
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnRight() {
  motorSet = "RIGHT";
  M1.write(FORWARD);      // turn motor 1 forward
  M2.write(FORWARD);      // turn motor 2 forward
  M3.write(BACKWARD);    // turn motor 3 backward
  M4.write(BACKWARD);    // turn motor 4 backward
  M3.write(speedSet+MAX_SPEED_OFFSET);      
  M4.write(speedSet+MAX_SPEED_OFFSET);     
  delay(200); // write motors this way for 1500        
  motorSet = "FORWARD";
  M1.write(FORWARD);      // set both motors back to forward
  M2.write(FORWARD);
  M3.write(FORWARD);
  M4.write(FORWARD);      
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnLeft() {
  motorSet = "LEFT";
  M1.write(BACKWARD);      // turn motor 1 backward
  M2.write(BACKWARD);      // turn motor 2 backward
  M1.write(speedSet+MAX_SPEED_OFFSET);     
  M2.write(speedSet+MAX_SPEED_OFFSET);    
  M3.write(FORWARD);     // turn motor 3 forward
  M4.write(FORWARD);     // turn motor 4 forward
  delay(2000); // write motors this way for 1500  
  motorSet = "FORWARD";
  M1.write(FORWARD);      // turn it on going forward
  M2.write(FORWARD);      // turn it on going forward
  M3.write(FORWARD);     // turn it on going forward
  M4.write(FORWARD);     // turn it on going forward
}  
//-------------------------------------------------------------------------------------------------------------------------------------
void turnAround() {
  motorSet = "RIGHT";
  M1.write(FORWARD);      // turn motor 1 forward
  M2.write(FORWARD);      // turn motor 2 forward
  M3.write(BACKWARD);    // turn motor 3 backward
  M4.write(BACKWARD);    // turn motor 4 backward
  M3.write(speedSet+MAX_SPEED_OFFSET);      
  M4.write(speedSet+MAX_SPEED_OFFSET);
  delay(1700); // write motors this way for 1700
  motorSet = "FORWARD";
  M1.write(FORWARD);      // set both motors back to forward
  M2.write(FORWARD);
  M3.write(FORWARD);
  M4.write(FORWARD);      
}  

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.