How to make my robot to make a 45 degrees turn.

Hi,

I'm using an ultrasonic sensor with my Arduino so depending on the distance my 4x4 robot goes forward, backwards or makes a turn.

So far, I was able to make my robot go forward until it approaches an obstacle then it starts to go backwards. I would like now that when my robot approaches an obstacule it stop and then make a degrees turn. What instructions should I add to the following code to get that kind of turn? I would like also to make each turm for an specific period of time (not continuously) but I don´t know what instructions should I use.

Code:

/*
 HC-SR04 Ping distance sensor]
 VCC to arduino 5v GND to arduino GND
 Echo to Arduino pin 13 Trig to Arduino pin 12
 More info at: http://goo.gl/kJ8Gl
 */

#define trigPin 12
#define echoPin 13
int ENA=5;//connected to Arduino's port 5(output pwm)
int IN1=2;//connected to Arduino's port 2
int IN2=3;//connected to Arduino's port 3
int ENB=6;//connected to Arduino's port 6(output pwm)
int IN3=4;//connected to Arduino's port 4
int IN4=7;//connected to Arduino's port 7

void setup() {
  Serial.begin (9600);
  pinMode(trigPin, OUTPUT);
  pinMode(echoPin, INPUT);
  pinMode(ENA,OUTPUT);//output
 pinMode(ENB,OUTPUT);
 pinMode(IN1,OUTPUT);
 pinMode(IN2,OUTPUT);
 pinMode(IN3,OUTPUT);
 pinMode(IN4,OUTPUT);
 digitalWrite(ENA,LOW);
 digitalWrite(ENB,LOW);//stop driving
}

void loop() {
  int duration, distance;
  digitalWrite(trigPin, HIGH);
  delayMicroseconds(1000);
  digitalWrite(trigPin, LOW);
  duration = pulseIn(echoPin, HIGH);
  distance = (duration/2) / 29.1;
  if (distance >= 20 || distance <= 0){
    Serial.println("Out of range");
    analogWrite(ENA,255);//start driving motorA
    analogWrite(ENB,255);//start driving motorB
    digitalWrite(IN1,LOW); 
    digitalWrite(IN2,HIGH);//setting motorA's directon
    digitalWrite(IN3,HIGH);
    digitalWrite(IN4,LOW);//setting motorB's directon
  }
  else {
    Serial.print(distance);
    Serial.println(" cm");
    analogWrite(ENA,255);//start driving motorA
    analogWrite(ENB,255);//start driving motorB
    digitalWrite(IN1,HIGH); 
    digitalWrite(IN2,LOW);//setting motorA's directon
    digitalWrite(IN3,LOW);
    digitalWrite(IN4,HIGH);//setting motorB's directon
  }
  delay(500);
}

Thanks!

Hi biotech,

Just a few comments on your post. First, you'll want to edit your post to put your code in a code window, otherwise nobody will want to read it... Modify the post, select the code section and then select the # option.

Without a wiring diagram, it is difficult to understand how the robot sensors and motors work, and the code doesn't give me enough information to help with specifics, but I'll give it a shot.

When you encounter an obstacle and go backwards, just program one of your motors to go in reverse and have the other motor go forward for a little bit to rotate the robot. Then drive them both forward again.

How much? It depends on your motors and the gearing. You'll have to experiment with different rotations.

Sounds like a fun modification. Good luck with it and keep us posted on your progress! Of course, if you run into a problem again, feel free to ask.

Can we get a picture of what the robot looks like? Does it have 4 wheel drive? Patduino is right--we need more information!

Turning an exact, or even approximate, #of degrees is not super easy to do. The best
way is to use wheel encoders, and anything else, like timed turns, will barely work, and
repeatability is poor. Even with encoders, you don't get perfect results, due to tire slippage,
different surfaces [hard floor vs carpet], different radius of inside vs outside wheel turning,
etc.

I don´t want to use encoders by now. Rather than that, I would like for the robot to turn for a certain time lapse. But how to do it?

Shall I have to use delay instruction? I tried to add the following in the original code but it didn´t work:

if (distance <= 20){
    Serial.println("Obstacule");
    analogWrite(ENA,100);//start driving motorA
    analogWrite(ENB,100);//start driving motorB
    digitalWrite(IN1,LOW); 
    digitalWrite(IN2,HIGH);//setting motorA's directon
    digitalWrite(IN3,LOW);
    digitalWrite(IN4,HIGH);//setting motorB's directon
    delay(500)
}

Any help is more than welcome.

Instead of using delay(), look up the "File > Examples > 2.Digital > BlinkWithoutDelay" sketch
in the Arduino IDE.

I've had an almost identical problem with my robot in the past, what you need to do is either get a rotary encoder OR time how long it takes the robot to turn in the particular direction you want to go. Of course the timing part will use a delay, but the encoder will monitor where the wheels exact positions are and you can set to where you want it to stop.

Now if you do time the wheels, you need to adjust the time for the speed (either the set speed or the battery/ voltage level, driving the wheels).
timing it won't be the proper way of doing it, but it does not require extra parts.

The encoder will track the positon of the wheels regardless of the speed, you just have to monitor the rotational numbers from the encoder and tell it where to stop. This will of course require parts but it is the better way of doing it.

1 Like