'Arduino obstacle avoidance car crashes and then read ultrasonic sensor

I've been working on a Arduino obstacle avoidance car, I'm using an arduino uno, two TT motors 1:48, one ultrasonic sensor SR04, one universal wheel and a L298D module with PWM to slow down motors.

I use serial monitor to check ultrasonic measure in cm, and seems to work fine except some times throws weird values line 2300, 2400 cm, which is not posible because the maximum measure distance is 400cm. I can also force those values if I put my hand over the sensor. There is a way to avoid that?

Also when I put the car on the floor sometimes it detects the minimum distance and the car stops before crashes to the wall, but other times it crashes and then reads the sensor and then executes a routine in case the distance is less that the distance threshold. I don't know why that happens, is not supposed to stop always almost instantly when the sensor reads the distance minimum distance and then rotate to avoid it?

This is my code:

int distance = 0;



long readUltrasonicDistance(int triggerPin, int echoPin)

{

pinMode(triggerPin, OUTPUT); // Clear the trigger

digitalWrite(triggerPin, LOW);

delayMicroseconds(2);

// Sets the trigger pin to HIGH state for 10 microseconds

digitalWrite(triggerPin, HIGH);

delayMicroseconds(10);

digitalWrite(triggerPin, LOW);

pinMode(echoPin, INPUT);

// Reads the echo pin, and returns the sound wave travel time in microseconds

return pulseIn(echoPin, HIGH);

}



void setup()

{

pinMode(10, OUTPUT);

pinMode(11, OUTPUT);

pinMode(6, OUTPUT);

pinMode(7, OUTPUT);

pinMode(8, OUTPUT);

pinMode(9, OUTPUT);

}



void loop()

{

// Speed always the same

analogWrite(10, 110);

analogWrite(11, 110);

distance = 0.01723 * readUltrasonicDistance(3, 2);

delay(100); // Wait for 100 millisecond(s)

if (distance < 8) {

digitalWrite(6, LOW);

digitalWrite(7, LOW);

digitalWrite(8, LOW);

digitalWrite(9, LOW);

delay(500); // Wait for 500 millisecond(s)

digitalWrite(6, LOW);

digitalWrite(7, HIGH);

digitalWrite(8, HIGH);

digitalWrite(9, LOW);

delay(500); // Wait for 500 millisecond(s)

digitalWrite(6, LOW);

digitalWrite(7, LOW);

digitalWrite(8, LOW);

digitalWrite(9, HIGH);

analogWrite(10, 90);

analogWrite(11, 90);

delay(500); // Wait for 500 millisecond(s)

} else {

digitalWrite(6, HIGH);

digitalWrite(7, LOW);

digitalWrite(8, LOW);

digitalWrite(9, HIGH);

}

}

I hope you can help me



Solution 1:[1]

I can't see too much wrong with the code, but I do have a number of suggestions:

  1. I would recommend using the NewPing library for accessing the sensor. This will handle the sensor trigger and return the distance in cm. It also handles any errors - and returns 0. It can also do some sampling - where it gives you a median of a series of measurements to try and reduce the errors you're seeing.

  2. You have quite a large delay - delay(100) - between measuring the distance, and checking for proximity. A robot can travel quite some distance in 100ms, and I don't think this delay is needed.

  3. I would normally slow the robot down as you get closer to the object. So perhaps go to 60% of your normal speed when you get within 15cm for example. This gives the robot more time to measure the distance and react as it gets nearer the obstacle.

  4. These sensors are no good for measuring distances if you approach an obstacle - such as a wall - at much of an angle. At 45 degrees for example, it just won't see the wall at all and happily crash into it. So you need to be aware of that.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 cguk70