This is a great little autonomous robot project using an arduino that can easily be completed in a short amount of time. We used a Modern Device RBBB (Really Bare Bones Board) as the brain of our robot. These RBBB kits are also great if you are new to soldering. Not a lot of parts, but just enough to get get some experience with.
The robot is powered with four AA batteries. The biggest cost expense with the project would be for the servos - (2) continuous rotation servos and (1) standard servo. For the eys we used a Sharp IR Sensor.
The robot sweeps the ir range finder 130 degrees and records the closest object. Objects closer than 10 inches will cause the robot to take action. If this object is more than 45 degrees to the right or left it makes a small correction away from the object. If the object is within the center 90 degrees, it stops, looks left and right, finds the clearest direction and turns about 90 degrees to that direction.
We picked up a copy of the code from Bunedoggle, and Brian was nice enough to help us out with getting the values to work for our servos. A copy of the code is located below as well as on the Bunedoggle site. You may have to experiment with the servo values a little.
Materials Needed:
(2) Continuous Rotation Servos
(1) Standard Servo
(1) RBBB or Arduino, or other Arduino compatible
(1) AA Baterry Box (holds 4)
(4) AA Batteries
(1) 1-1/4″ Caster Wheel
(2) Servo Mountable Wheels
(1) Sharp IR Sensor
(1) IR Sensor Servo Mount
(1) 840 T/P Breadboard
Hook-up Wire
Zip Ties
Double Sided Sticky Foam
Tape
To put it all together we used 1″x1″x1/4″ double sided sticky foam to hold the servos in place. Using zip ties also kept everything in place. You can use your creativity here and come up with another idea if you want. We planned to reuse all this stuff so we didn’t want anything to be permenant.
Shawn - http://www.ArduinoFun.com
Arduino Sketch:/*
* Brian Bailey *
* Drives servo robot and avoids obsticles using Sharp IR range finder
* http://bunedoggle.com/robots.php
*/
#define CENTER 1400
#define CENTER_R CENTER
#define CENTER_L CENTER+1
#define LEFT CENTER-650
#define RIGHT CENTER+650
#define R_FULL_FORWARD R_STOP+300
#define L_FULL_FORWARD L_STOP-300
#define L_FULL_REVERSE R_FULL_FORWARD
#define R_FULL_REVERSE L_FULL_FORWARD
#define R_STOP 1450
#define L_STOP 1450
#define LEFT_TURN 0
#define RIGHT_TURN 1
#define QUARTER_TURN_DELAY 800 // in milliseconds
#define DIST_ERR 50
#define RSPEED R_STOP + 100
#define LSPEED L_STOP - 110
#define DEBUG 0
#define BUMP_DELAY 125
int leftDist = 0; // the average
int rightDist = 0;
int forDist = 0;
int vision = 5;
boolean goingLeft = true;
boolean turnNow = false;
int curDist = 0;
int objDist = 0;
int objDir = 0;
#include
// create servo objects to control servos
ServoTimer2 leftWheel;
ServoTimer2 rightWheel;
ServoTimer2 head;
int leftSpeed = LSPEED; // variable to store the servo position
int rightSpeed = RSPEED;
int headPos=CENTER;
void setup()
{
leftWheel.attach(10); // attaches the servo on pin 9 to the servo object
rightWheel.attach(11);
head.attach(9);
rightWheel.write(rightSpeed); // Stop Wheels
leftWheel.write(leftSpeed); // Stop Wheels
head.write(headPos);
Serial.begin(9600); // initialize serial communication with computer
}
/*******************************************************
* turn - Executes an in-place turn for miliseconds
* QUARTER_TURN_DELAY gets you about 90 deg
********************************************************/
void turn(int dir, int duration){
// Store previous speeds
//rightSpeed = rightWheel.read();
//leftSpeed = leftWheel.read();
if(dir == LEFT_TURN){
rightWheel.write(R_FULL_REVERSE);
leftWheel.write(L_FULL_FORWARD);
}
else {
rightWheel.write(R_FULL_FORWARD);
leftWheel.write(L_FULL_REVERSE);
}
delay(duration);
// restore previous speeds
rightWheel.write(rightSpeed);
leftWheel.write(leftSpeed);
}
void go(){
rightWheel.write(RSPEED);
leftWheel.write(LSPEED);
}
void stop(){
rightWheel.write(R_STOP);
leftWheel.write(L_STOP);
}
/***************************************************
* scan - This function is called every cycle
* it turns the head a click and records a distance and
* heading. It only saves the closest object info.
* objDist and objDir hold the closest object data
****************************************************/
void scan(){
if(goingLeft){
head.write(head.read()-10);
}
else{
head.write(head.read()+10);
}
if(head.read() <= LEFT){
goingLeft = false;
forDist = 0;
objDist = 0;
turnNow = true;
}
if(head.read() >= RIGHT){
goingLeft = true;
forDist = 0;
objDist = 0;
turnNow = true;
}
curDist = analogRead(vision);
if(curDist > objDist){
objDist = curDist;
objDir = head.read();
if(DEBUG){
Serial.print(”New close obj at Dist: “);
Serial.print(objDist);
Serial.print(” heading: “);
Serial.println(objDir);
}
}
delay(10);
}
/**********************************************************
* bump
* Executes a nudge to a given side
* Pass in LEFT_TURN or RIGHT_TURN
***********************************************************/
void bump(int dir){
#define BUMP 100
if(dir == LEFT_TURN){
rightWheel.write(rightWheel.read()-BUMP);
delay(BUMP_DELAY);
rightWheel.write(rightWheel.read()+BUMP);
}
else {
leftWheel.write(leftWheel.read()+BUMP);
delay(BUMP_DELAY);
leftWheel.write(leftWheel.read()-BUMP);
}
}
/**********************************************************
* bumpSteer
* Nudges us back on coarse if we see something off to the
* side. Relies on objDist and objDir to be updated by scan()
*
***********************************************************/
void bumpSteer(){
// One bump per scan
if(!turnNow || objDist < 470)
return;
if(objDir > CENTER){
bump(RIGHT_TURN);
}
else if(objDir <= CENTER){
bump(LEFT_TURN);
}
// No turn till next scan
turnNow = false;
}
void lookAround(){
head.write(LEFT);
delay(400);
leftDist = analogRead(vision);
head.write(CENTER);
delay(400);
forDist = analogRead(vision);
head.write(RIGHT);
delay(400);
rightDist = analogRead(vision);
head.write(CENTER);
delay(200);
}
int cornerNav(){
if(objDist > 600 && objDir > CENTER - 350 && objDir < CENTER + 200){
if( DEBUG ){
Serial.println("Check:");
Serial.println(objDist);
Serial.println(objDir);
}
stop();
lookAround();
if(leftDist > rightDist + DIST_ERR){
turn(LEFT_TURN, QUARTER_TURN_DELAY);
}
else {
turn(RIGHT_TURN, QUARTER_TURN_DELAY);
}
go();
objDist = 0;
return 1;
}
return 0;
}
void loop()
{
scan();
if(!cornerNav()){
bumpSteer();
}
}
This is a companion discussion topic for the original entry at https://community.robotshop.com/robots/show/easy-arduino-robot