Go Down

Topic: Help please to improve this obstacle avoiding robot project. (Read 8290 times) previous topic - next topic

biotech

Apr 22, 2014, 05:52 pm Last Edit: Apr 28, 2014, 07:17 pm by biotech Reason: 1
Hi there,

I have made this simple code for an obstacle avoiding robot. When the ultrasonic sensor detects an obstacle the robot turns in one direction. The mod I need is a way to make the robot turn in one direction first and then in the other direction when it detects the next obstacle.

Code: [Select]

#include <Servo.h>

Servo motorLeft;           // Define left motor
Servo motorRight;         // Define right motor
#define trigPin A2
#define echoPin A3

void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
motorLeft.attach(A5);          // Set left motor to  pin A5
motorRight.attach(A4);      // Set right motor to pin A4
}

void loop() {
 int duration, distance;      // ultrasonic sensor routine
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(1000);
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 distance = (duration/2) / 29.1;
 if (distance >= 30 || distance <= 0){  
   Serial.println("Out of range");
   motorLeft.write(85);      // robot go forward routine
   motorRight.write(85);
 }
 else
 {
   Serial.print(distance);  
   Serial.println( "cm");    
   motorLeft.write(170);     // robot turn right routine
   motorRight.write(10);  
 }
 delay(100);
}


The robot is controlled by an Arduino UNO R3 and uses two modified 360 continuous rotation servo motors.

Wiring to analog pins: Trig to A2, Echo to A3, left motor to A5 and right motor to A4.

I don´t know how to do this modification to the code miself so please help me. Thanks!

Northof49

So the first time it encounters and obstacle you want it to automatically turn right, then the next time it encounters an obstacle you want it to blindly turn left?  Just alternate right and left?

biotech

#2
Apr 22, 2014, 09:24 pm Last Edit: Apr 22, 2014, 10:02 pm by biotech Reason: 1
Hi Northof49,

That's right. I want for the robot to alternate the turns blindly as it carries only one ultrasonic sensor.

Thanks!

Northof49

One way would be to have a variable that goes from 0 to 1 in value and increments by one each time a turn decision is required.  If it is 0 then it turns left, if it is 1 it runs right.  If it exceeds 1 on the next increment, then it becomes 0 again and starts all over.

biotech

The use of a variable that goes from 0 to 1 sounds very good to me. However, I´m doing something wrong with the way I implement the algorithm.

This is the new code with the counter:
Code: [Select]

#include <Servo.h>

int i=0;
Servo motorLeft;          // Define left motor
Servo motorRight;         // Define right motor
#define trigPin A2
#define echoPin A3

void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
motorLeft.attach(A5);  // Set left motor to digital pin 4
motorRight.attach(A4);  // Set right motor to digital pin 7
}

void loop() {
  int duration, distance;
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(1000);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  if (distance >= 30 || distance <= 0){
    Serial.println("Out of range");
    motorLeft.write(20);
    motorRight.write(20);
  }
  else   
    if (i=0);{
    Serial.print(distance);
    Serial.println( "cm");     
    motorLeft.write(170);
    motorRight.write(10);
    }
    if (i=1);{
    Serial.print(distance);
    Serial.println( "cm");     
    motorLeft.write(10);
    motorRight.write(170);
    }   
    if (i++ == 2) i = 0;         
  }


The motors don´t run propertly but instead they kind of start and stop running continuously. 

Can you tell me what is wrong please?

biotech

I still can´t make the code  work on my robot. Any help is more than welcome.

wildbill

Two classic C issues. This:
Code: [Select]
    if (i=0);{
should be:
Code: [Select]
    if (i==0){

Same thing a little further down too.

biotech

Thank you for the correction widbill. But I don´t know where to put the if statements either. I tried different ways to put them in but I haven´t been successful to make it work so far.

biotech

Please someone tell me what I´m doign wrong with the code.

I already changed if ( i=0) for if ( I==0) but still doesn´t work. The if statements should be in a different place or something, but I don´t know where.

wildbill


PaulS


Please someone tell me what I´m doign wrong with the code.

I already changed if ( i=0) for if ( I==0) but still doesn´t work. The if statements should be in a different place or something, but I don´t know where.

Did you also remove the semicolon?

The name, i, is pretty dumb. That name tends to be used a lot for for loops, etc. Global variable names should almost never be one letter names.

A name like turnLeft, with boolean as the type, and true or false as the values, makes more sense:
Code: [Select]
bool turnLeft = true;

Then, in loop():

Code: [Select]
if(turnLeft)
{
   // turn left
   turnLeft = false;
}
else
{
   // turn right
   turnLeft = true;
}
The art of getting good answers lies in asking good questions.

biotech

#11
Apr 26, 2014, 08:43 pm Last Edit: Apr 27, 2014, 02:38 am by biotech Reason: 1
I´m trying now to follow Paul's advise but the code is still not doing what I want.

This is the new code:
Code: [Select]

#include <Servo.h>

Servo motorLeft;          // Define left motor
Servo motorRight;         // Define right motor
#define trigPin A2
#define echoPin A3
int i;
boolean turnLeft = true;

void setup() {
Serial.begin (9600);
pinMode(trigPin, OUTPUT);
pinMode(echoPin, INPUT);
motorLeft.attach(A5);   // Set left motor to digital pin 4
motorRight.attach(A4);  // Set right motor to digital pin 7

}

void loop() {
 int duration, distance;
 digitalWrite(trigPin, HIGH);
 delayMicroseconds(1000);
 digitalWrite(trigPin, LOW);
 duration = pulseIn(echoPin, HIGH);
 distance = (duration/2) / 29.1;
 if (distance >= 30 || distance <= 0){
   Serial.println("Out of range");
   motorLeft.write(20);
   motorRight.write(20);
 }
 if (distance <= 30){
   if(turnLeft){
   Serial.print(distance);
   Serial.println( "cm");    
   motorLeft.write(170);
   motorRight.write(10);
   delay (1500);
   turnLeft = false;
   }
   else {
   Serial.print(distance);
   Serial.println( "cm");    
   motorLeft.write(10);
   motorRight.write(170);
   delay (1500);    
   turnLeft = true;
   }
 }
 delay(100);
}


The problem is that now when the robot finds and obstacule it turns right for 1500ms and then left for 1500ms in a loop. But what I want is for robot turn right when it finds and obstacule for as long as it takes to get it sorted. And then when it finds the next obstacule to do the same but now turning left. I have tried many variations on the code, but I still can get the outcome wanted.

Northof49

Get rid of the fixed time for the turn.  Have it keep turning until the obstacle is cleared.  The IF IT IS LESS AND 30 UNITS TURN part of the code will keep it turning until it is no longer less than 30 units from an obstacle.  You will need to have the event that changes the variable from left to right choice, triggered by it clearing the obstacle and going straight again.  As long as the obstacle is close, the main loop of the code will keep it turning.  That's the way I have mine programmed and it works slick.  Turns just enough to clear then goes straight.

biotech

I know that I have to take off the delays but if I do it with the code as it is the motors don´t work. That´s why I put them in even when they are not suitable for the task I'm trying to achieve.

Regarding the IF IT IS LESS AND 30 UNITS TURN Northof49 I don´t know what you mean. May I have an example please? Alongside that, even as I tried in many ways to change boolean from true to false when the event of clearing the obstacle is done I haven´t been successful so far. 

Is it possible please for someone to give me a routine example? Maybe that way I can understand the concept finally and start experimenting with it.

Thanks to you all for the help you are giving me.






Northof49

I gathered that part of the decision making engine from the seventh line of your void loop.  It has the robot going straight until something is less than 30 units in distance away.

Go Up