3 Simple Ways to
Share What You Make

With Instructables you can share what you make with the world — and tap into an ever-growing community of creative experts.

PhotosPhotos

Share one or more photos of a project, recipe, or whatever you've made, quickly and easily.

Step by StepStep-By-Step

Share your step-by-step photos with text instructions of what you made so others can do it too!

VideoVideo

Share your how-to video. You'll need your embed code from a video site such as YouTube.

How To Make an Obstacle Avoiding Arduino Robot

How To Make an Obstacle Avoiding Arduino Robot
Hello all! In this Instructable I'll be showing you how to make a robot similar to the "Mobile Arduino Experimental Platform" (MAEP) that I made. It is equipped with two motors that can steer the robot and the ability to see obstacles in front of it with a PING))) ultrasonic sensor. 

With the attached breadboard, you can do more electronics experiments, fool around with different sensors, etc. This project can teach you about electronics, programming, and robotics. It is also a fun toy to entertain younger siblings and pets (just be sure they don't break it!).

Here is a video of what MAEP will do when it is done:
 
Remove these adsRemove these ads by Signing Up
 

Step 1Parts

Parts
Here's everything you need to make MAEP. I tried to provide links to where you can buy these parts from YourDuino.com, which is the official shop of letsmakerobots.com. EDIT: YourDuino and LMR are now separated and YourDuino is no longer giving money to LMR, however they still have pretty good prices so feel free to shop there.

- Arduino compatible microcontroller. I used an Arduino Uno, so I recommend one if you wish to follow closely along with this tutorial. There are also some Arduino based controllers that are designed specifically for robotics that may be helpful, but you’ll have to find your own method of mounting those. You can buy a copy of the Uno from YourDuino which I believe is completely compatible: http://arduino-direct.com/sunshop/index.php?l=product_detail&p=5

-  Breadboard. Make sure it’s not too big, or else it won’t fit. However, we want it to be as big as possible so we have more room for electronics. This is good: http://arduino-direct.com/sunshop/index.php?l=product_detail&p=168

- A standard old 9 volt alkaline battery (which you can probably find at home), as well as a barrel jack connector to hook it up to your Uno easily (not required, but again, easier):  http://arduino-direct.com/sunshop/index.php?l=product_detail&p=119

- A power supply for the motors. I don’t believe the power supply I chose is the cheapest or best option, so I’m not going to recommend it to you. I used a 4.8 volt rechargeable NiCad battery, but it’s probably easier to just use a 4 AA battery holder (no need to buy a charger that way)

- A bunch of Boe-Bot hardware for the chassis. Unfortunately, you can’t get this from YourDuino, so look at Parallax, the manufacturer’s website. You can choose either to buy this: http://www.parallax.com/StoreSearchResults/tabid/768/List/0/SortField/4/ProductID/304/Default.aspx?txtSearch=boe+bot+chassis which comes with tons of extra components you don’t need (although may be useful someday), or you can buy all the components in the following list from Parallax and no, I’m not gonna provide a link for each one:



Stock # Quantity              Product Name

700-00002            8             Panhead screw, 4/40, 3/8

700-00003            8              4/40 x 3/8" Nut

700-00009            1             Tail Wheel Ball

700-00015            2              #4 Nylon Washer

700-00022            1              Boe-Bot Aluminum Chassis

700-00023            1              Cotter Pin-1/16" Diameter

700-00025            1              Rubber Grommet-13/32" Hole Diameter

700-00028            4              Panhead screw, 4/40, 1/4

700-00060            2              Standoff, threaded aluminum, round 4-40

721-00001            2              Wheel, Plastic, 2.58 Dia, .3 W

721-00002            2              Rubber Band Tire for 721-00001

900-00008            2              Continuous Rotation Servo



- Wire to hook things up will be necessary. Some male-to-male jumpers will do the trick: http://arduino-direct.com/sunshop/index.php?l=product_detail&p=94

- Finally, the PING))) sensor and mounting bracket, so that your robot doesn't kill itself: http://www.parallax.com/StoreSearchResults/tabid/768/List/0/SortField/4/ProductID/563/Default.aspx?txtSearch=ping+sensor+mount


