Multicolor Line Follower Guidance

Hi everyone,

I'm working on an Redbot Line follower with three line sensors. My task at hand is to program it to follow a track that goes from black, red and then blue. I have already made my measurements using the sensors and set the values.

The problem that I am having is getting it to follow the black line, it will follow the red and blue, but when it gets to black it stops.

I am using If else statements. The code in bold, when added, allows the Redbot to follow the black tape, but won't allow for the Redbot to follow the colored tape. But when I remove that section of code, the Redbot will follow the colored tape but not the black tape.

Any suggestions on what I could do?

#include <RedBot.h>
RedBotSensor left = RedBotSensor(A3); // initialize a left sensor object on A3
RedBotSensor center = RedBotSensor(A6); // initialize a center sensor object on A6
RedBotSensor right = RedBotSensor(A7); // initialize a right sensor object on A7
// constants that are used in the code. COLORLINETHRESHOLD is the level to detect
// if the sensor is on the line or not. If the sensor value is greater than this
// the sensor is above a DARK line.
//
// SPEED sets the nominal speed
#define COLORLINETHRESHOLD 690
#define BLACKLINETHRESHOLD 820
#define SPEED 60 // sets the nominal speed. Set to any number from 0 - 255.
RedBotMotors motors;

void setup(){
Serial.begin(9600);
Serial.println("Welcome to experiment 6.2 -Line Following");
Serial.println("------------------------------------------");
delay(2000);
Serial.println("IR Sensor Readings: ");
delay(500);
}

void loop() {
Serial.print(left.read());
Serial.print("\t"); // tab character
Serial.print(center.read());
Serial.print("\t"); // tab character
Serial.print(right.read());
Serial.println();
// if on the line drive left and right at the same speed (left is CCW / right is CW)
if((left.read() > COLORLINETHRESHOLD) && (center.read() > COLORLINETHRESHOLD) && (right.read() > COLORLINETHRESHOLD)) {
motors.stop();
}
else if((left.read() < COLORLINETHRESHOLD) && (center.read() < COLORLINETHRESHOLD) && (right.read() < COLORLINETHRESHOLD) ) {
motors.leftMotor(130);
motors.rightMotor(0);
}
else if (center.read() > COLORLINETHRESHOLD){
motors.leftMotor(100);
motors.rightMotor(100);
}
// if the line is under the right sensor, adjust relative speeds to turn to the right
else if (right.read() > COLORLINETHRESHOLD){
motors.leftMotor(130);
motors.rightMotor(0);
}
// if the line is under the left sensor, adjust relative speeds to turn to the left
else if (left.read() > COLORLINETHRESHOLD){
motors.leftMotor(0);
motors.rightMotor(130);
}
else if((left.read() < BLACKLINETHRESHOLD) && (center.read() < BLACKLINETHRESHOLD) && (right.read() < BLACKLINETHRESHOLD) ) {
** motors.leftMotor(130);**
** motors.rightMotor(0);**
** }**
** else if (center.read() > BLACKLINETHRESHOLD){**
** motors.leftMotor(100);**
** motors.rightMotor(100);**
** }**
// if the line is under the right sensor, adjust relative speeds to turn to the right
** else if (right.read() > BLACKLINETHRESHOLD){**
** motors.leftMotor(130);**
** motors.rightMotor(0);**
** }**
// if the line is under the left sensor, adjust relative speeds to turn to the left
** else if (left.read() > BLACKLINETHRESHOLD){**
** motors.leftMotor(0);**
** motors.rightMotor(130);**
** }**

else {
motors.stop();
}
}

Hodzilla:
Hi everyone,

I'm working on an Redbot Line follower with three line sensors. My task at hand is to program it to follow a track that goes from black, red and then blue. I have already made my measurements using the sensors and set the values.

The problem that I am having is getting it to follow the black line, it will follow the red and blue, but when it gets to black it stops.

I am using If else statements. The code in bold, when added, allows the Redbot to follow the black tape, but won't allow for the Redbot to follow the colored tape. But when I remove that section of code, the Redbot will follow the colored tape but not the black tape.

Any suggestions on what I could do?

#include <RedBot.h>
RedBotSensor left = RedBotSensor(A3); // initialize a left sensor object on A3
RedBotSensor center = RedBotSensor(A6); // initialize a center sensor object on A6
RedBotSensor right = RedBotSensor(A7); // initialize a right sensor object on A7
// constants that are used in the code. COLORLINETHRESHOLD is the level to detect
// if the sensor is on the line or not. If the sensor value is greater than this
// the sensor is above a DARK line.
//
// SPEED sets the nominal speed
#define COLORLINETHRESHOLD 690
#define BLACKLINETHRESHOLD 820
#define SPEED 60 // sets the nominal speed. Set to any number from 0 - 255.
RedBotMotors motors;

