Go Down

Topic: Line follower. Help to improve my code needed. (Read 6654 times) previous topic - next topic

biotech

Hi guys:

I built a line follower robot composed of the following items:
- 2 DC toy motors with gearbox
- Dual L298 H bridge
- Arduino UNO
- 2 QTR analogic sensors
- 3 leds

The wiring goes as follows:
- QTR signal 1 to A0
- QTR signal 2 to A1
- H bridge:
   ENA=5;//connected to Arduino's port 5(output pwm)
   IN1=2;//connected to Arduino's port 2
   IN2=3;//connected to Arduino's port 3
   ENB=6;//connected to Arduino's port 6(output pwm)
   IN3=4;//connected to Arduino's port 4
   IN4=7;//connected to Arduino's port 7
- Led connected to pins 8,9 and 10

I run the following code:

Code: [Select]

#define SENSOR_PINA0 A0
#define SENSOR_PINA1 A1
int LightValueA0; // The value from the sensor (0..1023)
int LightValueA1; // The value from the sensor (0..1023)
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(SENSOR_PINA0, INPUT);  // Not really necessary: here for example
pinMode(SENSOR_PINA1, INPUT);  // Not really necessary: here for example
pinMode(ENA,OUTPUT);//output
pinMode(ENB,OUTPUT);
pinMode(IN1,OUTPUT);
pinMode(IN2,OUTPUT);
pinMode(IN3,OUTPUT);
pinMode(IN4,OUTPUT);
delay(100);
digitalWrite(ENA,LOW);
digitalWrite(ENB,LOW);//stop driving
pinMode(8, OUTPUT);
pinMode(9, OUTPUT); 
}

void loop() {
{
    LightValueA0 = analogRead(SENSOR_PINA0);  //Read the voltage from sensor
    Serial.println(LightValueA0,DEC);      // Send result to Serial Monitor
    delay(100);
    LightValueA1 = analogRead(SENSOR_PINA1);  //Read the voltage from sensor
    Serial.println(LightValueA1,DEC);      // Send result to Serial Monitor
    delay(100);
    if (analogRead(SENSOR_PINA0) <= 900 && analogRead(SENSOR_PINA1) <= 900)
    {digitalWrite(9, HIGH);   // set the LED on
    delay(100);              // wait for a second
    digitalWrite(9, LOW);    // set the LED off
    delay(100);              // wait for a second
    analogWrite(ENA,220);//start driving motorA
    analogWrite(ENB,250);//start driving motorB
    digitalWrite(IN1,LOW);
    digitalWrite(IN2,HIGH);//setting motorA's directon
    digitalWrite(IN3,HIGH);
    digitalWrite(IN4,LOW);//setting motorB's directon
    delay(70);
    analogWrite(ENA,250);//start driving motorA
    analogWrite(ENB,250);//start driving motorB
    digitalWrite(IN1,LOW);
    digitalWrite(IN2,LOW);//setting motorA's directon
    digitalWrite(IN3,LOW);
    digitalWrite(IN4,LOW);//setting motorB's directon
    delay(50);
    digitalWrite(9, HIGH);   // set the LED on
    delay(100);              // wait for a second
    digitalWrite(9, LOW);    // set the LED off
    delay(100);}             // wait for a second
}
    if (analogRead(SENSOR_PINA0) >= 900 && analogRead(SENSOR_PINA1) <= 900)
    {digitalWrite(9, HIGH);   // set the LED on
    delay(100);              // wait for a second
    digitalWrite(9, LOW);    // set the LED off
    delay(100);              // wait for a second
    analogWrite(ENA,250);//start driving motorA
    analogWrite(ENB,250);//start driving motorB
    digitalWrite(IN1,LOW);
    digitalWrite(IN2,HIGH);//setting motorA's directon
    digitalWrite(IN3,LOW);
    digitalWrite(IN4,HIGH);//setting motorB's directon
    delay(50);
    analogWrite(ENA,200);//start driving motorA
    analogWrite(ENB,230);//start driving motorB
    digitalWrite(IN1,LOW);
    digitalWrite(IN2,LOW);//setting motorA's directon
    digitalWrite(IN3,LOW);
    digitalWrite(IN4,LOW);//setting motorB's directon
    delay(50);
    digitalWrite(9, HIGH);   // set the LED on
    delay(100);              // wait for a second
    digitalWrite(9, LOW);    // set the LED off
    delay(100);              // wait for a second
  }
  {
    if (analogRead(SENSOR_PINA0) <= 900 && analogRead(SENSOR_PINA1) >= 900)
    {digitalWrite(9, HIGH);   // set the LED on
    delay(100);              // wait for a second
    digitalWrite(9, LOW);    // set the LED off
    delay(100);              // wait for a second
    analogWrite(ENA,250);//start driving motorA
    analogWrite(ENB,250);//start driving motorB
    digitalWrite(IN1,HIGH);
    digitalWrite(IN2,LOW);//setting motorA's directon
    digitalWrite(IN3,HIGH);
    digitalWrite(IN4,LOW);//setting motorB's directon
    delay(50);
    analogWrite(ENA,200);//start driving motorA
    analogWrite(ENB,230);//start driving motorB
    digitalWrite(IN1,LOW);
    digitalWrite(IN2,LOW);//setting motorA's directon
    digitalWrite(IN3,LOW);
    digitalWrite(IN4,LOW);//setting motorB's directon
    delay(50);
    digitalWrite(9, HIGH);   // set the LED on
    delay(100);              // wait for a second
    digitalWrite(9, LOW);    // set the LED off
    delay(100);              // wait for a second
  }
    delay(100);
}}


