My first robot

I wasn't planning on getting into robots with the Arduino but I saw this at the dollar store for five bucks:

A few hours later it was this:

Pretty neat little dude :slight_smile: I "neutered" a couple of servos and rigged them up to drive it. I have a couple of sr04 ping sensors so I guess I'll build an obstacle avoiding robot. I just ran the servos directly off the pins (Not good, I know) but I have a motor shield.

I want to build a bot with the ping sensor mounted to a servo or either 2 sensors. Any advise?

Here is a link that I found useful. Arduino 4wd robot & Ping))) sensor | AK Eric
Also try searching Google for " ping scan robot ".

Best thing is to use a separate battery to power the servos. I use
4-6 rechargeable NiMH AA-cells in series to power all of my robots.
Those cells have 2000-2500 mA-hr of energy and can run your robot
for several hours.

Also, in the Files -> Examples section of the Arduino IDE, there are
example sketches for controlling servos and PIng sonars, etc.

Hi,
I am seriously jealous of your chassis ! I built a paper shell for my robot thinking the kids might like it but there were completely dismissive of it. If I had had that chassis I would never get the thing back from them.

As for advice, if you have kids, try and mount the electronics underneath so that you can keep the original design on top.

Duane B

rcarduino.blogspot.com

Well, here he is now:

There's room for 8 AA's and a small breadboard.

Thanks for the input guys!

Now to get him working :slight_smile: I have an Arduino motor shield and my sensor is an SR04 so the code is going to be different from a regular PING.

//"Arduino Garage Tennis Ball."  A distance sensor with LED Stoplights for people with multiple vehicles going into a limited space.
#include <Servo.h> // includes library

Servo servoLeft;
Servo servoRight;

const int triggerPin = 8;
const int echoPin = 9;
int redPin=13;
int yellowPin=12;
int greenPin=11;
long duration;
long distance;

void setup(){
  servoLeft.attach(10);
  servoRight.attach(7);
  
  
  pinMode (13, OUTPUT);
  pinMode (12, OUTPUT);
  pinMode (11, OUTPUT);
  Serial.begin(9600);
}

void loop()
{
  servoLeft.write(0);
  servoRight.write(180);
  
  int stopDistance=6;//object distance in inches from sensor that you want to trigger the Red LED.
  int warnDistance=60;//object distance in inches from sensor that you want to trigger the Yellow LED.
  pinMode(triggerPin, OUTPUT);
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(2);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(triggerPin, LOW);
  pinMode(echoPin, INPUT);
  duration = pulseIn(echoPin, HIGH);
  distance = duration / 72 / 2;//determines distance in inches of object from sensor by microseconds to inches formula.
  if (distance >= warnDistance){
    digitalWrite (redPin, LOW);
    digitalWrite (yellowPin, LOW);
    digitalWrite (greenPin, HIGH);
  }
  else if((distance>stopDistance) && (distance<warnDistance)){
    digitalWrite (redPin, LOW);
    digitalWrite (yellowPin, HIGH);
    digitalWrite (greenPin, LOW);
  }
  else{
    digitalWrite (redPin, HIGH);
    servoLeft.write (0);
    delay (2000);
    servoRight.write (0);
    delay (2000);
    
    digitalWrite (yellowPin, LOW);
    digitalWrite (greenPin, LOW);
  }
  Serial.println (distance);
}

Here's what it does:

Any help on what I'm missing?

DuaneB:
I built a paper shell for my robot

How do you mean, paper, Duane? Like paper mache?

/*MAEP 2.0 Navigation
by Noah Moroze, aka GeneralGeek
This code has been released under a Attribution-NonCommercial-ShareAlike license, more info at http://creativecommons.org/licenses/
PING))) code by David A. Mellis and Tom Igoe http://www.arduino.cc/en/Tutorial/Ping
*/

#include <Servo.h> //include Servo library

const int RForward = 0; 
const int RBackward = 180; 
const int LForward = RBackward; 
const int LBackward = RForward; 
const int RNeutral = 90; 
const int LNeutral = 90; //constants for motor speed

//////
const int triggerPin = 8;
const int echoPin = 9;  //Sharp infrared sensor pin

