How to code arduino car

  1. Drive 10m ahead

  2. If the ultrasonic sensor detects obstacle 30cm front, the robot stops.

  3. If the obstacle is removed, it continues to move

  4. if the obstacle is not removed for 1 minute, it moves but changes path.

  5. The changed path is following: Move backward by 30 cm. Drive with semi-circle of D=2m to to the left to avoid obstacle.

  6. After finishing the 10m straight to front, it ends.

Start making code for:

  1. motor control.
  2. ultrasonic sensor reading
  3. using the working motor control create code for estimating distance.
  4. make code handling time limits.

Merge the parts together and adjust them.

You need a lot more sensors than that to avoid an obstacle. I would add a 6axis gyro to know the direction of the car and if the car is moving. Ultrasonic sensors are handy but they describe an obstacle not alwase verry accurate, they have there limits. If you want to be MORE sure there is an obstacle you probebly need a lidar that is turns around 360 degrees.

When is the assignment due?

You have to drive 10m: How are you doing odometry? That is, how do you know you've traveled 10m? Encoders on the wheels/motors would be a good start.

What should I add to achieve number 4,5 to the coding?

void loop() {
float duration, distance;
digitalWrite(IR_TRIG, HIGH);
delay(10);
digitalWrite(IR_TRIG, LOW);

duration = pulseIn(IR_ECHO, HIGH);
distance = ((float)(340 * duration) / 10000) / 2;
Serial.print("\nDIstance : ");
Serial.println(distance);

if(distance < 20) { //sense obstacle (20cm)
Serial.println("stop");
stop(); //stop(3sec)
}else{ // no obstacle
Serial.println("forward");
forward();
}
}
void forward(){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
}
void backward(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, HIGH);
delay(500);
}
void left(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, HIGH);
digitalWrite(RIGHT_A2, HIGH);
digitalWrite(RIGHT_B2, LOW);
delay(1000);
}
void right(){
digitalWrite(LEFT_A1, HIGH);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, HIGH);
delay(1000);
}
void stop(){
digitalWrite(LEFT_A1, LOW);
digitalWrite(LEFT_B1, LOW);
digitalWrite(RIGHT_A2, LOW);
digitalWrite(RIGHT_B2, LOW);
delay(3000);
}

for number 5, it doesnt have to be the exact move as I wrote. It just have to move away and come back to straight line to avoid something that does not move like tree.

First, read the forum instructions. Then you can edit your code in that last post to be usable.

Your wiring diagram suggests you are connecting something to "Vin". DO not use "Vin"or the"barrel jack" on the UNO.

Oh Thank you. Then where should I connect the wire? Actually it works until 3.

This is my coding currently. I have changed the stop time to 30 sec and simplified step 4~5. But it does not function as well as I thought. It stops and goes smooth but it does not move away when an object is blocking. What statement should I use?

#include <SoftwareSerial.h>
 

#define LEFT_A1 4
#define LEFT_B1 5
#define RIGHT_A2 6 
#define RIGHT_B2 7 
 

#define IR_TRIG 9 
#define IR_ECHO 8 
 
void setup() {
  Serial.begin(9600);  
 

  pinMode(LEFT_A1, OUTPUT);
  pinMode(RIGHT_A2, OUTPUT);
  pinMode(LEFT_B1, OUTPUT);
  pinMode(RIGHT_B2, OUTPUT);  
 

  pinMode(IR_TRIG, OUTPUT);
  pinMode(IR_ECHO, INPUT);
}
 
void loop() {
  float duration, distance;
  digitalWrite(IR_TRIG, HIGH);
  delay(10);
  digitalWrite(IR_TRIG, LOW);
 

  duration = pulseIn(IR_ECHO, HIGH);

  distance = ((float)(340 * duration) / 10000) / 2;
  Serial.print("\nDistance : ");
  Serial.println(distance);
  int sum = 0;
  

 
   
   if(distance < 20) {      
     Serial.println("stop");
     stop(); 
     sum++ ;
   
     while (sum > 10) {
     Serial.println("backward");
     backward ();
     Serial.println("left");
     left ();
     Serial.println("forwardi");
     forwardi ();
     Serial.println("right");
     right ();
     Serial.println("forwardi");
     forwardi ();
     Serial.println("forwardi");
     forwardi ();
     Serial.println("right");
     right ();
     Serial.println("forwardi");
     forwardi ();
     Serial.println("left");
     left ();
     Serial.println("forward");
     forward();
     }
   }else {        
     Serial.println("forward");
     forward();
   }
}
 
