Line tracking robot cannot take sharp corners

Hello,

For my school project I am making a line tracking robot using five Line tracking sensors from DFRobot.
It needs to follow a black line in a certain course. But my robot can't take sharp corners. Can I improve my code to make this work or do I need to reposition my sensors?

Here's my code;

#define RECHTS_DIR 13 
#define RECHTS_SPEED 11
#define RECHTS_BRAKE 8

#define LINKS_DIR 12
#define LINKS_SPEED 3
#define LINKS_BRAKE 9

#define SENSOR_1 2
#define SENSOR_2 4
#define SENSOR_3 5
#define SENSOR_4 10
#define SENSOR_5 A2

#define VOORUIT HIGH
#define ACHTERUIT LOW

int out1=0;
int out2=0;
int out3=0;
int out4=0;
int out5=0;

void setup() {

  pinMode(LINKS_DIR, OUTPUT);
  pinMode(LINKS_SPEED, OUTPUT);
  pinMode(LINKS_BRAKE, OUTPUT);
  pinMode(RECHTS_DIR, OUTPUT);
  pinMode(RECHTS_SPEED, OUTPUT);
  pinMode(RECHTS_BRAKE, OUTPUT);
  
  pinMode(SENSOR_1, INPUT);
  pinMode(SENSOR_2, INPUT);
  pinMode(SENSOR_3, INPUT);
  pinMode(SENSOR_4, INPUT);
  pinMode(SENSOR_5, INPUT);
  
  digitalWrite(LINKS_DIR, VOORUIT);
  digitalWrite(RECHTS_DIR, VOORUIT);
  digitalWrite(LINKS_BRAKE, LOW);
  digitalWrite(RECHTS_BRAKE, LOW);
}
 
void loop()
 
{
 out1 = digitalRead(SENSOR_1);
 out2 = digitalRead(SENSOR_2);
 out3 = digitalRead(SENSOR_3);
 out4 = digitalRead(SENSOR_4);
 out5 = digitalRead(SENSOR_5);
 
  if(out3==0) // Als middensensor alleen lijn ziet 
{
digitalWrite(LINKS_SPEED,HIGH);  //beide motors maximum
digitalWrite(RECHTS_SPEED,HIGH);      
} 
 else if(out4==0 && out3==1) // als rechts4 lijn ziet maar midden niet (kleine bocht)
 {
 if(out3 != 0) 
  {
  digitalWrite(RECHTS_SPEED,LOW);
  digitalWrite(LINKS_SPEED,150);
  }
 }
  else if(out4==0 && out3==0) // als middensensor lijn ziet en rechts4 (erg kleine bocht)
  {
  if(out4 != 1)
   {
   digitalWrite(RECHTS_SPEED,LOW);
   digitalWrite(LINKS_SPEED,130);
   }
  }
 
  else if(out5 ==0 && out3==1) // als rechts5 lijn ziet en midden niet (scherpe bocht)
  {
 if(out3 != 0)
  {
  digitalWrite(RECHTS_SPEED,LOW);
  digitalWrite(LINKS_SPEED,185);
  }
  }
  else if(out5==0 && out3==1) // als rechts5 lijn ziet en midden lijn ziet (ERG SCHERP)
  {
  if(out5 != 1)
   {
   digitalWrite(RECHTS_SPEED,LOW);
   digitalWrite(LINKS_SPEED,HIGH);
  }
  }
 
     else if(out2==0 && out3==1) // als links2 lijn ziet maar midden niet
   {
   if(out3 != 0)
   {
   digitalWrite(LINKS_SPEED,LOW);
   digitalWrite(RECHTS_SPEED,150);
   }
   }
    else if(out2==0 && out3==0) // als links2 lijn ziet en midden ook
    {
    if(out2 != 1)
    {
    digitalWrite(LINKS_SPEED,LOW);
    digitalWrite(RECHTS_SPEED,130);
    }
    }
   else if( out2==0 && out1==0) // als links2 lijn ziet en links1 ook (redelijk scherpe bocht)
    {
      if(out3 !=0)
      {
      digitalWrite(RECHTS_SPEED,185);
      digitalWrite(LINKS_SPEED,LOW);
    }
   
    }
   else if(out1==0) // als links1 alleen lijn ziet (erg scherpe bocht)
   {
   if(out3 !=0)
   {
     digitalWrite(RECHTS_SPEED,HIGH);
      digitalWrite(LINKS_SPEED,LOW);
   }
  
  
   }
  
   
     else if(out1==1 && out2==1 && out3==1 && out4==1 && out5==1) // als alle sensors geen lijn zien
      {
      digitalWrite(RECHTS_SPEED,LOW);
      digitalWrite(LINKS_SPEED,LOW);
      }
 delay(30);
}

