Pages: [1]   Go Down
Author Topic: Line follower. Help to improve my code needed.  (Read 5547 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Jr. Member
**
Karma: 0
Posts: 76
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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!
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 216
Posts: 13702
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


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 smiley-wink
Logged

Rob Tillaart

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

Offline Offline
Jr. Member
**
Karma: 0
Posts: 76
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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?
Logged

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 216
Posts: 13702
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset


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();
}


Logged

Rob Tillaart

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

Offline Offline
Jr. Member
**
Karma: 0
Posts: 76
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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!!!

« Last Edit: May 10, 2013, 02:34:06 pm by biotech » Logged

Global Moderator
UK
Offline Offline
Brattain Member
*****
Karma: 302
Posts: 26273
I don't think you connected the grounds, Dave.
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
}}}}
I hate it when that happens.
Logged

"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.

Global Moderator
Netherlands
Offline Offline
Shannon Member
*****
Karma: 216
Posts: 13702
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.





Logged

Rob Tillaart

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

Offline Offline
Jr. Member
**
Karma: 0
Posts: 76
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 3
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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

Pages: [1]   Go Up
Jump to: