Line Following and Obstacle Avoidance Robot

I am working on a line following and obstacle avoidance robot. The aim is to ensure robot follows a line without deviating and move around an obstacle if detected and return back to the line. This should go in a loop and operate with different types of paths.

Line Following
I have successfully achieved the line following stage but the robot fails to follow the line at curves and sharp corners. The robot also does not go in a straight line at times.

Obstacle Avoidance
For obstacle avoidance, I have achieved this by making the robot turn right, turn left, turn left and turn right. In this method, the robot does not go back to the line but deviates away. From my research, I have understood that I need to use a PID library and DC motor with an encoder to get feedback to control the position of the motor.

I would like to know should I use a dc motor with an encoder or use a stepper motor for this operation. I am not clear on how to use a stepper motor to get the rotation and turning of the robot. Any advice is welcomed. Thank you in advance.

Code (Obtained from online)

#define echopin A4 // echo pin
#define trigpin A5 // Trigger pin


int motor_r2 = 9;
int motor_r1 = 10;

int motor_l2 = 5;
int motor_l1 = 6;


int speed = 115;

int  frontdist;
long duration;

int setdist = 10;

int L_S = A0; //sincer L
int R_S = A1; //sincer R


void setup() {

  pinMode(motor_l1, OUTPUT);
  pinMode(motor_l2, OUTPUT);

  pinMode(motor_r1, OUTPUT);
  pinMode(motor_r2, OUTPUT);

  pinMode (trigpin, OUTPUT);
  pinMode (echopin, INPUT);

  pinMode(L_S, INPUT);
  pinMode(R_S, INPUT);

  Serial.begin(9600);
  delay(1000);
}

void loop() {
  frontdist = data();
  Serial.println(frontdist);

  if (frontdist > setdist) {
    if ((digitalRead(L_S) == 0) && (digitalRead(R_S) == 0)) {
      forword();
    }
    if ((digitalRead(L_S) == 0) && (digitalRead(R_S) == 1)) {
      turnRight();
    }
    if ((digitalRead(L_S) == 1) && (digitalRead(R_S) == 0)) {
      turnLeft();
    }
  } else {

    turnLeft();
    delay(350);
    forword();
    delay(1000);
    turnRight();
    delay(200);
    forword();
    delay(500);

  }

}

long data() {
  digitalWrite(trigpin, LOW);
  delayMicroseconds(2);
  digitalWrite(trigpin, HIGH);
  delayMicroseconds(10);
  duration = pulseIn (echopin, HIGH);
  return duration / 29 / 2;
}

void stop() {
  analogWrite(motor_l1, 0);
  analogWrite(motor_l2, 0);
  analogWrite(motor_r1, 0);
  analogWrite(motor_r2, 0);
}

void forword() {
  analogWrite(motor_l1, speed);
  analogWrite(motor_l2, 0);
  analogWrite(motor_r1, 0);
  analogWrite(motor_r2, speed);
}

void backword() {
  analogWrite(motor_l1, 0);
  analogWrite(motor_l2, speed);
  analogWrite(motor_r1, speed);
  analogWrite(motor_r2, 0);
}


void turnRight() {
  analogWrite(motor_l1, 0);
  analogWrite(motor_l2, speed);
  analogWrite(motor_r1, 0);
  analogWrite(motor_r2, speed);

Hardware
L298N Driver
2 DC motor rear-wheel driven
1 castor wheel
Arduino Uno
2 IR sensor
1 HC-SR04 Ultrasonic Sensor

Summary
I want to make the robot go out of line if detected obstacle in front and return back to the line again with line following and obstacle avoidance.

I am not very familiar with Arduino projects related to motors but I have a fair amount of programming knowledge and experience in Python and C.

If You use Autoformat, in the IDE, before copying, the code will be a lot more easy to read. Ctrl T also works.
"does not work well" doesn't tell anything. Describe the problem in a scientific, engineering way.
Using delay in a real time environment can't be the best.

The regulation, the control, is very basic. Well done but side effects are likely to happen. Try to use lower speed and see what the result is.

I have autoformatted the code :slight_smile:

When I reduce the speed of both motors, the robot can follow the line when it is straight but it cannot make sharp turns or follow curved lines.

If obstacles are placed in the front, the robot will turn right (move out of the line) but cannot return back again. From what I understood is, I need to control the position of the motor by knowing how many rotations are made using an encoder with PID.

I have also looked into stepper motors which I think should be the easy way as I set the number of steps to be made in prefered direction if obstacles detected and repeat back the steps on the other wheel to return back to the line. Correct me if I'm wrong. :-\

The delays You use makes the execution blind for the duration of the delay.
There are no encoders with built in PID. That's an algorithm used in loop using the line sencing device and output the proper amount of power to the motors.

You need to think about the placement of your sensors and how they will respond.
With a single line sensor you could know it was on or off the line, but not how it had left.
With two line sensors you can with great care in placement follow a line and know if the robot has deviated right or left. However it cant handle sharp deviations or unexpected consequences.

You also need to have a search routine so it can find the line if its lost.

While its useful to know how much each motor (or wheel) has turned, that doesnt translate into absolute position as a driving wheel WILL slip, especially when the drive uses more power eg going up or downhill, accelerating or turning.

How to create intermediate stations or stops in between line follower track?

1 Like

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.