elegoo smart robot car - combining line tracking and obstacle avoidance

My son is doing a grade 5 science fair project - he was hit by a car 2 years ago, so now is very interested in learning how cars could be made to follow tracks and stops if it encounters an obstacle with sensor technology. His experiment is not to learn how to write all of the code, but just to understand how you build it and the components involved and their functions. He has built the smart robot car on his own and is wanting to have the code to do both line tracking and obstacle avoidance to test different line tracking patterns and if it stops with different size of obstacles that the smart car encounters. We are using the codes that came with the set he has bought and it has line tracking and obstacle avoidance codes separately but he wants them combined. It is a 4WD elegoo smart robot 3.0 - box set - uno controller board V5 sensor expansion board, servo and cloud platform Gp2Y0A21 distance sensor to rotate 180 degrees, ultrasonic sensor module (distance measurement and obstacle avoidance), line tracking module - black and white sensor for recognition of the white and black lanes.

We got the codes working separately so he knows he built it correctly. Here is the code we tried to combine … its not working at all - it does not track lines and does nothing but stop when it reaches an obstacle.
with the obstacle avoidance program - it stops at obstacle and turns and keeps going until it reaches a new obstacle. With line tracking it follows the track.

I am pretty sure it will need some code to search out the line after it avoids the obstacle but have no idea how to write that.

your help and guidance to my 10 year old would be great!

#include <Servo.h> //servo library
Servo myservo; // create servo object to control servo

int Echo = A4;
int Trig = A5;

//Line Tracking IO define
#define LT_R !digitalRead(10)
#define LT_M !digitalRead(4)
#define LT_L !digitalRead(2)

#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11

#define carSpeed 150
int rightDistance = 0, leftDistance = 0, middleDistance = 0;

void forward(){
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
Serial.println(“go forward!”);
}

void back(){
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
Serial.println(“go back!”);
}

void left(){
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
Serial.println(“go left!”);
}

void right(){
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
Serial.println(“go right!”);
}

void stop(){
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
Serial.println(“Stop!”);
}

//Ultrasonic distance measurement Sub function
int Distance_test() {
digitalWrite(Trig, LOW);
delayMicroseconds(2);
digitalWrite(Trig, HIGH);
delayMicroseconds(20);
digitalWrite(Trig, LOW);
float Fdistance = pulseIn(Echo, HIGH);
Fdistance= Fdistance / 58;
return (int)Fdistance;
}

void setup(){
Serial.begin(9600);
pinMode(LT_R,INPUT);
pinMode(LT_M,INPUT);
pinMode(LT_L,INPUT);
pinMode(Echo, INPUT);
pinMode(Trig, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
stop();
}

void loop() {

if(LT_M){
forward();
}
else if(LT_R) {
right();
while(LT_R);
}
else if(LT_L) {
left();
while(LT_L);
}

myservo.write(90); //setservo position according to scaled value
delay(500);
middleDistance = Distance_test();
if(middleDistance <= 20) {
stop();
delay(500);
myservo.write(10);
delay(1000);
rightDistance = Distance_test();

delay(500);
myservo.write(90);
delay(1000);
myservo.write(180);
delay(1000);
leftDistance = Distance_test();

delay(500);
myservo.write(90);
delay(1000);
if(rightDistance > leftDistance) {
right();
delay(360);

}

else if(rightDistance < leftDistance) {
left();
delay(360);
}
else if((rightDistance <= 20) || (leftDistance <= 20)) {
back();
delay(180);
}
else {
forward();
}
}
else {
forward();
}
}

Code posted properly, using code tags as described in “How to use this forum”.

#include <Servo.h>  //servo library
Servo myservo;      // create servo object to control servo

int Echo = A4;
int Trig = A5;

//Line Tracking IO define
#define LT_R !digitalRead(10)
#define LT_M !digitalRead(4)
#define LT_L !digitalRead(2)

#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11

#define carSpeed 150
int rightDistance = 0, leftDistance = 0, middleDistance = 0;

void forward() {
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  Serial.println("go forward!");
}

void back() {
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  Serial.println("go back!");
}

void left() {
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  Serial.println("go left!");
}

void right() {
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  Serial.println("go right!");
}

void stop() {
  digitalWrite(ENA, LOW);
  digitalWrite(ENB, LOW);
  Serial.println("Stop!");
}


//Ultrasonic distance measurement Sub function
int Distance_test() {
  digitalWrite(Trig, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH);
  delayMicroseconds(20);
  digitalWrite(Trig, LOW);
  float Fdistance = pulseIn(Echo, HIGH);
  Fdistance = Fdistance / 58;
  return (int)Fdistance;
}

void setup() {
  Serial.begin(9600);
  pinMode(LT_R, INPUT);
  pinMode(LT_M, INPUT);
  pinMode(LT_L, INPUT);
  pinMode(Echo, INPUT);
  pinMode(Trig, OUTPUT);
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);
  stop();
}