As for tools, all you need is a phillips head screwdriver, a computer, and one of those standard USB printer cables. The Arduino Uno I provided a link for has a cable included. 

Now lets get building!
« Previous StepDownload PDFView All StepsNext Step »
25 comments
May 27, 2012. 3:35 PMfaroos7 says:
hey what does centering the servos do exactly? because im getting the same thing user greentree89 is getting. robot goes in circles only and the sensor is jolting its not like doing full movements and if u manually turn it it keeps goin to the right n gets stuck n jolts there. i know im months late but u have an interesting project. any help would be appreciated
May 4, 2012. 9:18 PMbiomech75 says:
I think you fogot to add on the materials list a non 360º servo for the Ping sensor ;) 
Mar 13, 2012. 8:22 PMgreentree89 says:
Hey there i am back, i finally got all the parts and i have put my robot together, all that is left is to wire it up! :)
Just got a quick question, I am not entirely sure about the 5v power rail you mentioned.
So i got the 3 servo motors and the ping sensor that all need 5v.
should i be connecting them all to the battery 5v rail or the arduino 5v rail that you said to connect to the breadboard?
Thanks again !
Mar 14, 2012. 4:00 PMgreentree89 says:
Hey thanks for your reply, i have now wired it and uploaded the code to my robot.
What happens however is that it rotates in a circle with the right motor moving forward and the left moving backward.
when i put my hand in front of the sensor it moves backwards untill all is clear and then continues to move in rotation, also the sensor servo does not operate at all.

I made sure i got all the wires in the right place and also tried swapping the motor wires around but just got more odd movements

here is the code i am using:
/*MAEP 2.0 Navigation
by Noah Moroze, aka GeneralGeek
This code has been released under a Attribution-NonCommercial-ShareAlike license, more info at http://creativecommons.org/licenses/
PING))) code by David A. Mellis and Tom Igoe http://www.arduino.cc/en/Tutorial/Ping
*/

#include //include Servo library
#include

Ultrasonic ultrasonic ( 4, 5);
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 irPin = 0; //Sharp infrared sensor pin
const int dangerThresh = 4; //threshold for obstacles (in inches)
int leftDistance, rightDistance; //distances on either side
Servo panMotor;
Servo leftMotor;
Servo rightMotor; //declare motors

void setup()
{
rightMotor.attach(11);
leftMotor.attach(10);
panMotor.attach(6); //attach motors to proper pins
panMotor.write(90); //set PING))) pan to center
leftMotor.write(90);
rightMotor.write(90);
}

void loop()
{
int distanceFwd = ultrasonic.Ranging(INC);
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 = ultrasonic.Ranging(INC); //scan to the right
delay(500);
panMotor.write(180);
delay(700);
leftDistance = ultrasonic.Ranging(INC); //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);
}
}

Mar 15, 2012. 7:46 PMgreentree89 says:
I fixed it! :D
I was reading up the reason for the odd behavior from all 3 servos and it turns out it was because the servos need to share the ground from both arduino and the battery, i must of missed that part on your tutorial, i just took a lead from from the arduino gnd and connected it to the breadbord gnd rail that you said to link from both sides.
now it responds perfectly! :)
I have now tested out the whole code as i was breaking it down to see how it responded.
everything seems fine except the panmotor still moves all the way to the right at the very start before it even detects an object.
i will do some more tests tomorrow to find out the problem.
Mar 17, 2012. 2:40 PMgreentree89 says:
Hey i tried everything to get the panmotor servo working correctly but it will not respond other than go clockwise then it starts shaking, very odd i can only say it must be faulty.
i will order a new servo but in the mean time i have simplified the code for a fixed sensor so it simply turns left on detection of obstacles, i have also added a piezo and led to the code, i will make a video to show you my robot :)
it is very simple compared to your robot but for my first robot i am very proud :D
i also had to increase the speed of the right servo as it seems to turn left, i must of designed the balance of the chassis badly.
i also find that when it is heading towards obstacles at an angle it does not pick up on the obstacle and completely gets stuck, but i do have a spare sensor, perhaps i can use 2 on the robot to help this.
well theres plenty of ideas to upgrade my robot :)
I will make the video of my robot very soon, thankyou so much for all your help, you've been amazing and so very helpful :)
Mar 18, 2012. 7:55 PMgreentree89 says:
Hey there! :)
Thankyou so much for all your encouragement and it is because of you i have built my first robot.
I built up a random code from the link you sent me, it works great!
And to add to that i combined the code with something else i found which solves a problem my robot had,

