Let's Make Robots!

Basic obstacle avoiding robot

uses ultrasound to navigate around obstacles

I came across the instructions to build this in a magazine and found it a great entry into robotics. It is working well but I'm still fine-tuning the programming. I would like to add to this project over time, to eventually include voice control, speech and other nice things. For the heavier software I have a Raspberry Pi that I want to incorporate into the robot. This is my first venture into robotics and i am having a ball!

 

Update (21/11/2013): I have finally managed to shoot some video of P1. He is working nicely now and although there are still a few minor hickups (can't see what's below his nose, occassionally get's stuck), I consider this project completed. I had heaps of fun and went from 'not-a clue' to 'have-some-idea-what"s-going-on'. Now, I'm working on my Pi-Bot, complete with camera, LCD display and more - he is going to be a quite sophisticated fellow.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

I put my components together on the test bench today and copied and pasted the code into one of those super cheap clone UNO R3's with the 340 USB to TTL chips on it and used the russian driver to get it to work and all went to plan, the motors were powered from a seperate supply and although it ate the batteries quickly it did what I expected it to do. I backed the max speed down to 50% and increased the ping distance just to see what would happen and I got the results that I was looking for, in all very pleased. Thanks to all for the info here, it helped greatly,Cheers, Terry.

since my last post I have been playing around with the programming of my beastie and am now thinking that most of my problems (getting stuck in corners , going towards obstacles) have very little to do with the software but with the unreliability of the sensor. Separate tests revealed that one of every 3 or 4 pings does not come back and therefore messes with the program. granted the sensor is a cheapy, but has anyone had better experiences with the more expensive models? Any advice welcome ;)

 

I have a bot that is almost exactly like this, that I built to play around with code on before intergrating 'intelligence' into my large mobile platform. One thing I noticed, is when running the arduino off a 9v battery, and the motors off 4 AA batteries.. my ultrasonic sensor was not working exact, I removed the 4 AA batteries and the 9v battery and now power the entire thing from a 11v 3cell R/C battery and it functions perfectly. Plus the battery weighs less and holds more of a charge.

I'd love to see your code, just to see how it compares to mine.

I have now changed the setup to run the motors from 4xAA batteries and the Arduino with a 9V and this seems to work better. I have also completely rewritten the software and made it a lot simpler - and now it actually works! It is stop - go at the moment but it rarely runs into walls now. I will have to incorporate some sort of bump sensor as low obstacles stay 'under the radar' but apart from that it works well. 

Here is my vastly simplified code 9still needs a bit of fine tuning):

#include <AFMotor.h>
#include <Servo.h>
#include <NewPing.h>

#define TRIG_PIN A4 // Pin A4 on the Motor Drive Shield soldered to the ultrasonic sensor
#define ECHO_PIN A5 // Pin A5 on the Motor Drive Shield soldered to the ultrasonic sensor
#define MAX_DISTANCE 200 // sets maximum useable sensor measuring distance to 200cm
#define MAX_SPEED 180 // sets speed of DC traction motors to 180/256 or about 70% of full speed - to get power drain down.
#define MAX_SPEED_OFFSET 40 // this sets offset to allow for differences between the two DC traction motors ****** from 20
#define COLL_DIST 10 // sets distance at which robot stops and reverses to 10cm
#define TURN_DIST COLL_DIST+10 // sets distance at which robot veers away from object (not reverse) to 20cm (10+10)
NewPing sonar(TRIG_PIN, ECHO_PIN, MAX_DISTANCE); // sets up sensor library to use the correct pins to measure distance.

AF_DCMotor motor1(1, MOTOR12_1KHZ); // create motor #1 using M1 output on Motor Drive Shield, set to 1kHz PWM frequency
AF_DCMotor motor2(2, MOTOR12_1KHZ); // create motor #2, using M2 output, set to 1kHz PWM frequency
Servo myservo;  // create servo object to control a servo

int leftDistance, rightDistance; //distances on either side
int curDist = 0;
String motorSet = "";
int speedSet = 0;

//-------------------------------------------- SETUP LOOP ----------------------------------------------------------------------------
void setup() {
  myservo.attach(9);  // attaches the servo on pin 9 (SERVO_2 on the Motor Drive Shield to the servo object
  myservo.write(90); // tells the servo to position at 90-degrees ie. facing forward.
  delay(1000); // delay for one seconds
 }
//------------------------------------------------------------------------------------------------------------------------------------

//---------------------------------------------MAIN LOOP ------------------------------------------------------------------------------
void loop() {
  myservo.write(90);  // move eyes forward
  delay(90);
  curDist = readPing();   // read distance
  if (curDist < COLL_DIST) {changePath();}  // if forward is blocked change direction
  moveForward();  // move forward for 1/2 second
  delay(500);
 }