void setup(){
Serial.begin(9600);
Serial.println("Welcome to experiment 6.2 -Line Following");
Serial.println("------------------------------------------");
delay(2000);
Serial.println("IR Sensor Readings: ");
delay(500);
}

void loop() {
Serial.print(left.read());
Serial.print("\t"); // tab character
Serial.print(center.read());
Serial.print("\t"); // tab character
Serial.print(right.read());
Serial.println();
// if on the line drive left and right at the same speed (left is CCW / right is CW)
if((left.read() > COLORLINETHRESHOLD) && (center.read() > COLORLINETHRESHOLD) && (right.read() > COLORLINETHRESHOLD)) {
motors.stop();
}
else if((left.read() < COLORLINETHRESHOLD) && (center.read() < COLORLINETHRESHOLD) && (right.read() < COLORLINETHRESHOLD) ) {
motors.leftMotor(130);
motors.rightMotor(0);
}
else if (center.read() > COLORLINETHRESHOLD){
motors.leftMotor(100);
motors.rightMotor(100);
}
// if the line is under the right sensor, adjust relative speeds to turn to the right
else if (right.read() > COLORLINETHRESHOLD){
motors.leftMotor(130);
motors.rightMotor(0);
}
// if the line is under the left sensor, adjust relative speeds to turn to the left
else if (left.read() > COLORLINETHRESHOLD){
motors.leftMotor(0);
motors.rightMotor(130);
}
else if((left.read() < BLACKLINETHRESHOLD) && (center.read() < BLACKLINETHRESHOLD) && (right.read() < BLACKLINETHRESHOLD) ) {
** motors.leftMotor(130);**
** motors.rightMotor(0);**
** }**
** else if (center.read() > BLACKLINETHRESHOLD){**
** motors.leftMotor(100);**
** motors.rightMotor(100);**
** }**
// if the line is under the right sensor, adjust relative speeds to turn to the right
** else if (right.read() > BLACKLINETHRESHOLD){**
** motors.leftMotor(130);**
** motors.rightMotor(0);**
** }**
// if the line is under the left sensor, adjust relative speeds to turn to the left
** else if (left.read() > BLACKLINETHRESHOLD){**
** motors.leftMotor(0);**
** motors.rightMotor(130);**
** }**

else {
motors.stop();
}
}

what happened if instead of
"else if((left.read() < BLACKLINETHRESHOLD) && (center.read() < BLACKLINETHRESHOLD) && (right.read() < BLACKLINETHRESHOLD) )",
you used
"if((left.read() < BLACKLINETHRESHOLD) && (center.read() < BLACKLINETHRESHOLD) && (right.read() < BLACKLINETHRESHOLD) ) "

basically create a second if/elseif statement for BLACKLINETHRESHOLD case

It is pointless to print a value from each sensor, then operate on different values. Read each sensor ONCE on each pass through loop(), and store the value. Base your if statements on the values you stored, NOT on new readings.

PaulS:
It is pointless to print a value from each sensor, then operate on different values. Read each sensor ONCE on each pass through loop(), and store the value. Base your if statements on the values you stored, NOT on new readings.

I'm not sure if I understood what you were trying to say. The if statements are based on one stored value. The robot adjusts depending on a difference from the stored value.. If you were telling me to store a value for the background, it wouldn't work due to the track I am working with (inconsistent readings).

sherzaad:
what happened if instead of
"else if((left.read() < BLACKLINETHRESHOLD) && (center.read() < BLACKLINETHRESHOLD) && (right.read() < BLACKLINETHRESHOLD) )",
you used
"if((left.read() < BLACKLINETHRESHOLD) && (center.read() < BLACKLINETHRESHOLD) && (right.read() < BLACKLINETHRESHOLD) ) "

basically create a second if/elseif statement for BLACKLINETHRESHOLD case

Still no luck, making it an If statement still only lets it follow the black line and not the colored. Does the order of the statements matter? Should I group the turns with the turns and the straight's with the straights?

The if statements are based on one stored value.

Are they ?

 Serial.print(left.read());
 if((left.read() > COLORLINETHRESHOLD) && (center.read() > COLORLINETHRESHOLD) && (right.read() > COLORLINETHRESHOLD))

I see 2 calls to the left.read() function and there are more. They may not all return the same value as they are done over a period of time. Call the function once and use the returned value as many times as needed.