void loop() {

  if (LT_M) {
    forward();
  }
  else if (LT_R) {
    right();
    while (LT_R);
  }
  else if (LT_L) {
    left();
    while (LT_L);
  }

  myservo.write(90);  //setservo position according to scaled value
  delay(500);
  middleDistance = Distance_test();
  if (middleDistance <= 20) {
    stop();
    delay(500);
    myservo.write(10);
    delay(1000);
    rightDistance = Distance_test();

    delay(500);
    myservo.write(90);
    delay(1000);
    myservo.write(180);
    delay(1000);
    leftDistance = Distance_test();

    delay(500);
    myservo.write(90);
    delay(1000);
    if (rightDistance > leftDistance) {
      right();
      delay(360);

    }

    else if (rightDistance < leftDistance) {
      left();
      delay(360);
    }
    else if ((rightDistance <= 20) || (leftDistance <= 20)) {
      back();
      delay(180);
    }
    else {
      forward();
    }
  }
  else {
    forward();
  }
}

We STRONGLY recommend to add comments, in order to explain program logic, and to use sensible variable names.

That way, you avoid mistakes like the following, which is nonsensical. LT_R et al. need to be pin numbers for pinMode().

#define LT_R !digitalRead(10)

...

  pinMode(LT_R, INPUT);

.... thank for posting it properly for me? how do i add comments is that with the the " // " I am not a programmer at all! and just wanting to get this working for my son to experiment with different tracks and different size obstacles .... sorry for doing it wrong!...

This is a line of code with a comment, using the "//" form:

Servo myservo;      // create servo object to control servo

And you're going to need a myservo.attach() somewhere. You have to tell it what pin the servo is connected to...before you try to write to it.

Perhaps you should post the two separate working programs that you tried to combine. It looks like you may have lost a few important things in the combining process.

Steve

I hope I post this correctly this time:
I think now I just need the code for it to go back to the line after it avoids the obstacle!
code:

// Include the Servo library
#include <Servo.h>
// Define object 'myservo' to control the sensor
Servo myservo;

//The pin CONSTANTS for the line tracking sensors
#define LT_R !digitalRead(10)
#define LT_M !digitalRead(4)
#define LT_L !digitalRead(2)

// The pins CONSTANTS for other stuff
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11

// A constant for our car speed
#define carSpeed 150

// Define variables to store the value of the sensor readings
int Echo = A4;  
int Trig = A5; 
// Define variables to hold our right, left, and middle distance values
int rightDistance = 0, leftDistance = 0, middleDistance = 0;

// Function to go forward
void forward(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  Serial.println("go forward!");
}

// Function to go backward
void back(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  Serial.println("go back!");
}

// Function to go left
void left(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  Serial.println("go left!");
}

// Function to go right
void right(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW); 
  Serial.println("go right!");
} 

// Function to stop
void stop(){
   digitalWrite(ENA, LOW);
   digitalWrite(ENB, LOW);
   Serial.println("Stop!");
} 

// Function to measure distance with the ultrasonic sensor
int Distance_test() {
  digitalWrite(Trig, LOW);   
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH);  
  delayMicroseconds(20);
  digitalWrite(Trig, LOW);   
  float Fdistance = pulseIn(Echo, HIGH);  
  Fdistance= Fdistance / 58;       
  return (int)Fdistance;
}  

// Function to Initialize the Arduino
void setup(){
  // Attach the servo to pin 3
  myservo.attach(3);
  // Start the Serial Monitor
  Serial.begin(9600);     
  // Define the mode of our pins
  pinMode(Echo, INPUT);    
  pinMode(Trig, OUTPUT);  
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);
  pinMode(LT_R,INPUT);
  pinMode(LT_M,INPUT);
  pinMode(LT_L,INPUT);
  // Stop the car
  stop();
  // Put the sensor in the middle position 
  myservo.write(90);
}

