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 or equivalent. |
![]() |
A Motor Shield V1 |
![]() |
A rover chassis with 4 motors. |
![]() |
A battery holder |
![]() |
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 |

- 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.

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.
Give a Reply