And here's a picture of the line tracking sensors on the front of the robot;

Pictures of the course and line;

Hello

To help find out where the problem is, can you investigate the following?

Can your robot take corners that are less sharp? I see you have a variety of corners on your course.

Does the sharp corner problem happen with both left turns and right turns?

Have you tried reducing the speed of the robot to see if that makes a difference?

Also, it is a bit difficult to read your code the way it is posted at present. Two suggestions. In the Arduino IDE, use the Tools - Auto Format function to help with indenting the "if" statements. And when you post it again, put it between code tags - there is a button marked "#" above the row of smileys. If you have your code between the tags, it makes it easier to read.

Regards

Ray

Hello Ray

Thank you for your reply, this is the code. I think it should be better now.

I have tried to make it a little slower but its a speed contest, I did increase the turning speed when the sensor in the far corners are seeing the black line.

#define RECHTS_DIR 13 
#define RECHTS_SPEED 11
#define RECHTS_BRAKE 8

#define LINKS_DIR 12
#define LINKS_SPEED 3
#define LINKS_BRAKE 9

#define SENSOR_1 2
#define SENSOR_2 4
#define SENSOR_3 5
#define SENSOR_4 10
#define SENSOR_5 A2

#define VOORUIT HIGH
#define ACHTERUIT LOW

int out1=0;
int out2=0;
int out3=0;
int out4=0;
int out5=0;

void setup() {

  pinMode(LINKS_DIR, OUTPUT);
  pinMode(LINKS_SPEED, OUTPUT);
  pinMode(LINKS_BRAKE, OUTPUT);
  pinMode(RECHTS_DIR, OUTPUT);
  pinMode(RECHTS_SPEED, OUTPUT);
  pinMode(RECHTS_BRAKE, OUTPUT);

  pinMode(SENSOR_1, INPUT);
  pinMode(SENSOR_2, INPUT);
  pinMode(SENSOR_3, INPUT);
  pinMode(SENSOR_4, INPUT);
  pinMode(SENSOR_5, INPUT);

  digitalWrite(LINKS_DIR, VOORUIT);
  digitalWrite(RECHTS_DIR, VOORUIT);
  digitalWrite(LINKS_BRAKE, LOW);
  digitalWrite(RECHTS_BRAKE, LOW);
}

void loop()

{
  out1 = digitalRead(SENSOR_1);
  out2 = digitalRead(SENSOR_2);
  out3 = digitalRead(SENSOR_3);
  out4 = digitalRead(SENSOR_4);
  out5 = digitalRead(SENSOR_5);

  if(out3==0) // Als middensensor alleen lijn ziet 
  {
    digitalWrite(LINKS_SPEED,HIGH);  //beide motors maximum
    digitalWrite(RECHTS_SPEED,HIGH);      
  } 
  else if(out4==0 && out3==1) // als rechts4 lijn ziet maar midden niet (kleine bocht)
  {
    if(out3 != 0) 
    {
      digitalWrite(RECHTS_SPEED,LOW);
      digitalWrite(LINKS_SPEED,150);
    }
  }
  else if(out4==0 && out3==0) // als middensensor lijn ziet en rechts4 (erg kleine bocht)
  {
    if(out4 != 1)
    {
      digitalWrite(RECHTS_SPEED,LOW);
      digitalWrite(LINKS_SPEED,130);
    }
  }

  else if(out5 ==0 && out3==1) // als rechts5 lijn ziet en midden niet (scherpe bocht)
  {
    if(out3 != 0)
    {
      digitalWrite(RECHTS_SPEED,LOW);
      digitalWrite(LINKS_SPEED,185);
    }
  }
  else if(out5==0 && out3==1) // als rechts5 lijn ziet en midden lijn ziet (ERG SCHERP)
  {
    if(out5 != 1)
    {
      digitalWrite(RECHTS_SPEED,LOW);
      digitalWrite(LINKS_SPEED,HIGH);
    }
  }

  else if(out2==0 && out3==1) // als links2 lijn ziet maar midden niet
  {
    if(out3 != 0)
    {
      digitalWrite(LINKS_SPEED,LOW);
      digitalWrite(RECHTS_SPEED,150);
    }
  }
  else if(out2==0 && out3==0) // als links2 lijn ziet en midden ook
  {
    if(out2 != 1)
    {
      digitalWrite(LINKS_SPEED,LOW);
      digitalWrite(RECHTS_SPEED,130);
    }
  }
  else if( out2==0 && out1==0) // als links2 lijn ziet en links1 ook (redelijk scherpe bocht)
  {
    if(out3 !=0)
    {
      digitalWrite(RECHTS_SPEED,185);
      digitalWrite(LINKS_SPEED,LOW);
    }

  }
  else if(out1==0) // als links1 alleen lijn ziet (erg scherpe bocht)
  {
    if(out3 !=0)
    {
      digitalWrite(RECHTS_SPEED,HIGH);
      digitalWrite(LINKS_SPEED,LOW);
    }


  }


  else if(out1==1 && out2==1 && out3==1 && out4==1 && out5==1) // als alle sensors geen lijn zien
  {
    digitalWrite(RECHTS_SPEED,LOW);
    digitalWrite(LINKS_SPEED,LOW);
  }
  delay(30);
}