/////
const int dangerThresh = 10; //threshold for obstacles (in cm)
int leftDistance, rightDistance; //distances on either side
Servo panMotor;  
Servo leftMotor;
Servo rightMotor; //declare motors
long duration; //time it takes to recieve PING))) signal

//////
long distance;

/////
void setup()
{
  rightMotor.attach(11);
  leftMotor.attach(10);
  panMotor.attach(6); //attach motors to proper pins
  panMotor.write(90); //set PING))) pan to center
  Serial.begin(9600);
}

void loop()
{
  int distanceFwd = ping();
  if (distanceFwd>dangerThresh) //if path is clear
  {
    leftMotor.write(LForward); 
    rightMotor.write(RForward); //move forward
  }
  else //if path is blocked
  {
    leftMotor.write(LNeutral);
    rightMotor.write(RNeutral); 
    panMotor.write(0); 
    delay(500);
    rightDistance = ping(); //scan to the right
    delay(500);
    panMotor.write(180);
    delay(700);
    leftDistance = ping(); //scan to the left
    delay(500);
    panMotor.write(90); //return to center
    delay(100);
    compareDistance();
  }
}
  
void compareDistance()
{
  if (leftDistance>rightDistance) //if left is less obstructed 
  {
    leftMotor.write(LBackward); 
    rightMotor.write(RForward); //turn left
    delay(500); 
  }
  else if (rightDistance>leftDistance) //if right is less obstructed
  {
    leftMotor.write(LForward);
    rightMotor.write(RBackward); //turn right
    delay(500);
  }
   else //if they are equally obstructed
  {
    leftMotor.write(LForward); 
    rightMotor.write(RBackward); //turn 180 degrees
    delay(1000);
  }
}

long ping()
{
  // Send out PING))) signal pulse
  pinMode(triggerPin, OUTPUT);
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(2);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(triggerPin, LOW);
  
  //Get duration it takes to receive echo
  pinMode(echoPin, INPUT);
  duration = pulseIn(echoPin, HIGH);
  
  
  //Convert duration into distance
  return duration / 29 / 2;

{
   
  
  Serial.println (distance);
}}

I'm trying to get serial output of what the sensor is seeing. It works with the first sketch I posted but I'm not having any luck with this...

This prints to the monitor when something gets close to the threshold:

/*MAEP 2.0 Navigation
by Noah Moroze, aka GeneralGeek
This code has been released under a Attribution-NonCommercial-ShareAlike license, more info at http://creativecommons.org/licenses/
PING))) code by David A. Mellis and Tom Igoe http://www.arduino.cc/en/Tutorial/Ping
*/

#include <Servo.h> //include Servo library

Servo servoLeft;
Servo servoRight;
Servo servoScan;

//////
const int triggerPin = 8;
const int echoPin = 9;  //Sharp infrared sensor pin

/////
///const int dangerThresh = 10; //threshold for obstacles (in cm)
int leftDistance, rightDistance; //distances on either side

long duration; //time it takes to recieve PING))) signal

//////
long distance;

/////
void setup()
{
  servoLeft.attach(11);
  servoRight.attach(10);
  servoScan.attach(6); //attach motors to proper pins
  servoScan.write(90); //set PING))) pan to center
  Serial.begin(9600);
}

void loop()
{
  int dangerThresh = 10;
  
  
  ///int distanceFwd = ping();
  
   pinMode(triggerPin, OUTPUT);
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(2);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(triggerPin, LOW);
  pinMode(echoPin, INPUT);
  duration = pulseIn(echoPin, HIGH);
  distance = duration / 72 / 2;
  
  
  if (distance>dangerThresh) //if path is clear
  {
    servoLeft.write(180); 
    servoRight.write(0); //move forward
  }
  else //if path is blocked
  {
    servoLeft.write(90);
    servoRight.write(90); 
    servoScan.write(0); 
    delay(500);
    rightDistance = ping(); //scan to the right
    delay(500);
    servoScan.write(180);
    delay(700);
    leftDistance = ping(); //scan to the left
    delay(500);
    servoScan.write(90); //return to center
    delay(100);
    compareDistance();
  }
}
  