void forward(){
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
}
void forwardi (){
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
  delay (4000);
}
void backward(){
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, HIGH);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, HIGH);
  delay(1000);
}
void left(){
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, HIGH);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
  delay(1000);
}
void right(){
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, HIGH);
  delay(1000);
}
void stop(){
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, LOW);
  delay(3000);
}

The Arduino runs on 5 V - or as near as possible. So you power it by the "5V" pin. There may be a concern about powering it from a PC to the USB port at the same time, so just disconnect the power from the "5V" pin when connected to a PC.

Please also edit the first code in #5 with code tags.

You may have to understand the concept of State machines.

On you program:

  1. Do not use the delay function. It won't work for your problem. This effect must be done using the millis() or the micros() command
  2. Let us define certain situations or States.
    State=0 the car is moving forward,
    State=1 the car stopped because of the obstacle,
    State=2 the car is moving backward
    State=3 the car is turning left
    State=4 mission accomplished

Mapping this with your specs:
State=0 1. Drive 10m ahead
State=1 2. If the ultrasonic sensor detects an obstacle 30cm front, the robot stops.
State=0 3. If the obstacle is removed, it continues to move
4. if the obstacle is not removed for 1 minute, it moves but changes path.
State=2 5. The changed path is as follows: Move backward by 30 cm.
State=3 Drive with a semi-circle of D=2m to the left to avoid obstacles.
State=4 6. After finishing the 10m straight to the front, it ends.

State Transitions are:
0 --> 0 keep moving forward
0 --> 1 obstacle detected 30cm
0 --> 4 10 meters achieved
1 --> 0 obstacle removed
1 --> 1 Waiting
1 --> 2 1 minute elapse Change path
2 --> 2 Still moving backward
2 --> 3 backward or 30 cm achieved
3 --> 3 turning to the left
3 --> 0 2m achieved
4 --> 4 Stop

Try the following code:

#include <SoftwareSerial.h>


#define LEFT_A1 4
#define LEFT_B1 5
#define RIGHT_A2 6
#define RIGHT_B2 7


#define IR_TRIG 9
#define IR_ECHO 8

int currState = 0;
int nextState = 1;

unsigned long int forwardStartTime;
unsigned long int stopStartTime;
unsigned long int backStartTime;
unsigned long int leftStartTime;
unsigned long int totalForwardTime = 0;


void setup() {
  Serial.begin(9600);


  pinMode(LEFT_A1, OUTPUT);
  pinMode(RIGHT_A2, OUTPUT);
  pinMode(LEFT_B1, OUTPUT);
  pinMode(RIGHT_B2, OUTPUT);


  pinMode(IR_TRIG, OUTPUT);
  pinMode(IR_ECHO, INPUT);
}


void loop() {
  float duration, distance;
  digitalWrite(IR_TRIG, HIGH);
  delay(10);
  digitalWrite(IR_TRIG, LOW);
 

  duration = pulseIn(IR_ECHO, HIGH);

  distance = ((float)(340 * duration) / 10000) / 2;
  distance = 10;

  Serial.print("\nDistance : ");
  Serial.println(distance);

/*
STATE=0 1. Drive 10m ahead
STATE=1 2. If the ultrasonic sensor detects obstacle 30cm front, the robot stops.
STATE=0 3. If the obstacle is removed, it continues to move
           if the obstacle is not removed for 1 minute, it moves but changes path. 
STATE=2 The changed path is following: Move backward by 30 cm. 
STATE=3 Drive with semi-circle of D=2m to to the left to avoid obstacle.
STATE4 After finishing the 10m straight to front, it ends.
 */
  
  /* State Trnsitions
    0 --> 0 keep moving forward
    0 --> 1 obstacle detected 30cm
    0 --> 4 10 meters achieved

    1 --> 0 obstacle removed
    1 --> 1 Waiting
    1 --> 2 1 minute elapse Change path

    2 --> 2 Still moving backward
    2 --> 3 backward or 30 cm achieved

    3 --> 3 turning to the left
    3 --> 0 2m achieved

    4 --> 4 Stop
  */


  int prevState = currState;
  currState = nextState;
  if (currState == 0) {
    if (distance <= 30) {
      nextState = 1;
    } else if (prevState != currState) {  // just started
      forward();
      forwardStartTime = millis();
    } else { // keep going forward
      unsigned long int timeNow = millis();
      totalForwardTime = totalForwardTime + timeNow - forwardStartTime;
      forwardStartTime = timeNow;
      Serial.print("forwardStartTime:");
      Serial.print(forwardStartTime);
      if (totalForwardTime >= 10000) { //10 meters achieved
        nextState = 4;
      }
    }
  } else if (currState == 1) {
    if (distance > 30) { // obstacle removed
      nextState = 0;
    } else if (prevState != currState) {  // just stoped
      stop();
      stopStartTime = millis();
    } else if (millis() - stopStartTime > 60000) { //60 * 1000ms = 1 minute elapse Change path
      nextState = 2;
    }
  } else if (currState == 2) {
    if (prevState != currState) {  // start moving backward
      backward();
      backStartTime = millis();
    } else if (millis() - backStartTime > 3000) { //back 30 cm achieved
      nextState = 3;
    }
  } else if (currState == 3) {
    if (prevState != currState) {  // start turning left
      left();
      leftStartTime = millis();
    } else if (millis() - leftStartTime > 20000) { //left 2m achieved
      nextState = 0;
    }
  } else if (currState == 4) {  // Stop
    if (prevState != currState) {  // start turning left
      stop();
      while (true) {
      }
    }
  }
}

