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

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

// 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

// 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
//
//  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 debug 0

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

#define CAR_SPEED 150

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 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) {
right();
if( loopRight = 0 ) loopRight = 1;
--loopRight;
delay1y(loopRight);
// rescueLine('R', 500);
while(LT_R);
}
else if(LT_L) {
left();
if( loopLeft = 0 ) loopLeft = 1;
--loopLeft;
delay1y(loopLeft);
// rescueLine('L', 500);
while(LT_L);

// right(); // orig
left();
if( rescueLine('L', 100) ) forward();
// 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)

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;

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.