Go Down

Topic: CarBot - My first Robot (Read 4779 times) previous topic - next topic

bill2009

I was looking around for a basis for a wall-follower and I came across a battery operated car that originally had a wire-attached controller with two C-cells in it.  Much dicking around later I present... CarBot.

The original motors are being driven by a little motor-driver board from robotshop which is sitting on a proto-shield on top of my arduino.  There's a seeed studio ultrasonic rangefinder up front for object avoidance.

Once I had built and programmed the thing I discovered that it was very similar in intent and components to "Makey" from Make magazine.  I quickly ripped off the software and changed the pins etc to suit my details.
Code: [Select]
/*
* CarBot roams around, while avoiding objects
* sensed with the Seeed ultrasonic rangefinder.
* Thanks to:
* Makey Robot, MAKE Magazine, Volume 19, p. 77
* Created: June 2009 Kris Magri
 adapted from the program 06_Object_Avoidance
*/
#include <Streaming.h>
#define cout Serial
#define endl '\n'
 #define pingPin       4      // Seeed ultrasonic sensor on pin D4.
 #define leftSpeedPin 10      // Left motor speed control, to PWM_A
 #define leftDir1      18      // Left motor direction 1, to AIn1
 #define leftDir2      17      // Left motor direction 2, to AIn2
 #define rightDir1     15      // Right motor direction 1, to BIn1
 #define rightDir2     16      // Right motor direction 2, to BIn2
 #define rightSpeedPin 11      // Right motor speed control, to PWM_B
 #define basespeed     92      //default speed
 #define BOUNDARY     30      // (cm) Avoid objects closer than 30cm.
 #define INTERVAL     25      // (ms) Interval between distance readings.
                              // at 250 cm/s that's 6 cm
volatile unsigned long notstalled; // last time we know the robot was moving

void setup()                                                
{
 pinMode(leftDir1, OUTPUT);        // Set motor direction pins as outputs.
 pinMode(leftDir2, OUTPUT);      
 pinMode(rightDir1, OUTPUT);      
 pinMode(rightDir2, OUTPUT);

 analogWrite(leftSpeedPin,basespeed); //limit the speed of CarBot
 analogWrite(rightSpeedPin,basespeed);
 attachInterrupt(0,stallchecker,FALLING);
 Serial.begin(19200); //just what my xbees are set to

}
void stallchecker(){ //check to see if the robot is stuck
notstalled=millis(); //record the time of the wheelpass
}

// Main program
// Roam around while avoiding objects.
//
// Set motors to move forward,
// Take distance readings over and over,
// as long as no objects are too close (determined by BOUNDARY).
// If object is too close, avoid it -- back up and turn.
// Repeat.

void loop()                    
{
 long distance;                    // Distance reading from rangefinder.
 
 forward();                        // Robot moves forward continuously.
 do
 {
  delay(INTERVAL);                // Delay between readings.
   distance = readDistance();      // Take a distance reading.
   cout <<" f"<<distance;
   Serial.println(distance);       // Print it out.            
  }
 while((distance >= BOUNDARY)&& //loop til an object is sensed
      ((millis()-notstalled)<1000)); //or the wheels stop moving    

 if ((millis()-notstalled)<=1000){ //if it's just an object
   cout <<endl<<"bkp "<<endl;
   backward();                       // Move backward 750ms.
   delay(750);              
   leftTurn(300);}                   // Turn left 300ms.
 else{ //robot has stalled
     cout<< '\n' <<"stalled" << '\n';
     backward(); delay(1000); //longer backup
     leftTurn(500);                   // bigger turn
 }
}// end Main program


// forward
//
// Move robot forward by setting both wheels forward.
// Will persist until something else changes the
// motors' directions.

void forward() //designations confirmed dec 4
{
 digitalWrite(leftDir1, LOW);      // Left motor forward.            
 digitalWrite(leftDir2, HIGH);
 digitalWrite(rightDir1, LOW);     // Right motor forward.
 digitalWrite(rightDir2, HIGH);
}  


// backward
//
// Move robot backward by setting both wheels backward.
// Will persist until something else changes the
// motors' directions.

void backward()
{
 digitalWrite(leftDir1, HIGH);     // Left motor backward.
 digitalWrite(leftDir2, LOW);
 digitalWrite(rightDir1, HIGH);    // Right motor backward.
 digitalWrite(rightDir2, LOW);
}


// leftTurn
//
// Turn robot to left by moving wheels in opposite directions.
// Amount of turning is determined by duration argument (ms).

void leftTurn(int duration)
{
 digitalWrite(leftDir1, HIGH);     // Left motor backward.
 digitalWrite(leftDir2, LOW);
 digitalWrite(rightDir1, LOW);     // Right motor forward.
 digitalWrite(rightDir2, HIGH);
 delay(duration);                  // Turning time (ms).
}


// readDistance
// Take a distance reading from Ping ultrasonic rangefinder.
// from http://arduino.cc/en/Tutorial/Ping?from=Tutorial.UltrasoundSensor

long readDistance()
{
 long duration, inches, cm;

 // The sensor is triggered by a HIGH pulse of 2 or more microseconds.
 // We give a short LOW pulse beforehand to ensure a clean HIGH pulse.
 pinMode(pingPin, OUTPUT);
 digitalWrite(pingPin, LOW);
 delayMicroseconds(2);
 digitalWrite(pingPin, HIGH);
 delayMicroseconds(15);
 digitalWrite(pingPin, LOW);
 delayMicroseconds(20);

 // The same pin is used to read the signal from the Ping: a HIGH
 // pulse whose duration is the time (in microseconds) from the sending
 // of the ping to the reception of its echo off an object.
 pinMode(pingPin, INPUT);
 duration = pulseIn(pingPin, HIGH);

 // Convert the time into a distance.
 cm = microsecondsToCentimeters(duration);
 return(cm);
}

long microsecondsToCentimeters(long microseconds)
{
 // The speed of sound is 340 m/s or 29 microseconds per centimeter.
 // The ping travels out and back, so to find the distance of the
 // object we take half of the distance traveled.
 return microseconds / 29 / 2;
}


Hardly a harbinger of the robot apocalypse but I've learned a lot.  I'm planning to install a second sensor to make a wall racer and build another version with a servo to scan with the sensor.  I also got a pololu baby orangutan controller which, incredibly to me, should replace the arduino, proto-shield and motor driver board.  With this I can either have CarBot regain his wheelie capabilities or simplify my next platform.

This was my original inspiration: http://letsmakerobots.com/node/928


and here's makey, my accidental software developer: http://makeprojects.com/Project/My-Robot-Makey/51/1

p.00.ter

Nice car. It's good to see Makey getting some love. I still use the PING sweep out of that sketch all of the time.

Divyanshu


Go Up