The track is composed of a black line over a white pitch. Both sensors are places by the sides of the black line, so in a straight position the robot sees white in both sensors. When a turn comes one sensor reads black and then correct position. It all works well, but I have to introduce the stops to avoid the robot going off truck and the whole process of line following becomes to slow.

I would like to try code with PID algorithm or another simpler code but yet better than then one I am using until now. Can you help me please to improve the performance of my line follower?

Thanks!

robtillaart


first step: split your code in separate functions

void loop()
{
  dothis()
  dothat()
  if (somecondityion) dosomethingelse()
}

will make the code more manageable

furthermore reading how to use array's is also an important code cleaner - see tutorial section

ont tip:

use
Serial.begin (115200);  // is 12 x faster gives your robot more time to think as it speaks faster ;)
Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

biotech

Thank you robtillaart for all the help. That tip about Serial.begin (115200) has made a difference already.
I´m going through the other aspects you suggested to improve my code further. However, I still can´t get a sensor reading fast enough to avoid introducing the stops so the robot stays on track. Is it that I am using a very basic code? Will PID control make a big difference in the robot performance?

robtillaart


There are several delay()'s in your code. These block progress, you should have a look at blink without delay example to see how to write code triggered by a ticking clock.
Functions can be called when the need to

pseudo code

void loop()
{
  now = millis();
  if ( is it time for this (now) ) do this();
  if ( is it time for that (now) ) do that();
  if (is it time for something else(now) ) do something else();
  doThisEveryLoop();
}


Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

biotech

#4
May 10, 2013, 08:36 pm Last Edit: May 10, 2013, 09:34 pm by biotech Reason: 1
Hi,

As suggested by robtillaart, I am trying to learn how to introduce de blink without delay into my code. In the meantime, I have eliminated all the delays related to the leds so my new code goes as follows:

Code: [Select]