//-------------------------------------------------------------------------------------------------------------------------------------

void changePath() {
  moveStop();   // stop forward movement
  myservo.write(36);  // check distance to the right
    delay(500);
    rightDistance = readPing(); //set right distance
    delay(500);
    myservo.write(144);  // check distace to the left
    delay(700);
    leftDistance = readPing(); //set left distance
    delay(500);
    myservo.write(90); //return to center
    delay(100);
    compareDistance();
  }

 
void compareDistance()   // find the longest distance
{
  if (leftDistance>rightDistance) //if left is less obstructed
  {
    turnLeft();
  }
  else if (rightDistance>leftDistance) //if right is less obstructed
  {
    turnRight();
  }
   else //if they are equally obstructed
  {
    turnAround();
  }
}


//-------------------------------------------------------------------------------------------------------------------------------------

int readPing() { // read the ultrasonic sensor distance
  delay(70);  
  unsigned int uS = sonar.ping();
  int cm = uS/US_ROUNDTRIP_CM;
  return cm;
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveStop() {motor1.run(RELEASE); motor2.run(RELEASE);}  // stop the motors.
//-------------------------------------------------------------------------------------------------------------------------------------
void moveForward() {
    motorSet = "FORWARD";
    motor1.run(FORWARD);      // turn it on going forward
    motor2.run(FORWARD);      // turn it on going forward
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet+MAX_SPEED_OFFSET);
    delay(5);
  }
}
//-------------------------------------------------------------------------------------------------------------------------------------
void moveBackward() {
    motorSet = "BACKWARD";
    motor1.run(BACKWARD);      // turn it on going forward
    motor2.run(BACKWARD);     // turn it on going forward
  for (speedSet = 0; speedSet < MAX_SPEED; speedSet +=2) // slowly bring the speed up to avoid loading down the batteries too quickly
  {
    motor1.setSpeed(speedSet);
    motor2.setSpeed(speedSet+MAX_SPEED_OFFSET);
    delay(5);
  }

//-------------------------------------------------------------------------------------------------------------------------------------
void turnRight() {
  motorSet = "RIGHT";
  motor1.run(FORWARD);      // turn motor 1 forward
  motor2.run(BACKWARD);     // turn motor 2 backward
  delay(400); // run motors this way for 400ms
  motorSet = "FORWARD";
  motor1.run(FORWARD);      // set both motors back to forward
  motor2.run(FORWARD);     

//-------------------------------------------------------------------------------------------------------------------------------------
void turnLeft() {
  motorSet = "LEFT";
  motor1.run(BACKWARD);     // turn motor 1 backward
  motor2.run(FORWARD);      // turn motor 2 forward
  delay(400); // run motors this way for 400ms
  motorSet = "FORWARD";
  motor1.run(FORWARD);      // turn it on going forward
  motor2.run(FORWARD);      // turn it on going forward

//-------------------------------------------------------------------------------------------------------------------------------------
void turnAround() {
  motorSet = "RIGHT";
  motor1.run(FORWARD);      // turn motor 1 forward
  motor2.run(BACKWARD);     // turn motor 2 backward
  delay(800); // run motors this way for 800ms
  motorSet = "FORWARD";
  motor1.run(FORWARD);      // set both motors back to forward
  motor2.run(FORWARD);     


will post a video as soon as I get around to it.

I have a similar design but with 4WD using adafruit motor shield. I would like to know how you connected the ultrasound because i have nothing to connect to on my motor shield which is on top of my arduino uno. Any other pix of your project will appreciate.

If I recall, I had to solder pin headers to my motor shield. The spot is there for them, you just need to solder them on.

hi, I am actually using a DK Electronics motor shield, not sure whether that is different to the adafruit. The ultrasonic sensor is attached with 4 dupont wires that I soldered onto the analog pin rails near the M3 connectors (bottom left of photo).

The connections are:

sensor    Vcc - Trig - Echo - Grnd

Board     +5 -  A4 - A5 - Grnd

Hope this helps.P1 - view from top

Looks very good!

I recognise that material from Tech studies, but I can't remember what it is called for the life of me! 

Very nice first robot build.

A quick tip; it looks like you are using the adafruit motor shield, I would recommend running the motors off a seperate power supply and removing the jumper on the PWR pins, this protects the Arduino from not getting enough current due to the motors drawing excessive current. Someone else may be able to eleborate in much better detail.

I have to mention aswell, It's nice seeing the list of Aussie builders growing!

Galvanized sheet metal. Doesn't rust, cheaper than stainless.

The metal was a donation from a work mate, he cut it to size and all - thanks Rob. Originally I had a piece of stiff plastic that wasn;t quite stiff enough. The front wheel is  the ball from an old  trackball mouse, rolls smoothly in any direction!