Obstacle Avoidance not working

Hey! Im trying to get obstacle avoidance to work on my elegoo smart car. The basic premise of the project is this:

  1. The car needs to be controlled by the ir remote
  2. It needs to record a certain path (input from remote) and memorise it
  3. It needs to execute the memorised path
  4. If an obstacle is in the way of its memorised path, it needs to go around the obstacle and then go back to its memorised path.

So far im stuck on 4. I can either get it to go the memorised path or avoid the obstacle. Not both.

Many thanks in advance!

#include <IRremote.h>

// Motor driver pin configuration
#define PWMA 5    // Controls power to right motor
#define PWMB 6    // Controls power to left motor
#define AIN 7     // Controls direction of right motor, HIGH = FORWARD, LOW = REVERSE
#define BIN 8     // Controls direction of right motor, HIGH = FORWARD, LOW = REVERSE
#define STBY 3    // Place H-Bridge in standby if LOW, Run if HIGH
#define TRIG 13
#define ECHO 12

unsigned long path[50][2]; // Store path as a 2D array [IR code, timestamp]
unsigned long pathIndex = 0; // Index to keep track of the current step in the path
bool recording = false; // Indicates whether we are recording a path

// IR remote setup
int RECV_PIN = 9;  // IR receiver pin
IRrecv irrecv(RECV_PIN);
decode_results results;

void setup() {
  // Motor pins setup
  pinMode(PWMA, OUTPUT);     //set IO pin mode OUTPUT
  pinMode(PWMB, OUTPUT);
  pinMode(BIN, OUTPUT);
  pinMode(AIN, OUTPUT);
  pinMode(STBY, OUTPUT);
  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);
  digitalWrite(STBY, HIGH);  //Enable Motors to run
  digitalWrite(PWMA, LOW);  // Fully on 

  // Start the IR receiver
  Serial.begin(9600);
  irrecv.enableIRIn();
} 
  unsigned long measureDistance() {
  digitalWrite(TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);
  
  unsigned int duration = pulseIn(ECHO, HIGH);
  unsigned int distance = duration * 0.034 / 2; // Speed of sound in air is 0.034 cm/μs
  
  return distance;
  }

void loop() {
  if (irrecv.decode(&results)) {
    unsigned long value = results.value;
    // Print the received IR code to the serial monitor
    Serial.println(results.value, HEX);
     // Handle the IR remote buttons
     if (value == 0xFF6897) { 
      if (!recording) {
        // Start recording
        recording = true;
        pathIndex = 0;
        Serial.println("Recording started.");
   } else {
      // Stop recording
      recording = false;
      Serial.println("Recording stopped.");
    }
    delay(500); // Debounce the button
  }

  if (recording && pathIndex < 50) {
      // Store the received IR code in the recorded path
      path[pathIndex][0] = value;
      path[pathIndex][1] = millis();
      pathIndex++;
      Serial.print("Recorded: ");
      Serial.print(value, HEX);
      Serial.print(" Time Difference (ms): ");
      Serial.println(path[pathIndex - 1][1]);
    }
      delay(500); // Delay to prevent recording multiple actions in one press
    
if (value == 0xFF9867) { // Replace with your playback button code
      Serial.println("Playback started");
      executePath();
      delay(500); // Debounce the button
    } else {
      switch (results.value) {
      case 0xFF629D:  // Forward
        moveForward();
        break;
      case 0xFFA857:  // Backward
        moveBackward();
        break;
      case 0xFF22DD:  // Left
        turnLeft();
        break;
      case 0xFFC23D:  // Right
        turnRight();
        break;
      case 0xFF02FD:  // Stop
        stopCar();
        break;
      case 0xFF4AB5: // Reset Car
        resetArduino();
        break;
      default:
        // Unknown code; do nothing
        break;
    }
    
    
 irrecv.resume(); // Receive the next value
    }
}
}

// Functions to store and recall path

void executePath() {
  for (int i = 0; i < pathIndex; i++) {
    unsigned long value = path[i][0];
    unsigned long timestamp = path[i][1];

    unsigned long nextTimestamp = (i < pathIndex - 1) ? path[i + 1][1] : millis();
    unsigned long timeDifference = nextTimestamp - timestamp;

    bool obstacleDetected = false;
    
    switch (value) {
      case 0xFF629D:
         if (!checkObstacle()) {
          moveForward();
        }
        break;
      case 0xFFA857:
        moveBackward();
        break;
      case 0xFF22DD:
        turnLeft();
        break;
      case 0xFFC23D:
        turnRight();
        break;
      case 0xFF02FD:
        stopCar();
        break;
      case 0xFF4AB5: 
        resetArduino();
        break;
      default:
        // Handle unknown path steps
        break;
    }

    delay(timeDifference); // Delay between transmissions (adjust as needed)
    irrecv.resume(); // Receive the next value
  }
}
void avoidObstacle() {
  // Stop the motors
  analogWrite(PWMA, 0);
  analogWrite(PWMB, 0);

  // Back up a little
  digitalWrite(AIN, LOW);
  digitalWrite(BIN, LOW);
  analogWrite(PWMA, 120);
  analogWrite(PWMB, 120);
  delay(500);

  // Turn away from the obstacle
  digitalWrite(AIN, HIGH);
  digitalWrite(BIN, LOW);
  analogWrite(PWMA, 60);
  analogWrite(PWMB, 0);
  delay(1000);

  // Go forward a little
  digitalWrite(AIN, HIGH);
  digitalWrite(BIN, HIGH);
  analogWrite(PWMA, 120);
  analogWrite(PWMB, 120);
  delay(2000);

  // Turn back
  digitalWrite(AIN, LOW);
  digitalWrite(BIN, HIGH);
  analogWrite(PWMA, 0);
  analogWrite(PWMB, 60);
  delay(1000);

  // Resume forward motion
  moveForward();
}

bool checkObstacle() {
  // Check if an obstacle is too close (e.g., within 10 cm)
  unsigned long distance = measureDistance();
  if (distance <= 10) {
    Serial.println(" Obstacle in the way");
    Serial.println(distance);
    avoidObstacle();
    return true;
  }
  return false;
}

// Functions to control the car's movement
void moveForward() {
 digitalWrite(AIN, HIGH);    // Forward direction
 analogWrite(PWMA, 120);   // Full power
 digitalWrite(BIN, HIGH);    // Forward direction
 analogWrite(PWMB, 120);   // Full power
}

void moveBackward() {
  digitalWrite(AIN, LOW);    // Backwards direction
  analogWrite(PWMA, 120);   // Full power
  digitalWrite(BIN, LOW);    // Backwards direction
  analogWrite(PWMB, 120);   // Full power
}

void turnLeft() {
  digitalWrite(AIN, HIGH);     // Backwards direction
  analogWrite(PWMA, 60);   // Full power
  digitalWrite(PWMB, LOW);
}

void turnRight() {
  digitalWrite(PWMA, LOW);   // No power on Right
  digitalWrite(BIN, HIGH);    // Forward direction
  analogWrite(PWMB, 60);   // Full power
}

void stopCar() {
  digitalWrite(PWMA, LOW);   // No power on Right
  digitalWrite(PWMB, LOW);   // No power on Left
}

void resetArduino() {
  asm volatile ("  jmp 0");
}

It appears you may be spending to much of your time measuring the echo. Along with that you have several delays in your code. The processor does nothing for the time the delay(xxx) is running.

how would i reduce the echo measure time?

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.