Friday, December 14, 2012

Basic roaming bot w/t ultrasonic object avoidance

Hope you enjoy this tutorial, if interested please check out my latest project/website. It's an attempt at creating an artificial neural network for predicting stock directions. As always, any feedback is appreciated  www.mspann.com

Now back to the robot...

This simple roaming bot uses an ultrasound sensor to avoid objects in its path...Once assembly is complete, the bot's performance is only limited by your creativity when programming the sketch.  I will include a simple sketch program which gets the bot moving and pings the sonar sensor to determine if objects are in it's path.


Parts List

  • Arduino Uno U3 - Ordered this through Amazon.com for about $20.00
  • Arduino Motor Shield L293D -  Also on Amazon.com about $16.00
  • Ultrasonic Sensor HC-SR04 - Amazon.com about $4.00          
  • RC Car (used for motors battery pack)- Picked up a  cheap $10.00 car at my local Duane Reade, and it came with 2 DC motors...hard to beat that deal.                                 
  • 9 V battery connector (to power Arduino board when not plugged into usb) - Radio Shack.
  • Soldering Iron 
  • Mini Tools (screw driver, wire cutter, etc.) - These are needed to unscrew RC car parts 
  • Jumper cables

Open up the RC car

Now that we have all the parts we will need, lets begin by taking the RC car apart to see what we're working with.  RC car parts will vary but most low end ones will have either 2 DC motors or 1 DC and one Servo motor. The 2 DC motor setup would mean one motor powers the left wheel and one powers the right wheel so you can have the car go forward, back and turns are handled by having one motor forward while the other goes back.   The 1 DC and 1 servo motor setup would work by having 2 tires connected to the DC motor this would control forward and back. The servo motor would then be connected to the steering wheels turning them left or right.  

This RC car has 2 DC motors, each connected to one rear wheel.

If you look at the 3rd picture the wires leading from the DC motors of the rear wheels are red and black for the top wheel and white and yellow for the bottom wheel.

Those two shiny metal strips with a screw holding them in place, are the power connected to the battery pack which is directly underneath the metal strips and next to the motors.  This top is negative and the bottom is positive...this car uses 4 AA batteries at 1.5 v each that's a total of 6 v.  That means we will not have enough power for 2 motors and the Arduino board, we will need a secondary power source to supply the Arduino. This will come from your USB cable when plugged into the computer for programming and from the 9 v battery when the bot is disconnected from the USB and out roaming.

We don't need the RC cars controll board, so lets go ahead and clip all the wires connecting to it.

You see that red wire leading into that piece in the middle, that's the on off switch for the RC car. We will use this switch later.


Arduino and Motor Shield

We are almost ready for testing, first you will need to attach the Motor Shield L293D to the Arduino Uno board.  Align the pins and piggyback the Motor Shield to the top of the Arduino.



+=

Testing the Motors

The Arduino and Motor shield are ready for testing.
Connect one of the DC Motor's to the M1 screw pins on the Motor Shield.


In this picture it's the red and black wires going into the top right 2 screw pins...The top of the board has 5 screw pins, use the top 2 on the right for M1 the top 2 on the left are for M2 (yellow white wires) we will use that later.

Download and install the Motor Shield's library library download
Rename the folder to AFMotor place it along with all sub folders and files in your
My Documents/Arduino /libraries folder.
The Arduino IDE will need to started before the library is recognized, if the IDE is already open, simply quit and re-open.

Use the following code to run your test. This will run the motor forward 1 second, back 1 second and stop 1 second...Then the it will repeat (infinitely).

Sketch code - motor test


#include <AFMotor.h>
AF_DCMotor motor(1, MOTOR12_64KHZ); // create motor #1, 64KHz pwm
void setup() 
{
motor.setSpeed(200); // set the speed to 200/255
}
void loop() 
{
motor.run(FORWARD); // turn it on going forward
delay(1000);

motor.run(BACKWARD); // the other way
delay(1000);

motor.run(RELEASE); // stopped
delay(1000);
}

