This small Arduino obstacle-avoiding robot is an experiment in reducing
the size and complexity of larger kit and Do It Yourself (DIY) robots.
Bot Mechanics: | |
I started with an enclosed 4-cell AA battery pack. This had an advantage of having a small slide switch mounted in the case, so you don't have to keep disconnecting the power connector. | |
Two mini (9g) continuous rotation servo motors (RobotShop.com ~$5 / ea.) were attached to the back of the battery case using double-stick foam tape. Hot glue further secures the motors to the case, but probably is not needed as long as the tape is reasonably fresh and tacky. | |
A pair of small wheels off of a toy car were hollowed out, and were the perfect size for the round disk servo horn. The horn disk was press-fit into the wheel and super-glued in place. Hot glue on the inside of the wheel adds additional support between the disk and the inside surface. | |
A breadboard was trimmed down on the band saw to make a better fit, and the double-stick foam backing used to anchor the board to the lid of the battery box. | |
A piece of 1/8" plastic sheet was trimmed to make a mount for a 4-pin ultrasonic sensor module. Using a pencil, the position of the two cylindrical sensors was marked out on the plastic, and holes cut using a Dremel tool with a multi-purpose routing drill. A small piece of sticky-back Velcro helps space the sensor from the plastic and help hold it in place. Two O-rings are added to hold the sensors in the openings. A bead of hot glue was run along the edge of the breadboard and two small screws anchor the sensor assembly securely to the bot. | |
For the front wheel, a tiny ball-bearing was screwed to the battery box. (The front end of the box is mostly empty space, so there is no chance of shorting the batteries.) A hunt in the junk box came up with a small wheel assemble from some old printer parts, and a valve stem cap from a bicycle tire that fits over the bearing perfectly. A little cutting and sanding of the plastic frame with the tiny wheel, and then the two parts were glued together with more hot glue. | |
Bot Electronics: | |
The Arduino Nano connects directly into the breadboard. This is mounted at the rear of the board to allow access with the USB cable for programming the bot. A ground wire is connected between one of the negative rails and the "GND" pin on the Nano. Power is provided by a wire running from "VIN" on the Nano to the positive 5v rail. | |
The power wires from the battery pack are cut off close to the front of the breadboard. The positive (red) and negative (black) wires are each soldered to a pair of pins in a 2x2 connector and hot glue used to insulate the exposed pins. This fabricated connector plugs into one of the power rails of the breadboard. (This will be our 6v rail - assuming there are four 1.5v Alkaline batteries in the box) | |
A 5v regulator has the input pin bent out and a red wire soldered to it. (Hot glue can coat the exposed pin, or use a small piece of heat-shrink tubing to cover it.) The center pin (ground) and 5v output pin are trimmed off and inserted directly into the second power rail of the breadboard. (Note that this step is probably not required, but was done only as a precaution to provide 5v or less for the ultrasonic sensor and Arduino boards.) The red wire has the end soldered to a single pin or is stiffened by tinning the end with solder. This is then connected to the positive side of the 6v rail from the batteries. A wire connects both negative (ground) rails together. | |
Servo Motor wires have the signal wire split off and the power wires trimmed shorter. Another 2x2 pin connector has the two servo motor ground wires soldered on, and the two power wires soldered on the remaining two pins. Hot glue to insulate, and then the servo motor power is connected to the 6v rail. The two signal wires from the servo motors have enough reach to be connected to any of the Arduino pins. These each have a small pin soldered to the end and insulated with hot glue. Servo motor signal wires are attached to Arduino D10 and D11. | |
A four-wire connector is prepared for the sonar module. The outside power (Vcc and Gnd) connections are soldered to a pair of pins and connected to the 5v power rail. The inside pair of pins (Trig and Echo) are soldered to another pair of pins and connected to D5 and D6. |
Programming: |
Sample sketches are included. MiniPingBot1_0.ino is the first attempt to create a very simple program that uses a single ping to check distance. Then, based on the result, it moves forward, or if it detects an obstacle close by, backs up, rotates to the left and continues. This sketch is using the NewPing library and the core routines from the whisker-bot sketch from Parallax. |
#include <NewPing.h> // include new-ping library
#include <Servo.h> // Include servo library
#define TRIGGER_PIN 5 // using 4-pin Ping Sensor
#define ECHO_PIN 6
#define MAX_DISTANCE 200 // max distance is 500cm (~16.4 ft)
Servo servoLeft; // Declare left and right servos
Servo servoRight;
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); //declare sonar (ping sensor)
void setup() {
servoLeft.attach(10); // Attach left servo signal to pin 13
servoRight.attach(11); // Attach right servo signal to pin 12
//Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results
}
void loop() {
delay(50); //wait 50ms between pings
int uS = sonar.ping_cm(); // get distance in cm from sensor
// based on distance, do something...
// if uS = 0 distance to object is >= MAX_DISTANCE
//Serial.print("Ping: "); // Monitor ping results in
//Serial.print(uS); // serial monitor window
//Serial.println("cm"); // comment out when done debugging
if (uS > 30) {
forward(300); // forward 1/2 second
}
else {
backward(100); // obstacle detected closer than MAX_DISTANCE
turnLeft(400); // try turning left a bit and check again
}
}
// Servo control from Parallax BOE-Bot Whisker sketch
void forward(int time) // Forward function
{
servoLeft.writeMicroseconds(1700); // Left wheel counterclockwise
servoRight.writeMicroseconds(1300); // Right wheel clockwise
delay(time); // Maneuver for time ms
}
void turnLeft(int time) // Left turn function
{
servoLeft.writeMicroseconds(1300); // Left wheel clockwise
servoRight.writeMicroseconds(1300); // Right wheel clockwise
delay(time); // Maneuver for time ms
}
void turnRight(int time) // Right turn function
{
servoLeft.writeMicroseconds(1700); // Left wheel counterclockwise
servoRight.writeMicroseconds(1700); // Right wheel counterclockwise
delay(time); // Maneuver for time ms
}
void backward(int time) // Backward function
{
servoLeft.writeMicroseconds(1300); // Left wheel clockwise
servoRight.writeMicroseconds(1700); // Right wheel counterclockwise
delay(time); // Maneuver for time ms
}
|
MiniPingBot1_1 changes the method of determining distance with the sensor. One problem I noticed with the 1.0 version of the code was that the ping sensor would occasionally return a bad value and cause the bot to correct multiple times, even when no obstacle was close. Using the PING_MEDIAN function, five pings are used and the median result is returned to the program. This seems to eliminate the odd course corrections. |
int uS = sonar.ping_cm();
// get distance in cm from sensor uS using single ping
becomes: unsigned int uS = (sonar.ping_median() / US_ROUNDTRIP_CM);
// Get average distance for 5 pings, convert to cm
// US_ROUNDTRIP_CM = distance sound travels in cm/sec
|
MiniPingBot files (zip) <== Click to download the MiniPingBot 1.0 & 1.1 sketch files and NewPing library. To use: extract the contents of this zip file to your Arduino working directory. Open the containing folder for the Arduino.exe program and locate the "libraries" subdirectory. Copy the entire "NewPing" folder into the libraries directory. |
For more assistance contact Technical Support here.