bclose

A 4×4 autonomous robot

Objectives

 

 
    • We keep on playing with DC motors and with the Adafruit Motor Shield V1.
    • We seek the Rover can find its route autonomously, avoiding obstacles.
    • We will see the foundations of autonomous movement.

 

 

Bill of materials

Arduino Mega 2560 Arduino MEGA or equivalent.
Motor shield  A Motor Shield V1
  Rover chasis
A rover chassis with 4 motors.
Battery holder battery holder
Ping sensor HC-SR04  A HC-SR04 ultrasound sensor 
 

Some previous comments

 

At first, this chapter was designed to set up a remote control system of our rover, but given that in this humble site we aspire to put the means so that whoever can learn to program and given that our brand new 4×4 wheel rover is on the way, I can’t  help  trying to build an autonomous control system.

We mean, of course, to equip our Rover with some obstacle sensor so it can take  decisions based on its readings, to see what happens. And what better than a sensor we already know from previous chapters: the ultrasonic distance sensor.

In a previous tutorial we saw how to handle it and would be quite easy to attach it to our small 4×4 robot at the front side. Naturally we can complicate  it as much as we want,  using multiple distance, light or sound sensors.

But for this first prototype, we will apply a basic rule of engineering: KISS, in short, Keep It Simple St***d . We will complicate our lives later.

 

 
  • An algorithm, just in case we have not talked about it before, is a standardized procedure for solving a specific problem.
  • In our case, the algorithm will simply turn to the left whenever the ultrasonic distance sensor detects an obstacle within a given distance, which is not a very sophisticated algorithm but we have to start somehow.
 

 

 

Connecting the sensor

 

We saw in a previous chapter how to connect the ultrasonic distance sensor to an Arduino UNO. On this occasion we are going to use an Arduino MEGA, because we need to have enough free pins to connect the Distance Sensor (2 pins) and leave room for the remote control ( 6 pins).

 

 
  • We could, of course, use an Arduino UNO, but a MEGA is more comfortable to use, because the Adafruit Motor Shield does not cover all the pins and, in addition, as we are going to load several libraries we are not sure wether the Arduino ONE will run out of  memory.
 

Just bear in mind that since the 5V pin is not available, because it is hidden by the Motor Shield, we used the pin 52 to power the ultrasonic distance sensor (as the ultrasonic sensor consumes almost nothing and a MEGA pin is able to  drive it) and the GND, which is next to it.

 

 
  • This is a very interesting trick when you want to connect something that does not consume more than 20 mA, which is less than the maximum that an Arduino pin is able to source or sink, and sometimes it prevents us from doing odd things to get 5V. But make sure that you will not exceed this limit.
 

We have chosen these pins for sheer lazyness but you can choose whichever you want, of course.

Let’s include here a diagram of the pins which we have connected, so that you can use them without the need to modify the sketches.

 

Sensor GND Vcc Echo Trigger
MEGA GND 52 48 50
Wire color Black Red Blue Purple

 

A 4×4 autonomous robot, circuit wiring diagram
 
  • Do not trust the drawing and pay attention to the names of the pins and the table of connections above. It’s not easy to burn it, but the cemeteries are full of optimists.
 

In our case, we have fit the ultrasonic sensor into a 3D printered plastic holder (this, for example)  and held it to the front of the robot using plastic tape.

 

Rover with a ultrasound sensor

Let’s see the control sketch.

 

 

An autonomous sketch for the 4×4 Rover

 

As we have just assembled a simple distance sensor, this is all the information we can use and that is why the autonomous movement has to be based on the distance to the nearest obstacle.

It is not the ideal situation but it will be useful as our first approach.

So the idea is the following:

As long as there is no obstacle at less than 30 centimeters, we move forward. If for whatever reason we have got into a problem without knowing how and the distance to an obstacle is less than, let’s say, 15 cm, we move backward. And if the obstacle is between 15 and 30 cm, we turn left.

We apply a delay, after every movement, to make sure that the Rover is moving little by little.

We will reuse the code of the previous chapter, in which we had already programmed the movements, and we will simply change the setup, according to the steps described above.

We have to install the  new_ping library, just in case you have not have installed before.

Let’s take a look at the program:

Prog_95_0.

We start, as usual, including the libraries and some definitions:

#include <NewPing.h>
#include <AFMotor.h>

#define TRIGGER_PIN 50  // Pin connected to the trigger pin.
#define ECHO_PIN 48     // Pin connected to the echo pin.
#define MAX_DISTANCE 200

 

The define statements, correspond to the pins we have chosen in the MEGA and the MAX_DISTANCE variable specifies the maximum value that the sonar library can return, it does not matter  too much here. We now have to create an instance of a sonar object.

 

NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE);

 

And as for the setup, it’s simple. We define pin 52 as output and set it to HIGH to power the sonar. After that we put a small delay to make sure that the power is stable.

 

void setup()
   {
       pinMode(52, OUTPUT) ;      // We will use pin 52 as 5V VCC 
       digitalWrite(52, HIGH) ;
       delay(50);                 // Just in case
   }

As for the loop, we have to start by sending a pulse to measure the distance:

 

unsigned int uS = sonar.ping();  // Send ping, get ping time in microseconds (uS)
int dist = uS / US_ROUNDTRIP_CM ;

 

And now we can proceed to decide the movement according to the rules mentioned above:

 

if (dist > 30)
      Fordward() ;
else if ( dist < 15)
   {
      Reverse() ;
      delay(500);
      TurnLeft() ;
      delay(500);
   }
else
   {
      TurnLeft() ;
      delay (400);
   }
delay(250);

 

The result is quite erratic and with a rather strange behavior, a quite robotic movement, in the worst sense. It also gets stuck without knowing very well why, but as a first approximation it may be worth.

 

 

 

Enhancing the autonomous navigation

 

To be a first test is not that bad. Surely we could imagine a little more sophisticated algorithm that improve the navigation.

For example, we could imagine that the time the robot is turning  depends on the distance to the detected obstacle: the closer it is, the more time it turns. Or perhaps the rotation direction could be random.

 
  • Although we would have to find some way to prevent it from turning once on each side to end up facing always the obstacle.
 

Another way to improve decision making, would be to include more sensors and rely on them to make the rover turn. We could use a light sensor and move around always looking for the brightest point in the room.

Imagine that we use two distance sensors slightly offset from the direction of movement. This way we could consider that if the one on the right, for example, detects an obstacle and the other sensor does not, the conclusion would be to turn to the left and vice versa.

Using two ultrasonic sensors, we could make adaptative turns depending on the relative position of the obstacles.

We leave the subject here, but if you are interested  it would be very easy to think about how to improve the autonomous movement. I leave it as a pending task and if anyone comes up with any ingenious solution, share it with us.

 

Summary

 

 
    • We keep on playing with the Adafruit Motor Shield V1.
    • We have seen a very basic algorithm to move the rover autonomously.
    • We have discussed some methods to enhance the movement.