#define SENSOR_PINA0 A0
#define SENSOR_PINA1 A1
int LightValueA0; // The value from the sensor (0..1023)
int LightValueA1; // The value from the sensor (0..1023)
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 (115200);
pinMode(SENSOR_PINA0, INPUT);  // Not really necessary: here for example
pinMode(SENSOR_PINA1, INPUT);  // Not really necessary: here for example
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() {
{
   LightValueA0 = analogRead(SENSOR_PINA0);  //Read the voltage from sensor
   Serial.println(LightValueA0,DEC);      // Send result to Serial Monitor
   delay(100);
   LightValueA1 = analogRead(SENSOR_PINA1);  //Read the voltage from sensor
   Serial.println(LightValueA1,DEC);      // Send result to Serial Monitor
   delay(100);
   if (analogRead(SENSOR_PINA0) >= 900 && analogRead(SENSOR_PINA1) >= 900)
   {digitalWrite(9, HIGH);   // set the LED on
   delay(100);              // wait for a second
   digitalWrite(9, LOW);    // set the LED off
   delay(100);              // wait for a second
   analogWrite(ENA,200);//start driving motorA
   analogWrite(ENB,230);//start driving motorB
   digitalWrite(IN1,LOW);
   digitalWrite(IN2,HIGH);//setting motorA's directon
   digitalWrite(IN3,HIGH);
   digitalWrite(IN4,LOW);//setting motorB's directon
   delay(200);
   analogWrite(ENA,200);//start driving motorA
   analogWrite(ENB,230);//start driving motorB
   digitalWrite(IN1,LOW);
   digitalWrite(IN2,LOW);//setting motorA's directon
   digitalWrite(IN3,LOW);
   digitalWrite(IN4,LOW);//setting motorB's directon
   delay(50);    
}
   if (analogRead(SENSOR_PINA0) >= 900 && analogRead(SENSOR_PINA1) <= 900)
   {
   analogWrite(ENA,180);//start driving motorA
   analogWrite(ENB,230);//start driving motorB
   digitalWrite(IN1,LOW);
   digitalWrite(IN2,HIGH);//setting motorA's directon
   digitalWrite(IN3,LOW);
   digitalWrite(IN4,HIGH);//setting motorB's directon
   delay(100);
   analogWrite(ENA,200);//start driving motorA
   analogWrite(ENB,230);//start driving motorB
   digitalWrite(IN1,LOW);
   digitalWrite(IN2,LOW);//setting motorA's directon
   digitalWrite(IN3,LOW);
   digitalWrite(IN4,LOW);//setting motorB's directon
   delay(50);  
 }
 {
   if (analogRead(SENSOR_PINA0) <= 900 && analogRead(SENSOR_PINA1) >= 900)
   {
   analogWrite(ENA,230);//start driving motorA
   analogWrite(ENB,180);//start driving motorB
   digitalWrite(IN1,HIGH);
   digitalWrite(IN2,LOW);//setting motorA's directon
   digitalWrite(IN3,HIGH);
   digitalWrite(IN4,LOW);//setting motorB's directon
   delay(100);
   analogWrite(ENA,200);//start driving motorA
   analogWrite(ENB,230);//start driving motorB
   digitalWrite(IN1,LOW);
   digitalWrite(IN2,LOW);//setting motorA's directon
   digitalWrite(IN3,LOW);
   digitalWrite(IN4,LOW);//setting motorB's directon
   delay(50);    
 }
 {
   if (analogRead(SENSOR_PINA0) <= 900 && analogRead(SENSOR_PINA1) <= 900)
   {
   analogWrite(ENA,230);//start driving motorA
   analogWrite(ENB,230);//start driving motorB
   digitalWrite(IN1,LOW);
   digitalWrite(IN2,LOW);//setting motorA's directon
   digitalWrite(IN3,LOW);
   digitalWrite(IN4,LOW);//setting motorB's directon
   delay(100);  
 }
 delay(100);
}}}}


The robot works much better now. However, I still need to introduce de stops to avoid the robot going off track. Any other tips to improve my code further? Shall I also try to eliminate the remaining delays related to the motors control? If so, how can I do it?

Thanks!!!


AWOL

"Pete, it's a fool looks for logic in the chambers of the human heart." Ulysses Everett McGill.
Do not send technical questions via personal messaging - they will be ignored.

robtillaart

Quote
Any other tips to improve my code further?

you made two steps forwards, the best advise now is to start from scratch. but first read about the array's and how to write functions.

Then rebuild the robot again, I think I recognize in your code that you want to put every thing in it as fast as possible (correct me if I'm wrong)
Writing code is being an architect and a strategist, make a design of how the robot should act, and write that incrementally, in small steps one function at one time.
And make a step back if needed, it is part of the process of learning to write code.





Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

biotech

Thanks Karma for your advise as well. I´ll try to make a new code entirely and then be back to this forum to get the valuable feedback.

Gaur

http://crackeconcept.blogspot.com/2014/03/3-sensor-line-follower-ardiuno.html
cheakout this code....not PID ...still rocking

bvfst

Can you show me the diagram of your first circuit with two sensors? And can you also tell me where and how did you connect your batteries?

Go Up