Also, the robot fails to take the indicated corners;

I thought about changing the motor direction instead of standing still when the robot has to turn. Do you think this would work?

Thanks for that.

I appreciate it's a speed contest :slight_smile: but I assume that when you slow the robot down as a test, it is better at following the tight corners? And just so I understand, on the corners that the robot has problems with, does it try to turn the correct way (but goes too wide) or does it just go straight on.

I'm afraid I don't read Dutch (?). Can you explain which sensor is which? Sensor 3 is in the middle, I guess, but which sensors are on the left and right when looking in the direction that the robot is moving?

Many thanks.

Ray

When all five sensors don't see the line. The robot stops, because when the robot reaches the end of the track it had to stop and find a object. But the corner is so sharp that all the sensors see no line and it just stops.

delay(30);

What if you remove or shorten the blind-period?

  else if(out4==0 && out3==1) // als rechts4 lijn ziet maar midden niet (kleine bocht)
  {
    if(out3 != 0)

What other value could "out3" have here?

In some of the statements where you are controlling the left and right speed, you have commands like this:

digitalWrite(RECHTS_SPEED,185);

My understanding is that digitalWrite can only write HIGH or LOW, which causes the output pin to be at +5V or 0V. I have not checked it, but I think digitalWrite may interpret another value, like 185 as HIGH. So, in effect your speed is being set to one of two levels (depending on how your motors react to +5V and 0V). What was the thinking behind the 185 value and the similar ones?

Regards

Ray

but I think digitalWrite may interpret another value, like 185 as HIGH.

You're absolutely right; any non-zero value will be treated as HIGH.

AWOL:

but I think digitalWrite may interpret another value, like 185 as HIGH.

You're absolutely right; any non-zero value will be treated as HIGH.

With a zero-value, do you mean values like 10 100 120 70?

No, I mean anything that is not zero.

I do not mean any value x where x % 10 is zero.

AWOL:
No, I mean anything that is not zero.

I do not mean any value x where x % 10 is zero.

I will try this when I'm back with my project. I thought that if I wrote 100 the motors were running at half of the speed.
I want the robot to turn sharp when the outer sensors see the line en less sharp when the inner sensors see the line. I'm very new to this.

Maybee you could use a pwm output, with that you could controll the speed just fine.

But you'll need to use analogWrite, not digitalWrite.

Your problem here is that the "kinks" in the circuit are actually smaller than the robot footprint.

Also, there is a speed matter - the robot is over-running the decision points.

I haven't looked into the program, but it will need to be rather clever. You need it to "remember" the last signal it received before it ran out of track; that signal will have been that the track turned in one direction or the other. It needs to reverse the wheel on the side that the track turned so that in the process, it turns in that direction, then when it has centred on the track again, it can proceed.

If there was no turn before it ran out of track, it needs to reverse straight until it finds the track again and then if there is no turn found suggesting that it is actually the "end of the line" step very slowly until it runs out of track and stop.