Introduction: Obstacle Avoiding Robot V2
Recently I did an instructable on a simple obstacle avoiding robot. In this instructable I will be implementing a panning PING))) sensor, unlike the previous robot who's sensor was stationary. I will utilize this third servo upon which the PING))) sensor is mounted to pan left and right once the robot reaches the distance threshold. When the robot is panning left and right, it is looking for the “clearer” path. Once the robot has decided which path is clearer, it rotates and starts moving in that direction. In this tutorial I will describe to you through visuals and written instructions on how to create this obstacle avoiding robot. I will try to be as clear as possible and leave no details behind. You can also refer back to my first robot for additional information if you need to. Continue onto the first step for the parts list.
Step 1: Gather the Parts
To build this robot you are going to need the following parts. All of these parts can be gotten separately or in a bundle (you won't need all of the parts in the bundle) at http://www.parallax.com/.
Hardware:
The following hardware you can get anywhere in various prices.
• Arduino Nano (any 5v Arduino of your choosing will work).
• Four AA batteries
• AA battery holder
• Breadboard (a mini breadboard was perfect in size).
• Wire
• PING))) Ultrasonic Distance Sensor
Hardware from Parallax:
The following hardware you can get anywhere in various prices.
Stock # Quantity Product Name
700-00009 1 Tail Wheel Ball
700-00022 1 Boe-Bot Aluminum Chassis
700-00023 1 Cotter Pin-1/16" Diameter
700-00025 1 Rubber Grommet-13/32" Hole Diameter
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
570-28015 1 PING))) Mounting Bracket Kit
Software:
• Arduino IDE (my version is 1.0.5).
Miscellaneous:
• Phillips head screw driver
• Computer
• Screws and nuts
Hardware:
The following hardware you can get anywhere in various prices.
• Arduino Nano (any 5v Arduino of your choosing will work).
• Four AA batteries
• AA battery holder
• Breadboard (a mini breadboard was perfect in size).
• Wire
• PING))) Ultrasonic Distance Sensor
Hardware from Parallax:
The following hardware you can get anywhere in various prices.
Stock # Quantity Product Name
700-00009 1 Tail Wheel Ball
700-00022 1 Boe-Bot Aluminum Chassis
700-00023 1 Cotter Pin-1/16" Diameter
700-00025 1 Rubber Grommet-13/32" Hole Diameter
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
570-28015 1 PING))) Mounting Bracket Kit
Software:
• Arduino IDE (my version is 1.0.5).
Miscellaneous:
• Phillips head screw driver
• Computer
• Screws and nuts
Step 2: Tuning the Servos
Before we go ahead and start building anything, we need to calibrate the servos. First, we have to hook up the servo motors. The black wire should be connected to ground on your Arduino (labeled "GND"), the red one to 5 volts (labeled "5V"), and the white one to pin 11 (labeled "~D11"). Once you have your servo hooked up to your Arduino, upload the following code to your Arduino board. Your servo will more than likely start to move because it isn't tuned perfectly yet. The small potentiometer that you see labeled there in my picture turns left and right. Adjust the potentiometer with a phillips head scredriwer. It will take a few shots to get it right because the servo has to be absolutely still if you've tuned it right. A hair to far left or right and it begins to spin. If you've tuned the servo to perfection and you see no movement from the servo, hook up the other servo and do the same.
CODE FOR SERVO CALIBRATION:
//Center Servos
#include <Servo.h>
Servo servo;
void setup()
{
servo.attach(11);
}
void loop()
{
servo.write(90);
}
Continue onto the next step where we construct the circuit.
CODE FOR SERVO CALIBRATION:
//Center Servos
#include <Servo.h>
Servo servo;
void setup()
{
servo.attach(11);
}
void loop()
{
servo.write(90);
}
Continue onto the next step where we construct the circuit.
Step 3: Constructing the Circuit
As you can see, the circuit is very simple again. Nothing has changed from the first robot other than adding a third panning servo to pin D6 of the Arduino. I tried to make the schematic as neat as possible and I believe it's quite easy to follow. If your robot is not operating properly, the only problem/s that I foresee is/are somewhere within your code. Don't hesitate to ask for help. As noted in my previous obstacle avoiding robot instructable, the sensor that you see there in the schematic is NOT the PING))) sensor. The software that I used to create the schematic doesn't have the PING))) sensor in its inventory, so I used one that at least somewhat resembled the PING))) sensor. The connections are the same (red=power, black=ground, yellow=SIG). I believe that is all that needs to be said regarding the circuit, but if you have any questions, don't hesitate to ask. Continue onto the next step for the programming part.
Step 4: Programming
The basic concept of the code is for the robot to always be monitoring for objects in front of it while moving. This is done by the PING))) sensor where it sends out a 40kHz chirp which is not audible, and retrieves the echo. The program then gets the duration it takes for the pulse to get back and converts it into distance. Once the robot detects an object where the distance forward is greater than the danger threshold - the path is clear so our program tells the robot to move forward. Otherwise the robot will stop then pan left and right. Depending upon which path is "clearer", the robot will rotate to that clearer path and start heading in that direction. The code just loops in this fashion. That is basically the "theory" behind the code. If you know of any improvements that could be done to the code, I would love to hear your feedback! Continue onto the last step for additional pictures and conclusion.
THE CODE:
/*
> Design an obstacle avoiding robot using an Arduino NANO and Parallax PING))) Ultrasonic Distance Sensor
> Version 2
> Zoran M.
*/
#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;
}
Continue on for additional pictures and the conclusion.
THE CODE:
/*
> Design an obstacle avoiding robot using an Arduino NANO and Parallax PING))) Ultrasonic Distance Sensor
> Version 2
> Zoran M.
*/
#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;
}
Continue on for additional pictures and the conclusion.
Step 5: Additional Pictures and Conclusion
This project went nearly without a hiccup; probably because there wasn't much to do other than add the third servo. There were some bumps in the road regarding the code, though, where I spent some time debugging, but nothing too significant. Thankfully there were some other sources of similar builds which I borrowed some ideas from. For more detailed pictures on how to mount the servos you can refer to the instructable on my other obstacle avoiding robot. A neat addition that could be made in the future is to incorporate a piezoelectric buzzer that would go up in frequency as the robot got closer to an object or an LED bar that would serve the same function. Don't hesitate to post up your versions, even if you did it like I did. I would love to see them!