void loop() {
  // This is where the loop begins
  
  // LINE FOLLOWER
  // If we detect the middle sensor
  if(LT_M){
    // Then go forward
    forward();
  }
  // Else if we detect the RIGHT sensor
  else if(LT_R) {
    // Then go right
    right();
    // And keep going right until we don't detect anything on the right sensor
    while(LT_R);                             
  }
  // Else if we detect something on the left sensor
  else if(LT_L) {
    // Then go left
    left();
    // And keep going left until we don't detect anything on the left sensor
    while(LT_L);  

  }
  // OBJECT AVOIDANCE
  // Take a reading of what is in front of us  
  middleDistance = Distance_test();
  // Print the result in the Serial monitor
  Serial.print("Middle Distance = ");
  Serial.println(middleDistance);

  // If the distance to an obstacle is less than 20
  if(middleDistance <= 20) {     
    // STOP!
    stop();
    // Wait half a second
    delay(500);
    // Now go in reverse                         
    back();
    // And set the servo to point right
    myservo.write(0);
    // Wait a second...
    delay(1000);
    // ...and stop.
    stop();
    //  Read the distance to any obstacle that may be on the right      
    rightDistance = Distance_test();
    // Print the right distance on the serial monitor
    Serial.print("Right Distance = ");
    Serial.println(rightDistance);
    // Wait half a second
    delay(500);
    // Return the ultrasound sensor to the middle position
    myservo.write(90);
    // Wait another half a second to give the sensor a chance to catch up              
    delay(500);
    // And now set the servo to point to the left                                                  
    myservo.write(180);
    // Wait another half a second so it can catch up.              
    delay(500);
    // Take a reading to any obstacles that may be on the left
    leftDistance = Distance_test();
    // Print the left distance on the Serial monitor
    Serial.print("Left Distance = ");
    Serial.println(leftDistance);
    // Wait half a second
    delay(500);
    // Return the ultrasound sensor to the middle position
    myservo.write(90);
    // And wait a second              
    delay(1000);
    // Now, if the obstacle on the left is close to us
    if(rightDistance > leftDistance) {
      // Then let's go right
      right();
      // And wait a third of a second before we continue
      delay(360);
    }
    // Else if the obstacle on the right is closer to us
    else if(rightDistance < leftDistance) {
      // Then let's go left
      left();
      // And wait a third of a second before we continue
      delay(360);
    }
    // Else if the distance to obstacle on either side is less than 20
    else if((rightDistance <= 20) || (leftDistance <= 20)) {
      // Then let's go in reverse
      back();
      // And wait 180 miliseconds before we continue
      delay(180);
    }
  // But if there is nothing in front of us
  else {
    // Then keep going straight
    forward();
  }
  // Break out of the object avoidance code
}
// Go back to the start of the loop                     
}

What is your strategy for finding the line again? That obviously wasn't part of either of your original programs.

Perhaps you could sort of reverse what you did to avoid the obstacle e.g. if you went left for some time perhaps go right until one of the line sensors detects something.

Steve

Here is the new code I have received with some help so my son in grade 5 can learn about the scientific method and test different variables such as different lien tracking patterns and different obstacles. He is also just learning basics of the components and functions to make the smart car move and very basics of coding. I have received help, but now am stuck with an error … can you please review and assist so I can test?

The error says ‘leftTurn’ cannot be used as a function, in the line:
leftTurn ? right() : leftTurn();

Here is my code:

// Include the Servo library
#include <Servo.h>
// Define object 'myservo' to control the sensor
Servo myservo;

//The pin CONSTANTS for the line tracking sensors
#define LT_R !digitalRead(10)
#define LT_M !digitalRead(4)
#define LT_L !digitalRead(2)

// The pins CONSTANTS for other stuff
#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11

// A constant for our car speed
#define carSpeed 130

// Define variables to store the value of the sensor readings
int Echo = A4;  
int Trig = A5; 
// Define variables to hold our right, left, and middle distance values
int rightDistance = 0, leftDistance = 0, middleDistance = 0;

// Function to go forward
void forward(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  Serial.println("go forward!");
}

// Function to go backward
void back(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW);
  Serial.println("go back!");
}

// Function to go left
void left(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, LOW);
  digitalWrite(IN2, HIGH);
  digitalWrite(IN3, LOW);
  digitalWrite(IN4, HIGH);
  Serial.println("go left!");
}