Once you created your sketch using the code above, connect the Arduino to the PC using the USB cable and upload your sketch.  The code above will begin executing and the motors should begin to run forward, back, stop...repeat.


Test the Sensor

Now we, want to test the ultrasonic sensor.
You will need to solder 4 jumper cables to the sensor's pins.














Connect the Sensor's wires to the Arduino Motor shield.

The 2 red wires go to the shield's 5V and GND pins.The white(echo) and green (trig) connect to the shield's 2 and 3 pins.

Don't worry about the cardboard box for the sensor, I just added that because it will be part of the finished bot, but you don't need it at this testing stage.

After the sensor is connected, we are ready to test.




Use the code below to test the ultrasonic range finder.

Sketch code - ultrasonic test


#define trigPin 3
#define echoPin 2

void setup() 
{
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
}

int CheckDistance()
{
  long duration, distance;
  digitalWrite(trigPin, LOW);  // Added this line
  delayMicroseconds(2); // Added this line

  digitalWrite(trigPin, HIGH);
//  delayMicroseconds(1000); - Removed this line
  delayMicroseconds(10); // Added this line
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  
  return distance;
}

void loop() 
{
   int testDistance = CheckDistance(); /// get object distance using ping
   
   /// if object is more than 50 cm away it is out of range
    if (testDistance >= 50 || testDistance <= 0) /// if object is more than 50 cm away it is out of range
    {
    Serial.println("Out of range");
    }
    else /// object is closer than 50cm, prit distance
    {
    Serial.print(testDistance);
    Serial.println(" cm");
    }
   
  delay(500); ///wait half a sec before next ping
}

Connect the Arduino to the PC using your USB cable and upload the above sketch.  To see the ping distance results go to Tools, Serial Monitor in the IDE while the sketch is running, here the ping distance values will be printed.


Assemble the bot

Lets connect all the motors and sensor to the Arduino so we can test the entire bot. Some of these wire connections may need soldering, to keep them fastened securely to the motor shield.

  • Connect the 2 DC motors to M1 and M3 on the Motor shield. The white and yellow wires did not reach up to the M3 pins so I extended them with some red wire...don't forget to cover the connection point of the 2 wires with electrical tape.

  • Connect the power from the RC car's positive battery (it's the black wire on the RC car's bottom metal strip) to the motor shield's PWR pin screw.  If you don't know which battery metal strip is positive, open up the battery case and check which side of the AA battery touches that piece of the metal strip where the wire connects.
  • Connect the ground (black wire) from the RC car's on/off switch to the GND pin screw on the motor shield.
  • Connect the ultrasound sensor's wires to the motor shield.  The 2 red wires go to the shield's 5V and GND pins.The white(echo) and green (trig, looks blue in the pic but it's green) connect to the shield's 2 and 3 pins.




  • Connect the external 9v battery power to the Arduino board.  This is so we will no longer need the USB to power the Arduino.

 


  • Finally, upload your sketch and run one last test.

Sketch code - roaming bot test


This sketch will have the robot ping to find if there is an object within range.  If no objects are within range it will continue forward a small distance then ping again.  If an object is found it will perform a sequence of commands to try and avoid the object (move back, turn, etc.).  Then the whole process repeats in an infinite a loop.

#include <AFMotor.h>
#define trigPin 3
#define echoPin 2
AF_DCMotor motor1(1, MOTOR12_8KHZ); // create motor #1, 8KHz pwm
AF_DCMotor motor3(3, MOTOR34_8KHZ); // create motor #3, 8KHz pwm

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  motor1.setSpeed(255); // set the speed to 200/255
  motor3.setSpeed(255); // set the speed to 200/255
}

int CheckDistance()
{
  long duration, distance;
  digitalWrite(trigPin, LOW);  // Added this line
  delayMicroseconds(2); // Added this line

  digitalWrite(trigPin, HIGH);
//  delayMicroseconds(1000); - Removed this line
  delayMicroseconds(10); // Added this line
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  
  return distance;
}

