Go Down

Topic: My first robot (Read 5766 times) previous topic - next topic

hoff70

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  :)  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?

Ufoguy

Here is a link that I found useful. http://www.akeric.com/blog/?p=1590
Also try searching Google for " ping scan robot ".
If you want to meet a beautiful nurse you must be patient.

oric_dan

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.

DuaneB

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
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

hoff70

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  :) I have an Arduino motor shield and my sensor is an SR04 so the code is going to be different from a regular PING.

hoff70

Code: [Select]
//"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:

http://www.youtube.com/watch?v=WO_lZbVlgPM&feature=youtu.be

Any help on what I'm missing?

JimboZA


I built a paper shell for my robot


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

My hovercraft is full of eels.

No PMs for help please.
DO NOT power servos from Arduino 5V: give them their own power and connect the grounds.

hoff70

#7
Jun 17, 2012, 06:27 am Last Edit: Jun 17, 2012, 07:18 am by hoff70 Reason: 1
Code: [Select]
/*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:

Code: [Select]
/*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  :P

cyclegadget

#8
Jun 17, 2012, 07:10 am Last Edit: Jun 17, 2012, 07:12 am by cyclegadget Reason: 1
In this sketch, I think you need something like this:
Code: [Select]
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:
Code: [Select]
distance = duration / 72 / 2;//determines distance in inches of object from sensor by microseconds to inches formula.
Good links: Eagle tutorial= http://www.youtube.com/playlist?list=PLDE1858BD83D19C70
General Arduion tutorials = http://tronixstuff.wordpress.com
http://www.gammon.com.au/forum/bbshowpost.php?bbtopic_id=123

hoff70

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:

Code: [Select]
/*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/


DuaneB

#10
Jun 17, 2012, 08:10 am Last Edit: Jun 17, 2012, 08:16 am by DuaneB Reason: 1
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 -

http://rcarduino.blogspot.com/p/cars.html

Duane B

rcarduino.blogspot.com
Read this
http://rcarduino.blogspot.com/2012/04/servo-problems-with-arduino-part-1.html
then watch this
http://rcarduino.blogspot.com/2012/04/servo-problems-part-2-demonstration.html

Rcarduino.blogspot.com

JimboZA

#11
Jun 17, 2012, 08:51 am Last Edit: Jun 17, 2012, 09:05 am by JimboZA Reason: 1
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.
My hovercraft is full of eels.

No PMs for help please.
DO NOT power servos from Arduino 5V: give them their own power and connect the grounds.

hoff70

#12
Jun 17, 2012, 07:30 pm Last Edit: Jun 17, 2012, 07:57 pm by hoff70 Reason: 1
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:

Code: [Select]
#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:

http://www.youtube.com/watch?v=RyPL9w83QXs&feature=youtu.be

hoff70

Well, here he is:

http://www.youtube.com/watch?v=Sit6Zq13QN4&feature=youtu.be

Code: [Select]
/*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...

cyclegadget


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!
Good links: Eagle tutorial= http://www.youtube.com/playlist?list=PLDE1858BD83D19C70
General Arduion tutorials = http://tronixstuff.wordpress.com
http://www.gammon.com.au/forum/bbshowpost.php?bbtopic_id=123

Go Up