void compareDistance()
{
  if (leftDistance>rightDistance) //if left is less obstructed 
  {
    servoLeft.write(180); 
    servoRight.write(180); //turn left
    delay(500); 
  }
  else if (rightDistance>leftDistance) //if right is less obstructed
  {
    servoLeft.write(0);
    servoRight.write(0); //turn right
    delay(500);
  }
   else //if they are equally obstructed
  {
    servoLeft.write(0); 
    servoRight.write(0); //turn 180 degrees
    delay(1000);
  }
}

long ping()
{
  // Send out PING))) signal pulse
  pinMode(triggerPin, OUTPUT);
  digitalWrite(triggerPin, LOW);
  delayMicroseconds(2);
  digitalWrite(triggerPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(triggerPin, LOW);
  
  //Get duration it takes to receive echo
  pinMode(echoPin, INPUT);
  duration = pulseIn(echoPin, HIGH);
  
  
  //Convert duration into distance
  
  ////return duration / 29 / 2;
  
  distance = duration / 72 / 2;

{
   
  
  Serial.println (distance);
}}

It's getting closer but he's still pretty spastic :stuck_out_tongue:

In this sketch, I think you need something like this:

distance =  ping();
Serial.println (distance);

I say this because I do not see where you are getting the latest value for distance. You define the variable distance before the set-up but, you never change it's value.

Currently, you are using the function ping() to = int distanceFwd .

In your previous sketch you did work with the variable distance:

distance = duration / 72 / 2;//determines distance in inches of object from sensor by microseconds to inches formula.

Thanks! I edited my last post with some updated code. I'm slowly working my way through the different parts of the sketch to try and understand what is doing what.

Here's the original code:

/*MAEP 2.0 Navigation
by Noah Moroze, aka GeneralGeek
This code has been released under a Attribution-NonCommercial-ShareAlike license, more info at http://creativecommons.org/licenses/
PING))) code by David A. Mellis and Tom Igoe http://www.arduino.cc/en/Tutorial/Ping
*/

#include <Servo.h> //include Servo library

const int RForward = 0; 
const int RBackward = 180; 
const int LForward = RBackward; 
const int LBackward = RForward; 
const int RNeutral = 90; 
const int LNeutral = 90; //constants for motor speed
const int pingPin = 7;
const int irPin = 0;  //Sharp infrared sensor pin
const int dangerThresh = 10; //threshold for obstacles (in cm)
int leftDistance, rightDistance; //distances on either side
Servo panMotor;  
Servo leftMotor;
Servo rightMotor; //declare motors
long duration; //time it takes to recieve PING))) signal

void setup()
{
  rightMotor.attach(11);
  leftMotor.attach(10);
  panMotor.attach(6); //attach motors to proper pins
  panMotor.write(90); //set PING))) pan to center
}

void loop()
{
  int distanceFwd = ping();
  if (distanceFwd>dangerThresh) //if path is clear
  {
    leftMotor.write(LForward); 
    rightMotor.write(RForward); //move forward
  }
  else //if path is blocked
  {
    leftMotor.write(LNeutral);
    rightMotor.write(RNeutral); 
    panMotor.write(0); 
    delay(500);
    rightDistance = ping(); //scan to the right
    delay(500);
    panMotor.write(180);
    delay(700);
    leftDistance = ping(); //scan to the left
    delay(500);
    panMotor.write(90); //return to center
    delay(100);
    compareDistance();
  }
}
  
void compareDistance()
{
  if (leftDistance>rightDistance) //if left is less obstructed 
  {
    leftMotor.write(LBackward); 
    rightMotor.write(RForward); //turn left
    delay(500); 
  }
  else if (rightDistance>leftDistance) //if right is less obstructed
  {
    leftMotor.write(LForward);
    rightMotor.write(RBackward); //turn right
    delay(500);
  }
   else //if they are equally obstructed
  {
    leftMotor.write(LForward); 
    rightMotor.write(RBackward); //turn 180 degrees
    delay(1000);
  }
}

long ping()
{
  // Send out PING))) signal pulse
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  
  //Get duration it takes to receive echo
  pinMode(pingPin, INPUT);
  duration = pulseIn(pingPin, HIGH);
  
  //Convert duration into distance
  return duration / 29 / 2;
}

Along with the project link: http://www.instructables.com/id/How-To-Make-an-Obstacle-Avoiding-Arduino-Robot/

Hi,

Regarding the paper body shell, I made a few paper templates and ran them for a while before cutting a final version from plastic card. The plastic card version is reinforced in the joins using epoxy putty. It works well as a quick way to build a body.

Two other ideas I have seen are paper craft, these are printed nets that you can download, cut out and fold to get cars, tanks, planes, robots etc.

Another nice idea I have seen is cutting bodyshells from aluminium baking trays, same idea as paper nets, but these are easy to weather and dent for a post apocalyptic look.

Off topic - (only a little bit, why shouldn't our robots have decent bodyshells ?)

An example of some not quite post apocalyptic weathering on a plastic bodyshell of mine -

More here -

Duane B

rcarduino.blogspot.com

I do like the Baja Bug...

I found some paper nets- so far only London buses but Google will find more when I search properly. Thanks for that idea.

Edit...There are some nice nets here at Papertoys

Seems I need to pop down to the China Mall or whatever it's called today for a look around at toys. Basically an aircraft hangar sized mall with individual shops all selling cheap junk... might find a toy or two to use.

Nice work on the baja! I like the weathered look, in fact I thought I was looking at a real car 8)

I decided to give the copy/paste a rest. It's really confusing and I'm learning more by "writing" code than just tinkering with other peoples.

I'm just starting over here:

#include <Servo.h>

Servo servoLeft;          // Define left servo
Servo servoRight;         // Define right servo
Servo servoScan;          // Define US scan servo

void setup() { 
  servoLeft.attach(10);  // Set left servo to digital pin 10
  servoRight.attach(9);  // Set right servo to pin 9
  servoScan.attach(11);  // Set scan servo to digital pin 11
} 

void loop() {            // Loop through motion tests
  forward();             // Example: move forward
  delay(2000);           // Wait 2000 milliseconds (2 seconds)
  reverse();
  delay(2000);
  turnRight();
  delay(2000);
  turnLeft();
  delay(2000);
  stopRobot();
  delay(5000);
  servoScan.write(90);
  
  ///scan

  
}

// Motion routines for forward, reverse, turns, and stop
void forward() {
  servoLeft.write(0);
  servoRight.write(180);
}

void reverse() {
  servoLeft.write(180);
  servoRight.write(0);
}

void turnRight() {
  servoLeft.write(180);
  servoRight.write(180);
}
void turnLeft() {
  servoLeft.write(0);
  servoRight.write(0);
}

void stopRobot() {
  servoLeft.write(90);
  servoRight.write(97);
  //////
  
  if (stopRobot) {
    servoScan.write(0);
    delay(1000);
    servoScan.write(180);
    delay(1000);
    servoScan.write(90);
    
  }
    
    /////
  {
  }}

I need to get the "scan" servo code more in line with the rest of the sketch and work on "if" "else" but I understand a lot more about what's happening now. I also had to regroup some on the hardware because 90 wasn't stopping one of my servo's. Weird that it took a value of 97... but it now stops. That was causing me some grief.

I added a longer delay for the STOP, plus 1 sec delays on the scanning servo but it seems like there is some kind of accumulation because it stops for 7 seconds. I'm guessing that the scan + motor delay is doing this?

I plan on just working towards:

Forward until obstacle- stop- scan R & L- print values- reverse. Then work from there.

I have all the puzzle pieces, I just need to fit them together.

I'm a hobby machinist/weldor so I hope to take what I'm learning and scale it up to some type of yard rover.

Here he is:

Well, here he is:

/*MAEP 2.0 Navigation
by Noah Moroze, aka GeneralGeek
This code has been released under a Attribution-NonCommercial-ShareAlike license, more info at http://creativecommons.org/licenses/
PING))) code by David A. Mellis and Tom Igoe http://www.arduino.cc/en/Tutorial/Ping
*/

#include <Servo.h> //include Servo library

const int RForward = 0; 
const int RBackward = 180; 
const int LForward = RBackward; 
const int LBackward = RForward; 
const int RNeutral = 97; 
const int LNeutral = 90; //constants for motor speed
const int pingPin = 12;
const int irPin = 13;  //Sharp infrared sensor pin
const int dangerThresh = 10; //threshold for obstacles (in cm)
int leftDistance, rightDistance; //distances on either side
Servo panMotor;  
Servo leftMotor;
Servo rightMotor; //declare motors
long duration; //time it takes to recieve PING))) signal

void setup()
{
  rightMotor.attach(11);
  leftMotor.attach(10);
  panMotor.attach(6); //attach motors to proper pins
  panMotor.write(90); //set PING))) pan to center
}

void loop()
{
  int distanceFwd = ping();
  if (distanceFwd>dangerThresh) //if path is clear
  {
    leftMotor.write(LForward); 
    rightMotor.write(RForward); //move forward
  }
  else //if path is blocked
  {
    leftMotor.write(LNeutral);
    rightMotor.write(RNeutral); 
    panMotor.write(0); 
    delay(500);
    rightDistance = ping(); //scan to the right
    delay(500);
    panMotor.write(180);
    delay(700);
    leftDistance = ping(); //scan to the left
    delay(500);
    panMotor.write(90); //return to center
    delay(100);
    compareDistance();
  }
}
  
void compareDistance()
{
  if (leftDistance>rightDistance) //if left is less obstructed 
  {
    leftMotor.write(LBackward); 
    rightMotor.write(RForward); //turn left
    delay(500); 
  }
  else if (rightDistance>leftDistance) //if right is less obstructed
  {
    leftMotor.write(LForward);
    rightMotor.write(RBackward); //turn right
    delay(500);
  }
   else //if they are equally obstructed
  {
    leftMotor.write(LForward); 
    rightMotor.write(RBackward); //turn 180 degrees
    delay(1000);
  }
}

long ping()
{
  // Send out PING))) signal pulse
  pinMode(pingPin, OUTPUT);
  digitalWrite(pingPin, LOW);
  delayMicroseconds(2);
  digitalWrite(pingPin, HIGH);
  delayMicroseconds(5);
  digitalWrite(pingPin, LOW);
  
  //Get duration it takes to receive echo
  pinMode(irPin, INPUT);
  duration = pulseIn(irPin, HIGH);
  
  //Convert duration into distance
  return duration / 29 / 2;
}

The right motor is pin 11
The left motor is pin 10
the scanning servo is pin 6

the trig is pin 12
the echo is pin 13

I just powered the servo motors with a 5V regulator with a heat sink and the SR04 off the Arduino.

I guess I'll take him apart now. I really need several boards for tinkering...

Nice job! It looks like the object avoidance is working. It might work a little quicker if it turned when backing-up. I have a similar Tamiya track set-up and I want it to work similar to yours someday.

Keep it up!

Thanks! His vision is a little narrow and the he tends to lose his tracks XD The toy I built him from wasn't really designed to have power running to the wheels. It was a fun little project though!

The Tamiya track platform I built has the same problem of loosing it's tracks. The only answer for me was to only do slow or partial turns. On a slick floor it is not bad but, put it on carpet and the first 90 degree turn will pull the track off.

Tracks are fun but, I think I am going to a wheeled project next.

Hi,

Same here, the Tamiya tracks work well on tiled floors but are hopless on stone/concrete/tarmac/carpet etc.

Here is a more off road orientated Tamiya of mine -

Its a rock crawler so slow enough to convert to autonomous operation, its also supports front and rear steering. I image that the turning circle of wheeled vehicles would be a bit frustrating without this front/rear steering capability to tighten the turn radius.

It also supports crab steering so you could sort of 'side step' obstacles - might add another dimension to a project, when to turn and when to crab steer.

Duane B

rcarduino.blogspot.com

Cool jeep DuaneB!

I have the running gear of a 1/10th scale Tamiya Clod Buster. I am considering using it. I need to get a reversing speed control though, one that would be real cheap.

Good Job! Looks good. There are momentary switches you could try to add to it. They can help guide the robot. I think someone already mentioned the PING Sensor.