from my last post, simply when the robot came in at an obstacle from an angle it would not detect it and then try and turn too late and it must move forward to make a turn, but when it gets too close to an obstacle it moves backwards then turns.
I have tested the random turning which i really like but i noticed a problem i had not thought of before,

lets say it comes to a corner, and chooses to turn left, it will then immediately meet the other wall and by chance the random code makes it turn right it hit the previous wall again, i have watched it do this quite a few times, but its still quite fun to watch it like this as you said because you never know which turn it will take making things interesting, it always gets it's self out of areas sooner or later anyway hahah

I have bought a new servo for the sensor which should arrive shortly.
Video coming soon! :)
Thanks again!
here is my code if you are interested in seeing it at the moment:


#include //include Servo library
#include

Ultrasonic ultrasonic ( 4, 5);


const int numOfReadings = 1; // number of readings to take/ items in the array
int readings[numOfReadings]; // stores the distance readings in an array
int arrayIndex = 0; // arrayIndex of the current item in the array
int total = 0; // stores the cumlative total
int averageDistance = 0; // stores the average value
int echoPin = 5; // SRF05 echo pin (digital 2)
int initPin = 4; // SRF05 trigger pin (digital 3)
unsigned long pulseTime = 0; // stores the pulse in Micro Seconds
unsigned long distance = 0; // variable for storing the distance (cm
int pinSpeaker = 13;
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
int leftDistance, rightDistance; //distances on either side
Servo leftMotor;
Servo rightMotor; //declare motors
int randNumberSpeed; // variable to store the random speed value
int randNumberDir; // variable to store the random direction value
int x = randNumberDir;
void setup()
{
Serial.begin(9600);
rightMotor.attach(11);
leftMotor.attach(8);
pinMode(2, OUTPUT);
pinMode(3, OUTPUT);
pinMode(pinSpeaker, OUTPUT);
pinMode(4, OUTPUT); // trig init
pinMode(5, INPUT); //echo
// create array loop to iterate over every item in the array

for (int thisReading = 0; thisReading < numOfReadings; thisReading++) {
readings[thisReading] = 0;

randomSeed(millis());
}

}