void MotorForward(int delaytime)
{
  motor1.run(FORWARD);
  motor3.run(FORWARD);
  delay(delaytime);
}
void MotorBackward(int delaytime)
{
  motor1.run(BACKWARD);
  motor3.run(BACKWARD);
  delay(delaytime);
}
void MotorRelease()
{
  motor1.run(RELEASE);
  motor3.run(RELEASE);
  delay(1000);
}

void MotorLeft()
{
  motor1.run(FORWARD);
  motor3.run(BACKWARD);
  delay(600);
}

void MotorRight()
{
  motor1.run(BACKWARD);
  motor3.run(FORWARD);
  delay(500);
}

void loop() 
{
  int testDistance = CheckDistance();
  
   Serial.print(testDistance);
   Serial.println(" test");
   
  if (testDistance >= 30 || testDistance <= 0){
    Serial.println("Out of range");
    //go forward and check range again
    MotorForward(700);
    MotorRelease();
  }
  else 
  {
    Serial.print(testDistance);
    Serial.println(" cm");
    //object in path, reverse and turn to avoid
    MotorBackward(600);
    MotorRelease();
    MotorRight();
    MotorRelease();
    MotorForward(600);
    MotorRelease();
    MotorLeft();
    MotorRelease();
    
  }
   
  delay(500);
}

*** Pro tips 
  • I settled on the sketch code above after a lot of trial and error.  My previous sketches would work fine in testing but not once the completed bot was set free. My main problems were, I had the DC motors running at the same time I was trying to ping, this caused interference in the circuitry and resulted in bogus ping readings, which in turn resulted in the robot malfunctioning...The above sketch resolves this issue by making sure all motors are off (released) when the ping occurs.
  • The frequency of the DC motors declared in your sketch may be different from the one I used here, basically your options would be either: MOTOR12_64KHZ, KHZMOTOR12_8KHZ or MOTOR12_1KHZ  Test a few of these out to see which freq your motors respond best to. I believe the default would be 1khz.
  • When I dismantled the RC car, some of the joints supporting the RC car's battery contacts loosened.  I noticed this during testing when I squeezed my hand against the car's battery door, the motor speed would increase.  I tightened these connections and this resolved the power leak issue.

Now with our final systems testing completed, we can attach the outer shell to the bot for aesthetics and let it run around.



Robot Shell

With our testing complete, it's time to think about the robot's appearance.  Feel free to get really creative with this part.  I decided to use what I had laying around, some cardboard I scrapped from a box one of the Arduino boards were shipped in. One of the cardboard pieces had this 'V3' printed on it, so I thought it would look cool to have that on the front of the bot.




I cut out some pieces and came up with the rough design of what the bot will look like. I loosely placed the shell parts on the robot to see how they fit, there is a bit of trial and error here so don't worry if it doesn't look good right away.

Once satisfied with the shell, go ahead and attach it to the bot.  I mostly used scotch tape and twist ties to attach the cardboard pieces to the frame of the old RC car.  Since I didn't attach a switch for the 9v battery, I cut out a hole in the back for the battery  to be able to disconnect the 9v battery wires whenever it wasn't being used.

 


It's Alive!

Now that everything was tested and assembled, it's time to let this little bot roam free and see what it does...enjoy!

video


As you can see from the video, the sketch definitely needs more tweaking...but the basics are there...It went forward, detected an object then reversed and tried to turn (probably should increase the turning time). Hope you enjoyed this tutorial and please feel free to post any questions or comments below.