void forward() {
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
}
void backward() {
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, HIGH);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, HIGH);
}
void left() {
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, HIGH);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
}
void right() {
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, HIGH);
}
void stop() {
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, LOW);
}

There is still work to be done. You should remove/rewrite the portion with the delay(10) and the pulseIn(). Also the timing of how much on time is 10m, 30cm, 2m. I hope this gives you an idea on what to do.

Thank you for your answers. I have finished my code and done the project. I'll be looking in to your coding for further learnings. Thank you so much!

#include <SoftwareSerial.h>
 

#define LEFT_A1 4
#define LEFT_B1 5
#define RIGHT_A2 6
#define RIGHT_B2 7
 

#define IR_TRIG 9
#define IR_ECHO 8
 
void setup() {
  Serial.begin(9600);  
 

  pinMode(LEFT_A1, OUTPUT);
  pinMode(RIGHT_A2, OUTPUT);
  pinMode(LEFT_B1, OUTPUT);
  pinMode(RIGHT_B2, OUTPUT);  
 

  pinMode(IR_TRIG, OUTPUT);
  pinMode(IR_ECHO, INPUT);
}
 
void loop() {
  float duration, distance;
  digitalWrite(IR_TRIG, HIGH);
  delay(10);
  digitalWrite(IR_TRIG, LOW);
 

  duration = pulseIn(IR_ECHO, HIGH);

  distance = ((float)(340 * duration) / 10000) / 2;
  Serial.print("\nDistance : ");
  Serial.println(distance);
  int sum = 0;

   while(distance < 20) {      
     Serial.println("stop");
     stop();
     sum++ ;
     Serial.println(sum);
  float duration, distance;
  digitalWrite(IR_TRIG, HIGH);
  delay(10);
  digitalWrite(IR_TRIG, LOW);
 

  duration = pulseIn(IR_ECHO, HIGH);

  distance = ((float)(340 * duration) / 10000) / 2;
  Serial.print("\nDistance : ");
  Serial.println(distance);

 if(distance >= 20){        
     Serial.println("forward");
     forward();}
   
      if(distance >= 20)  {    
     break;
      }
   
    if(sum > 9) {
     Serial.println("backward");
     backward ();
     Serial.println("left");
     left ();
     Serial.println("forwardi");
     forwardi ();
     Serial.println("right");
     right ();
     Serial.println("forwardi");
     forwardi ();
     Serial.println("forwardi");
     forwardi ();
     Serial.println("right");
     right ();
     Serial.println("forwardi");
     forwardi ();
     Serial.println("left");
     left ();
     Serial.println("forward");
     forward();
     sum = 0;
     }

   


 }
if(distance >= 20){        
     Serial.println("forward");
     forward();}
}

void forward(){
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
}
void forwardi (){
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
  delay (2000);
}
void backward(){
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, HIGH);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, HIGH);
  delay(1000);
}
void left(){
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, HIGH);
  digitalWrite(RIGHT_A2, HIGH);
  digitalWrite(RIGHT_B2, LOW);
  delay(500);
}
void right(){
  digitalWrite(LEFT_A1, HIGH);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, HIGH);
  delay(500);
}
void stop(){
  digitalWrite(LEFT_A1, LOW);
  digitalWrite(LEFT_B1, LOW);
  digitalWrite(RIGHT_A2, LOW);
  digitalWrite(RIGHT_B2, LOW);
  delay(3000);
}