// Function to go right
void right(){
  analogWrite(ENA, carSpeed);
  analogWrite(ENB, carSpeed);
  digitalWrite(IN1, HIGH);
  digitalWrite(IN2, LOW);
  digitalWrite(IN3, HIGH);
  digitalWrite(IN4, LOW); 
  Serial.println("go right!");
} 

// Function to stop
void stop(){
   digitalWrite(ENA, LOW);
   digitalWrite(ENB, LOW);
   Serial.println("Stop!");
} 

// Function to measure distance with the ultrasonic sensor
int Distance_test() {
  digitalWrite(Trig, LOW);   
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH);  
  delayMicroseconds(20);
  digitalWrite(Trig, LOW);   
  float Fdistance = pulseIn(Echo, HIGH);  
  Fdistance= Fdistance / 58;       
  return (int)Fdistance;
}  

// Function to Initialize the Arduino
void setup(){
  // Attach the servo to pin 3
  myservo.attach(3);
  // Start the Serial Monitor
  Serial.begin(9600);     
  // Define the mode of our pins
  pinMode(Echo, INPUT);    
  pinMode(Trig, OUTPUT);  
  pinMode(IN1, OUTPUT);
  pinMode(IN2, OUTPUT);
  pinMode(IN3, OUTPUT);
  pinMode(IN4, OUTPUT);
  pinMode(ENA, OUTPUT);
  pinMode(ENB, OUTPUT);
  pinMode(LT_R,INPUT);
  pinMode(LT_M,INPUT);
  pinMode(LT_L,INPUT);
  // Stop the car
  stop();
  // Put the sensor in the middle position 
  myservo.write(90);
}

void circulate(int leftTurn) {
    int sideDist = 0, midDist = 0;
    //Now try to circulate until we find next line
    // as long as there is no visible line, try again
    while (!(LT_M || LT_R || LT_L)) {
      myservo.write(leftTurn ? 0 : 180);
      delay(500);
      sideDist = Distance_test();
      myservo.write(90);
      delay(500);
      midDist = Distance_test();

      if (midDist > 20 && sideDist <= 20) {
        forward();
      } else if (sideDist > 20) {
        leftTurn ? right() : leftTurn();
      }
      //let it move a little
      //TODO: Adjust the delay to a reasonable value
      
      // by doing some experiments. Goal is to be able to go
      // about distance of 15 units before next scan
      delay(1000);

      //stop and get ready for next scan
      stop();
    }

    //At this point we should have found a line
    // Simply let the function return and
    // let loop() function handle the line tracking again
}

void loop() {
  // This is where the loop begins
  
  // LINE FOLLOWER
  // If we detect the middle sensor
  if(LT_M){
    // Then go forward
    forward();
  }
  // Else if we detect the RIGHT sensor
  else if(LT_R) {
    // Then go right
    right();
    // And keep going right until we don't detect anything on the right sensor
    while(LT_R);                             
  }
  // Else if we detect something on the left sensor
  else if(LT_L) {
    // Then go left
    left();
    // And keep going left until we don't detect anything on the left sensor
    while(LT_L);  

  }
  // OBJECT AVOIDANCE
  // Take a reading of what is in front of us  
  middleDistance = Distance_test();
  // Print the result in the Serial monitor
  Serial.print("Middle Distance = ");
  Serial.println(middleDistance);

  // If the distance to an obstacle is less than 20
  if(middleDistance <= 20) {
    int lastTurnLeft = 0;     
    // STOP!
    stop();
    // Wait half a second
    delay(500);
    // Now go in reverse                         
    back();
    // And set the servo to point right
    myservo.write(0);
    // Wait a second...
    delay(200);
    // ...and stop.
    stop();
    
    //  Read the distance to any obstacle that may be on the right      
    rightDistance = Distance_test();
    // Print the right distance on the serial monitor
    Serial.print("Right Distance = ");
    Serial.println(rightDistance);
    // Wait half a second
    delay(500);
    // Return the ultrasound sensor to the middle position
    myservo.write(90);
    // Wait another half a second to give the sensor a chance to catch up              
    delay(500);
    // And now set the servo to point to the left                                                  
    myservo.write(180);
    // Wait another half a second so it can catch up.              
    delay(500);
    // Take a reading to any obstacles that may be on the left
    leftDistance = Distance_test();
    // Print the left distance on the Serial monitor
    Serial.print("Left Distance = ");
    Serial.println(leftDistance);
    // Wait half a second
    delay(500);
    // Return the ultrasound sensor to the middle position
    myservo.write(90);
    // And wait a second              
    delay(1000);
    // Now, if the obstacle on the left is close to us
    if(rightDistance > leftDistance) {
      // Then let's go right
      right();
      delay(1000);
      stop();
      circulate(0);
    }
    // Else if the obstacle on the right is closer to us
    else if(rightDistance < leftDistance) {
      // Then let's go left
      left();
      delay(1000);
      stop();
      circulate(1);
    }
    // Break out of the object avoidance code
  }
// Go back to the start of the loop                     
}