void loop() {
digitalWrite(initPin, HIGH); // send 10 microsecond pulse
delayMicroseconds(10); // wait 10 microseconds before turning off
digitalWrite(initPin, LOW); // stop sending the pulse
pulseTime = pulseIn(echoPin, HIGH); // Look for a return pulse, it should be high as the pulse goes low-high-low
distance = pulseTime/58; // Distance = pulse time / 58 to convert to cm.
total= total - readings[arrayIndex]; // subtract the last distance
readings[arrayIndex] = distance; // add distance reading to array
total= total + readings[arrayIndex]; // add the reading to the total
arrayIndex = arrayIndex + 1; // go to the next item in the array

// At the end of the array (10 items) then start again
if (arrayIndex >= numOfReadings) {
arrayIndex = 0;
}

averageDistance = total / numOfReadings; // calculate the average distance
delay(10);

// Check the average distance and move accordingly

if (averageDistance <= 10) {
// go backwards
leftMotor.writeMicroseconds(1000);
rightMotor.writeMicroseconds(2000);
digitalWrite(2, HIGH);
digitalWrite(3, LOW);
{
playTone(750, 500);
delay(350);
}
}


if (averageDistance <= 25 && averageDistance > 10 ) {

//turn left
randomSeed(millis());
randNumberDir = random(300); {
if (randNumberDir > 150){
rightMotor.writeMicroseconds(1000);
leftMotor.writeMicroseconds(1500);
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
{
playTone(750, 300);
delay(750);
}
}
else if (randNumberDir < 150){
rightMotor.writeMicroseconds(1500);
leftMotor.writeMicroseconds(2000);
digitalWrite(2, LOW);
digitalWrite(3, HIGH);
{
playTone(750, 400);
delay(750);
}
}
}
}

if (averageDistance > 25) {
// go forward
digitalWrite(2, LOW);
digitalWrite(3, LOW);
delay(1000);
leftMotor.writeMicroseconds(2000);
rightMotor.writeMicroseconds(1100);
}
}


// duration in mSecs, frequency in hertz
void playTone(long duration, int freq) {
duration *= 1000;
int period = (1.0 / freq) * 1000000;
long elapsed_time = 0;
while (elapsed_time < duration) {
digitalWrite(pinSpeaker,HIGH);
delayMicroseconds(period / 2);
digitalWrite(pinSpeaker, LOW);
delayMicroseconds(period / 2);
elapsed_time += (period);
}
}
Mar 14, 2012. 6:38 PMgreentree89 says:
Heheh got 3 problems all at once, i tried this but it still does the same thing.
It simply continues to move in rotation, it seems to be the left motor that is going the wrong way no matter where ever i set it to 0, 180 or 90

And of course it does not stop but rather instead moves backwards when there is an obstacle.

I also tried that code for the sensor servo, it moves it all the way to the right but then nothing else happens, same for the robot code, nothing moves it to the left again.

Its ok if you cant figure this one out, you've been an amazing help with all my questions, i will continue to try and work on it.
Thanks again.
Feb 27, 2012. 2:23 AMfjohn says:
hey nice post....by the way could u make the code for two geared motors instead of the continues servos/? please!!!
Feb 28, 2012. 12:02 AMfjohn says:
a im using a motor driver like the l239d the motor just acts like a normal one it just have gears and dont need special programming so could ya make one ??? u know so if it finds an obstacle it turns????than ks
Feb 25, 2012. 5:37 PMgreentree89 says:
I found this: http://www.meanpc.com/2012/01/hc-sr04-ultrasonic-sensor-added-to.html
though i much prefer your code where the ping servo rotates to choose the best path.
I shall now try and combine both codes to suit my robot :)
Feb 26, 2012. 7:35 PMgreentree89 says:
Hey this is great! thankyou very much.

I spent a while trying to combine the codes but i kept getting so many errors but after i tried what you sent me, it works perfectly.
Just wondering do i change the Ranging(CM) to an actual number like Ranging(15) ? just to be sure.

I have just ordered the right batteries and i must also get a new servo motor as for some reason it gets really hot but it no longer moves.

I will be sure to upload photo's and a vid to show you :)
Thanks again.
Feb 24, 2012. 3:45 PMgreentree89 says:
Hey my ultrasonic sensor has 4 pins, the 5v, gnd, echo and trig.
How should i connect them and what should i add to the code to make it work?
Thanks :)
Feb 25, 2012. 1:22 PMgreentree89 says:
Hey thanks for your reply and link, i have tried combining the code with your one but i am very new with programming and it does not take long for me to get lost.
I am not sure what i should take out of your code and replace.

Pro

Get More Out of Instructables

Already have an Account?

close

All Steps Viewing
View all steps of an Instructable on the same page when you're a Pro Member.

Upgrade to Pro today!
4
Followers
1
Author:generalgeek314
A kid who is passionate about robotics, electronics, and computer programming.