16 comments:

  1. Hi my name i will just love ur bot and will try your design however i will mount mine on a toy tank with tqo seperate motors.

    My email is huwissp@hotmail.com would love to hear from you!

    ReplyDelete
    Replies
    1. Hi there, glad you like the tutorial and I hope you find it helpful. The toy tank sounds like a cool idea, I'd like to see how it turns out.

      Delete
  2. It could be much better if you expand the tutorial in order to build more complex robotics applications http://www.intorobotics.com/interfacing-programming-ultrasonic-sensors-tutorials-resources/

    ReplyDelete
    Replies
    1. Calin, you are absolutely right..I would like to expand further and get into some more complex designs.

      Delete
  3. Hi Arthur, I am a student and I am performing almost the same project that you have made, just asking that if I am the one who is controlling the car by an android device then how to configure on the ultrasonic that it will not move by itself rather only change direction before hitting any obstacle and then keeps on checking any idea about that please help me and thank you in advance

    ReplyDelete
    Replies
    1. Hi there, your project sounds very interesting I'm curious as to how it will turn out. A bot which is controlled by an android device yet it still will try to automatically avoid objects if the ultrasound detects it. I think it's a great idea, but it will be challenging. The main challenge I see is having the sketch code run the ultrasound function to determine object distance simultaneously as the rest of the sketch code is receiving / transmitting instructions from the android device. I have yet to try something like this, so I don't have a proven solution for you. I think you might want to try something where you write the sketch code in such a way where the robot is listening for instructions from the android device (ex. move forward). When it receives the instructions to begin moving forward it does so for a specified amount of time. Then Stop (regardless of instruction from android). then run a separate function to check using ultrasound if there is an object ahead. If yes, run some commands to change direction and go back to android instructions, if No then go back to listen for instructions from Android device. Hope this helps, good luck and let me know how your project goes.

      Delete
    2. Hi Arthur, thanks for the reply and I have some questions regarding how much volts the motor shield can handle as in maximum, plus, If I had a battery which is 19V will it burn the circuit or not, plus, I saw a bit of smoke when we connected the 19V to the external power not under the arduino Uno power, also, about the android controlling the toy car via Bluetooth, I will explain about my project in more detail

      Delete
  4. Hi Arthur

    im building like your project with car that run 2 motor in each side its like tank
    i tried different sketch but non worked for me, i was wondering if you can help me on that i will appreciate it. im using arduino uno, motor contro shield like yours and distance sensor like the one you are using,

    thank you

    ReplyDelete
  5. Great project! Thanks for posting the details. Curious why you chose motor3 connection in your code instead of motor2? I tried your code on my bot but modified it to create a motor2 and it did not work. When I reset it to use motor 3 and hooked my motor to that connection it worked fine. Don't you think it should work either way?

    ReplyDelete
  6. I made a robot using the same rc car that you used. I've found 3 of them so far at goodwill for a few bucks each. Originally I had used the HC-SR04 as you did, but I fried it I think. While waiting for my replacement to come in the mail I used push buttons to work as bump sensors. A couple of differences in my design: I took off the front wheels and added a caster so it can turn more freely. I used the rc car's board and soldered into the motor controller to save myself buying the motor board; it wasn't too difficult for a novice like me. Here is a video off the bot doing what it does best, "bumping and tipping."
    simple arduino robot - https://www.youtube.com/watch?v=qVPjyqYX6mA

    ReplyDelete
  7. This comment has been removed by a blog administrator.

    ReplyDelete
  8. Nice blog thanks for sharing this tutorials. For more robotics tutorials and learning visit Robotics tutorials

    ReplyDelete
  9. Hi, why do you devide by 29.1? You devide the distance by 2 because the lenght of the signal is for going to the object and the way back, but then why 29.1 instead of 58? I cant wrap it arround my head... Looking forward for your answer. Thank you in advance.

    ReplyDelete
  10. Nice project, thank you.
    But I have a question, the 2 dc motors turns and stop and turns and stop if nothing in front of ultrasonic. I want the 2 motors still spin untill ultrasonic catch somthing in front of it then the car move backward and move forward.

    ReplyDelete
  11. Really very interesting and very valuable information about the carshield reviews it's good work.
    carshield reviews

    ReplyDelete
  12. You have some honest ideas about the automobile repairs share here I really get many information and discovered most peoples will agree with your blog.
    automobile repairs

    ReplyDelete