It's told you what is wrong, leftTurn is an integer variable. It isn't a function, so you can't call it claiming that it is a function.

Perhaps you mean left()...which is a function. But who knows? As soon as those ternary operators turn up in some code I lose interest. Too confusing for me.

Steve

sorry I am not knowledgeable at all with coding .. I am trying to learn - but as above - i am just wanting the car to do both obstacle avoidance and line tracking so my son can test different line tracking tracks and size and shapes and moving obstacles to learn the scientific method for his science project ... wondering if you could me fix this?

Did you try changing leftTurn() in that line to left()?

If that was the only error it should now compile though you'll have to say if it then does what you want it to. I don't have the same hardware are you so I can't test it for you.

Steve

when I do this it says 'left' cannot be used as a function

msloane:
when I do this it says 'left' cannot be used as a function

That's odd because when I do and it looks like

     } else if (sideDist > 20) {
        leftTurn ? right() : left();
      }

it compiles perfectly.

Steve

try this code use rescueLine and do rectangle line

// Modified version of Line_tracking_car sketch from Elegoo 
// Downloaded from https://www.elegoo.com/tutorial/Elegoo%20Smart%20Robot%20Car%20Kit%20V3.0.2018.06.06.zip
//
//  Right motor truth table
//  Here are some handy tables to show the various modes of operation.
//  ENB         IN3             IN4         Description  
//  LOW   Not Applicable   Not Applicable   Motor is off
//  HIGH        LOW             LOW         Motor is stopped (brakes)
//  HIGH        LOW             HIGH        Motor is on and turning forwards
//  HIGH        HIGH            LOW         Motor is on and turning backwards
//  HIGH        HIGH            HIGH        Motor is stopped (brakes)   
//
 #define LT_R !digitalRead(10)                //Line Tracking IO define
      #define LT_M !digitalRead(4)
      #define LT_L !digitalRead(2)
 
 #define debug 0
 
 #define ENA 5
 #define ENB 6
 #define IN1 7
 #define IN2 8
 #define IN3 9
 #define IN4 11
 
 #define CAR_SPEED 150
 #define READING_LT_R 1
 #define READING_LT_L -1
 
 unsigned long int currentMillis = 0;
 unsigned long int last = 0; 
 unsigned long int interval = 1000; // 500 msec .for drive
      unsigned long msec500 = 0;
 boolean trapLast = true;
      boolean start = true;
 int previousReading = 0;
 int loopRight = 150; // counter for loop right org 50
 int loopLeft = 150; // counter for loop left org. 50
 
 // ------ delay for time exit ----.
 boolean delay1x (int time, int wsk ) {
 for( int x = 0; x < time; x++ ) { 
 delay(1);
 if( LT_M && wsk == 0 ) return true;
 if( LT_R && wsk == 1 ) return true; 
 if( LT_L && wsk == -1) return true; 
 return false;
 } // ------ for x --------
 } // ------- delay1x -----
 
 // ------ delay for time ----.
 void delay1y (int time ) {
 for( int x = 0; x < time; x++ ) { 
 delay(1);
 }
 } // ------------- 
 
    // --------------------------------------------
 boolean rescueLine( int c, int angle ) { 
 int v = 150; 
 analogWrite(ENB,0);             // speed = 0
 analogWrite(ENA,0);  
 analogWrite(ENB,v);
 analogWrite(ENA,v);
             
 if (c == 'L') {
 // -------------------
 right();
 if( delay1x(angle, 1) ) {
 stop();
 return true;         
 }
 return false; 
 } // ---------
 
 else if ( c == 'R' ) {
 
 // -------------------- 
 left();
 if( delay1x(angle, -1) ) {
 stop();
 return true;                 
 } 
 return false; 
 } // ----------- 
 
 else if ( c == 'M') {
 right();
 if( delay1x(angle, 0) ) {
 stop();
 return true;         
 }
 stop(); 
 return false; 
 } // ---- M ------
 
 } // ----- end-rescueLine ------ 
 
 // ---------------------------------------
 void forward(){
 analogWrite(ENA, CAR_SPEED);
 analogWrite(ENB, CAR_SPEED);
 digitalWrite(IN1, HIGH);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, HIGH);
 if( debug ) Serial.println("go forward!");
 }
 
 // --------------------------------------
 void back(){
 analogWrite(ENA, CAR_SPEED);
 analogWrite(ENB, CAR_SPEED);
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, HIGH);
 digitalWrite(IN3, HIGH);
 digitalWrite(IN4, LOW);
 if( debug ) Serial.println("go back!");
 }
 
 // --------------------------------------
 void left(){
 analogWrite(ENA, CAR_SPEED);
 analogWrite(ENB, CAR_SPEED);
 digitalWrite(IN1, LOW);
 digitalWrite(IN2, HIGH);
 digitalWrite(IN3, LOW);
 digitalWrite(IN4, HIGH);
 if( debug ) Serial.println("go left!");
 }
 
 // --------------------------------------
 void right(){
 analogWrite(ENA, CAR_SPEED);
 analogWrite(ENB, CAR_SPEED);
 digitalWrite(IN1, HIGH);
 digitalWrite(IN2, LOW);
 digitalWrite(IN3, HIGH);
 digitalWrite(IN4, LOW); 
 if( debug ) Serial.println("go right!");
 } 
 
 // --------------------------------------
 void stop(){
 digitalWrite(ENA, LOW);
 digitalWrite(ENB, LOW);
 if( debug ) Serial.println("Stop!");
 
 digitalWrite(IN1, LOW);      
 digitalWrite(IN2, LOW); // Right wheel stopped
 // digitalWrite(IN1, HIGH);      
 // digitalWrite(IN2, HIGH); // Right wheel stopped
 digitalWrite(IN3, LOW);      
 digitalWrite(IN4, LOW); // Left wheel stopped
 // digitalWrite(IN3, HIGH);      
 // digitalWrite(IN4, HIGH); // Left wheel stopped
 }
 
 // ------------------------------------------------ setup ------------------------------------
 void setup(){
 Serial.begin(115200);
 pinMode(LT_R,INPUT);
 pinMode(LT_M,INPUT);
 pinMode(LT_L,INPUT);
 
 pinMode(IN1, OUTPUT); // Motor-driven port configuration
 pinMode(IN2, OUTPUT);
 pinMode(IN3, OUTPUT);
 pinMode(IN4, OUTPUT);
 pinMode(ENA, OUTPUT);
 pinMode(ENB, OUTPUT);
 
      Serial.println(" start file: SimpleLineTrackingCarDemo.ino ");
      msec500 = millis();
 }
 
 // ------------------------------------------------ loop -------------------------------------
 void loop() {
        
     if( start ) {
      forward();
        if( (millis() - msec500) > 500 ){
          start = false;
          stop();
        }  
     } // ---------------- 
       
      char d;     
 if(LT_M){
 forward();
 // rescueLine('M', 1000); // 1000 msec == +/- 180 deg.
 }
 else if(LT_R) {
 previousReading = READING_LT_R;
 right();
 if( loopRight = 0 ) loopRight = 1;
 --loopRight;
        ++loopLeft;                           // add
 delay1y(loopRight);
 // rescueLine('R', 500); 
 while(LT_R);                             
 }   
 else if(LT_L) {
 previousReading = READING_LT_L;
 left();
 if( loopLeft = 0 ) loopLeft = 1;
 --loopLeft;
        ++loopRight;                          // add
 delay1y(loopLeft);
 // rescueLine('L', 500); 
 while(LT_L);  
 
 } else if (previousReading == READING_LT_R){
 // right(); // orig
 left();
 if( rescueLine('L', 100) ) forward(); 
 } else if (previousReading == READING_LT_L){
 // left(); // orig
 right();
 if( rescueLine('R', 100) ) forward(); 
 }
 
 if( !LT_L && !LT_M && !LT_R ) { // no line --> stop
         if( debug ) Serial.print(" 224  "); 
 if (trapLast) { 
 trapLast = false;
 last = millis();
 }
 }
 
 if( millis() - last > interval ) {
 stop ();
 delay(100);
 trapLast = true;
        last = millis();
 }
    
 } // ---------------------------- end-loop ------------------------------
 
 // ---------------------------------- end ---------------------

