Navigation

Hi guys, i was wondering if anyone has been successful with getting the Rover R2 to navigate and avoid obstacles using a servo and Ping?

(same as the same but using a ping instead) Im not great at controlling or sending commands to the motor.

Thanks

Do you mean the DFRobotShop Rover V2?

Sorry yes, that’s the one i meant; DFRobotShop Rover V2. Im trying to create an obstacle navigation robot with a servo and ping. Im just finding it difficult so wanted to see some examples. The sample code used IR. Could i just modify that for ping?

[highlight=#fbfbfb][font=Helvetica Neue, Helvetica, Arial, sans-serif][/font][/highlight]

Unfortunately the IR code is not reuseable for the PING. Fortunately though the PING is very popular and people have put sample code online for use with Arduino. Do one thing at a time:

  1. Learn how to operate a servo via Arduino (fairly easy using the servo library)
  2. Learn how to get a distance value for the PING
  3. Put the two together, and then add an “if” statement to have the sensor stop when it detects something “too close”
  4. Understand the movement code
  5. Integrate it all together.

Similar project

I personally have used the Ping sensor on a simple Arduino robot.

Here is some useful sample code to get you started

[code]const int pingPin = 11;
unsigned int duration, inches;

void setup() {
Serial.begin(9600);
}

void loop() {
pinMode(pingPin, OUTPUT); // Set pin to OUTPUT
digitalWrite(pingPin, LOW); // Ensure pin is low
delayMicroseconds(2);
digitalWrite(pingPin, HIGH); // Start ranging
delayMicroseconds(5); // with 5 microsecond burst
digitalWrite(pingPin, LOW); // End ranging
pinMode(pingPin, INPUT); // Set pin to INPUT
duration = pulseIn(pingPin, HIGH); // Read echo pulse
inches = duration / 74 / 2; // Convert to inches
Serial.println(inches); // Display result
delay(200); // Short delay
}[/code]

From my experience, if you want to use a single ping sensor, you can try making a pan tilt mount for it. When I did sumo-robotics, I did autonomous navigation using IR sensors. I did the calibration by viewing the raw data in excel. It was a great learning experience.

Thanks guys,

DOes anyone have example of movement codes? Struggling to know how to control the motors as thats what im finding the hardest. I can get a pan with servo and ping, but either the rover doesn’t move (can hear the engines though) or only one side moves and it circles itself. I’ve checked and all wiring is correct

Hey Tasawar,

Try doing a unit test with your motors. One thing I always do is I try to find three critical values.

Pulse for idle
Pulse for Full speed ahead
Pulse for Full speed reverse

When you record these three pulses for both sides, you will have tested your motors to a certain extent. Actually, I don’t have a DFRover but I think they are DC motors. You can do the same style of test still though.

If you cannot get these simple steps working, post some pictures of your wiring or send me your code and I’ll try to have a look.

Also it is important to do this because if you ever need to code a gradually stop / start function (this reduces current spikes across your micro). In the future, if you decide to add a bunch of add-ons to your nice robot platform, the increased weight and sensors will increase the current draw. When the current draw and the current spike becomes too high, it will reset your microcontroller. Coding something to gradually start / stop motors helps reduce this spike. if you have a scope you would be able to probe this out.

We offer sample code in the DFRobotShop Rover User Guide using the W, A, S, D keys on your keyboard which is fairly easy to understand and modify.

Thanks guys for your support guys.

So going by your suggestions of getting the movement part down and understanding it, I now know how it works doing various tests, such as going forward, then stopping and turning etc. I’ve also got the ping working for obstacle detection (with the rover v2 and it works), however when i add a servo it all falls apart, is this due to power? Im currently only using 4xAA 1.2v NiMH batteries (4.8v), so i’ll try 1.5 batteries next to make it 6v.

I was wondering, would 9v supply via the barrel increase it more? Because i know the barrel powers both the board and motors?

I think it’s a power issue as the code seems sound, so does the movement, but when i run it the rover it just turns left. When testing just the servo is does the sweep, but added with the ping it behaves randomly. I think its because it currently only has 4.8v going to the motors and the servo can drain this.

Would increasing the voltage to 6v via the 4xAA batteries or increasing to 9v using the barrel help this? Just don’t want to make sure not to damage the rover (i know 6+ can lower the life of the DC motors though)

Or maybe using a voltage regulator.

Which servo are you using, how is it connected to the board and what code are you using to move it?

If you mean using a normal rectangular 9V, they cannot provide much current at all.
The onboard regulator can only provide so much current, so if you are using the Arduino’s digital pins to power the servo, that may be the issue.

The suggested battery is actually a 3.7V, 1000mAh or 2000mAh LiPo, which we have used to power the motors, sensors and a small pan/tilt on the autonomous rover.

Can you describe your setup with the servos and perhaps provide an image or two?

Thank you for your feedback, i think i’ve got it working as you mentioned the digital pins and i was using the ones that the motors were using so i’ve changed the pins for the sensors. Just wondering, can i not change the pins that the motors use?

To answer your questions, everything is connected via a breadboard for testing.

  1. Im using a standard parallax 180 servo. This is connected to GND and 5v via the breadboard. Signal was originally on pin 6 but i’ve changed it to 10 so it now works

  2. Ping is also connected to GND and 5v via the breadboard. Echo has been moved to pin 4 and trigger to pin 3 (originally on 8 and 9) so also works

When you say 3.7v is that the total or for individual batteries? Im now using Duracell but still need to test with the previous batteries that i was using as i’ve only realised it was a code error after changing the batteries.

I can try and provide pictures and the code in the next post (rover looks a little messy as i’ve been testing before making it look nice)

Im now working on making the rover run smoother and more accurate (ping bracket is a too high i think and there’s no tilt)

Code below is what im using and now it’s working. Still need to edit etc to make it smoother. Any tips?
[blockquote][code]//Since we are using servos and ultrasonic sensors in the robot we will include some libraries written to make their use easier
#include <Servo.h>
#include <NewPing.h>

//Below are the symbolic constants. Instead of having to type in a non-sensical pin number each time we want to do something we can write an easy to understand name which represents the pin, the compiler will then replace the names with the numbers

int E1 = 6; //M1 Speed Control
int E2 = 5; //M2 Speed Control
int M1 = 8; //M1 Direction Control
int M2 = 7; //M2 Direction Control

#define USTrigger 3
#define USEcho 4
#define MaxDistance 100
#define LED 13

//Here we have created two ‘objects’, one for the servo and one for the ultrasonic sensor
Servo servo;
NewPing sonar(USTrigger, USEcho, MaxDistance);

//Below we are creating unsigned integer variables which we will use later on in the code. They are unsigned as they will only have postive values
unsigned int duration;
unsigned int distance;
unsigned int FrontDistance;
unsigned int LeftDistance;
unsigned int RightDistance;
unsigned int Time;
unsigned int CollisionCounter;

void setup() //This block happens once on startup
{
Serial.begin(9600); //I have included the serial initialize but commented it out, if you want to debug and print information to the serial monitor just uncomment

//Here we are setting the pin modes. As we will sending out signals from the pins we set them as outputs
int i;
for(i=5;i<=8;i++)
pinMode(i, OUTPUT);
Serial.begin(9600);
servo.attach(10); //The servo is attached to pin 4
}

void loop() //This block repeats itself while the Arduino is turned on
{
servo.write(90); //Rotate the servo to face the front
scan(); //Go to the scan function
FrontDistance = distance; //Set the variable FrontDistance to the value of the distance returned from the scan function
Serial.println("Front distance = ");
Serial.print(distance);
if(FrontDistance > 40 || FrontDistance == 0) //If there is nothing infront of the robot within 40cm or the distance value is 0 (which for the newping libary means no ping was returned) then…
{
moveForward(); //Go to the moveForward function
}
else //Else (if there is something infront of the robot within 40cm) then…
{
CollisionCounter = CollisionCounter + 1;
moveStop(); //Go to the moveStop function
navigate();
}
}

void moveForward() //This function tells the robot to go forward
{
Serial.println("");
Serial.println(“Moving forward”);
analogWrite(E1,255);
digitalWrite(M1,LOW);
analogWrite(E2,255);
digitalWrite(M2,LOW);;
}

void moveBackward() //This function tells the robot to move backward
{
Serial.println("");
Serial.println(“Moving backward”);
analogWrite(E1,255);
digitalWrite(M1,LOW);
analogWrite(E2,255);
digitalWrite(M2,LOW);
}

void moveLeft() //This function tells the robot to turn left
{
Serial.println("");
Serial.println(“Moving left”);
analogWrite(E1,255);
digitalWrite(M1,HIGH);
analogWrite(E2,255);
digitalWrite(M2,LOW);

}

void moveRight() //This function tells the robot to turn right
{
Serial.println("");
Serial.println(“Moving right”);
analogWrite(E1,255);
digitalWrite(M1,LOW);
analogWrite(E2,255);
digitalWrite(M2,HIGH);

}

void moveStop() //This function tells the robot to stop moving
{
Serial.println("");
Serial.println(“Stopping”);
analogWrite (E1,0);
digitalWrite(M1,LOW);
analogWrite (E2,0);
digitalWrite(M2,LOW);
}
void scan() //This function determines the distance things are away from the ultrasonic sensor
{
Serial.println("");
Serial.println(“Scanning”);
Time = sonar.ping();
distance = Time / US_ROUNDTRIP_CM;
delay(500);
}
void navigate()
{
Serial.println(“There’s an obstacle!”);
servo.write(167); //Move the servo to the left (my little servos didn’t like going to 180 so I played around with the value until it worked nicely)
delay(1000); //Wait half a second for the servo to get there
scan(); //Go to the scan function
LeftDistance = distance; //Set the variable LeftDistance to the distance on the left
Serial.println("Left distance = ");
Serial.print(distance);
servo.write(0); //Move the servo to the right
delay(1000); //Wait half a second for the servo to get there
scan(); //Go to the scan function
RightDistance = distance; //Set the variable RightDistance to the distance on the right
Serial.println("Right distance = ");
Serial.print(distance);
if(abs(RightDistance - LeftDistance) < 5)
{
moveBackward(); //Go to the moveBackward function
delay(200); //Pause the program for 200 milliseconds to let the robot reverse
moveRight(); //Go to the moveRight function
delay(100); //Pause the program for 200 milliseconds to let the robot turn right
}
else if(RightDistance < LeftDistance) //If the distance on the right is less than that on the left then…
{
moveLeft(); //Go to the moveLeft function
delay(100); //Pause the program for half a second to let the robot turn
}
else if(LeftDistance < RightDistance) //Else if the distance on the left is less than that on the right then…
{
moveRight(); //Go to the moveRight function
delay(100); //Pause the program for half a second to let the robot turn
}
}[/code][/blockquote]

No, there are hardwired on the board.

It would be a single cell (1S) LiPo battery which outputs 3.7V.

Sorry for multiple posts;

The rover at full speed seems to always turn slightly towards left. I’ve tested with the constant speed and it’s the same

Can this be fixed with adjusting speed, or is this a wiring issue? It’s only ever one direction.

Thank you for your continued support :slight_smile:

This is a problem inherent with lower cost motors - despite the manufacturer’s best efforts, two motors from the same production line will likely not produce the exact same speed.
Add a gearbox where the greasing also affects the speed and you find that one track will turn slightly faster than the other. This is the case on most robots, and the way to correct it is to use encoders.
We created the Encoder Pair for Tamiya Twin Motor Gearbox specifically for this; your microcontroller sends speed commands to the motor controller but also counts the number of actual rotations of the motors and adjusts the speed of each motor accordingly.
If you are not ready to implement this “closed loop” feedback system, try lowering the speed of the faster motor slightly to get the robot to travel as straight as you can.

Thank, i had thought this was the issue as i’ve seen others have this problem. I had originally played with the speed but no difference.

No bother, i shall carry on adjusting the speed and doing as planned as the code does the job for now. I plan to add more such as an IR beacon