I am just picking this piece of code because it is simple and typical of the rest of your program and will be suitable to make some points
if (distance < 20) {
delayMicroseconds(100);
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
}
Probably the most important thing is that you have the testing of the distance and the action all rolled into one. That makes it very difficult to unravel the actions when you send another command. A much better way to handle things is to have a variable to keep track of the state of the system. Maybe two variables makes more sense - one for the state of the obstacle detection and one for the state of the command selected by the user.
Then the action can take place depending on the states of the variables. For example, all the directions might be available if there is no obstacle. But if there is a medium distance obstacle maybe only reverse is available etc.
An example of what I mean is code something like this for forward
void moveForward() {
if (direction == 'F' and obstacle == 'N') {
// commands to make the motor move forwards
}
}
Doing it that way should automatically make FWD available again as soon as the car is far enough from the obstacle. I am assuming there is another function to set the value of the variable obstacle - something like
void checkObstacle() {
if (distance > x) {
obstacle = 'N'; // N for none
}
else if (distance > y) {
obstacle = 'C'; // C for close
}
else {
obstacle = 'A'; // A for approaching
}
}
Another, separate point I would like to make is how you handle the pins in this code
digitalWrite(9, HIGH);
digitalWrite(8, HIGH);
Your code would be much easier to develop and maintain if you give names to the numbers. For example. at the top of the program
byte leftMotorPin = 9; // if my names are wrong, use something suitable
byte rightMotorPin = 8;
and then
digitalWrite(leftMotorPin, HIGH);
digitalWrite(rightMotorPin, HIGH);
Finally, if you want a responsive program do not use delay() or delayMicroseconds(). If you really need timing intervals then use millis() ( or micros() ) to manage the timing without blocking as illustrated in Several Things at a Time