So post the code that you have so far and explain in detail what it does and what you need it to do.

We'll gladly help you get it working but we're unlikely to just give you the code. That sounds too much like you cheating on your school project.

Steve

Hi. I am sorry. I have no choice but to ask for codes. This is because i been learning C# only. C and C++ are brand new to me. My teacher wouldnt help me as he wants me to figure it out myself. I searched online and watch tons of youtube video yet i cant find one that works well. I am desperate hence i came here for help.

My codes are below. I combined both of line following and collision domain codes and i know it shouldn’t be done like this. However, i do not have a clue to make it work properly. I want the codes to work so whatever track or formation the car is on, if there is object in front of the car, it will avoid the object and continue to resume moving along the track or formation. Please please i beg you to help me to make it work.

TestingLine_Collision.ino (3.09 KB)

Just POST your code.

Why is that so hard to do?

#include <Servo.h> //servo library
Servo myservo; //create servo object to control servo

int Echo = A4;
int Trig = A5;

#define ENA 5
#define ENB 6
#define IN1 7
#define IN2 8
#define IN3 9
#define IN4 11
#define carSpeed 150
int rightDistance = 0, leftDistance = 0, middleDistance = 0;

#define LT_R !digitalRead(10)
#define LT_M !digitalRead(4)
#define LT_L !digitalRead(2)

void forward()
{
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
Serial.println(“Forward”);
}

void back()
{
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
Serial.println(“Backward”);
}

void left()
{
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
Serial.println(“Left”);
}

void right()
{
analogWrite(ENA, carSpeed);
analogWrite(ENB, carSpeed);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
Serial.println(“Right”);
}

void stop()
{
digitalWrite(ENA, LOW);
digitalWrite(ENB, LOW);
Serial.println(“Stop!”);
}

//Ultrasonic distance measurement sub function
int Distance_test()
{
digitalWrite(Trig, LOW);
delayMicroseconds(2);
digitalWrite(Trig, HIGH);
delayMicroseconds(20);
digitalWrite(Trig, LOW);
float Fdistance = pulseIn(Echo, HIGH);
Fdistance = Fdistance / 58;
return (int)Fdistance;
}

void setup()
{
myservo.attach(3); //attach servo on pin 3 to servo object
Serial.begin(9600);
pinMode(Echo, INPUT);
pinMode(Trig, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(ENA, OUTPUT);
pinMode(ENB, OUTPUT);
pinMode(LT_R, INPUT);
pinMode(LT_M, INPUT);
pinMode(LT_L, INPUT);
stop();
}

void loop()
{
//Collision Domain
myservo.write(90); //set servo position according to scaled value
delay(500);
middleDistance = Distance_test();

if(middleDistance <= 20)
{
stop();
delay(500);
myservo.write(10);
delay(1000);
rightDistance = Distance_test();

delay(500);
myservo.write(90);
delay(1000);
myservo.write(180);
delay(1000);
leftDistance = Distance_test();

delay(500);
myservo.write(90);
delay(1000);

if(rightDistance > leftDistance)
{
right();
delay(360);
}
else if(rightDistance < leftDistance)
{
left();
delay(360);
}
else if((rightDistance <= 20) || (leftDistance <= 20))
{
back();
delay(180);
}
else
{
forward();
}
}
else
{
forward();
}

//Line Following
if(LT_M)
{
forward();
}
else if(LT_R)
{
right();
while(LT_R);
}
else if(LT_L)
{
left();
while(LT_L);
}
}

So, what’s the problem?

while(LT_L);

Blocking loops are not a good idea, ditto big delays.

(It’s a good thing that pins default to input, isn’t it?)

Please remember to use code tags when posting code

My codes are below. I combined both of line following and collision domain codes and i know it shouldn't be done like this. However, i do not have a clue to make it work properly. I want the codes to work so whatever track or formation the car is on, if there is object in front of the car, it will avoid the object and continue to resume moving along the track or formation. Please please i beg you to help me to make it work.