Problema con vehículo que esquiva obstáculos

Hola gente!

Me estoy iniciando con Arduino Uno y como primer proyecto decidí hacer un “vehículo” que avanza y al encontrar un obstáculo gira. El problema es que este funciona en un comienzo pero luego de toparse con obstáculos un par de veces se detiene y no realiza ninguna acción, aveces al moverlo vuelve a andar pero eventualmente se detiene y es necesario desconectar la corriente y volver a conectarla (pulsar el botón Reset de la placa no ayuda en nada).

Los elementos que utilizo son:
#Arduino Uno R3
#Modulo L298N
#Sensor HC-SR04
#Mini Protoboard
#4 Pilas AA en Serie (6V y aproximadamente 2500 mAh)
#Una rueda 360 (para la parte posterior)
#2 motores de corriente continua con rueda como este:

Les adjunto el código:

#define IN1 8
#define IN2 7
#define IN3 4
#define IN4 2
#define disparador 13
#define receptor 12

float tiempo;
word espacio;
byte repeticion;
byte aleatorio;

void setup() 
{
	pinMode(IN1, OUTPUT); /* IN1, IN2 y ENA corresponten a un motor */
	pinMode(IN2, OUTPUT);
	pinMode(IN3, OUTPUT); /* IN3, IN4 y ENB corresponden a otro motor */
	pinMode(IN4, OUTPUT);
	digitalWrite(IN1, LOW);
	digitalWrite(IN2, LOW);
	digitalWrite(IN3, LOW);
	digitalWrite(IN4, LOW);
	pinMode(disparador, OUTPUT); /* disparador es el Trig */
	pinMode(receptor, INPUT); /* receptor es el Echo */
	Serial.begin(9600);
	randomSeed(analogRead(5));
}

void loop() 
{
	Distancia();

	if (repeticion < 1)
	{
		aleatorio = byte(random(0, 2));		/* Genero un valor aleatorio para la direccion de giro pseudo-aleatoria */
	}

	if (espacio > 23)
	{ 
		Avanzar();
	} 
	else /* Que gire */
	{
		Distancia();
		while (espacio <= 23)
		{
			Retroceder();
		}
		switch (aleatorio)
		{
			
		case 0:
			Izquierda();
			repeticion++;
			if (repeticion == 3)
			{
				repeticion = 0;
			}
			delay(1176);
			break;
			
		case 1:
			Derecha();
			repeticion++;
			if (repeticion == 3)
			{
				repeticion = 0;
			}
			delay(1176);
			break;
		}
	}
}

void Distancia() 
{
	digitalWrite(disparador, LOW);
	delayMicroseconds(2);
	digitalWrite(disparador, HIGH);
	delayMicroseconds(10);
	digitalWrite(disparador, LOW);

	tiempo = float(pulseIn(receptor, HIGH) / 2);	/* Tomo el tiempo de recepcion Echo */
	espacio = word(0.03432 * tiempo);

	Serial.print("Obstaculo a: ");
	Serial.print(espacio);
	Serial.println(" cm");
}

void Avanzar() 
{
	digitalWrite(IN1, LOW);
	digitalWrite(IN2, HIGH);
	digitalWrite(IN3, HIGH);
	digitalWrite(IN4, LOW);
}

void Retroceder()
{
	digitalWrite(IN1, HIGH);
	digitalWrite(IN2, LOW);
	digitalWrite(IN3, LOW);
	digitalWrite(IN4, HIGH);
}

void Izquierda()
{
	digitalWrite(IN1, HIGH);
	digitalWrite(IN2, LOW);
	digitalWrite(IN3, HIGH);
	digitalWrite(IN4, LOW);
}

void Derecha() 
{
	digitalWrite(IN1, LOW);
	digitalWrite(IN2, HIGH);
	digitalWrite(IN3, LOW);
	digitalWrite(IN4, HIGH);
}

Gracias por su tiempo!

Moderador: No repitas lo que se lee arriba

Gracias por responder!

No veo como estos consejos podrían solucionar mi problema más que para ordenar el código.
Utilizando la función Distancia() en el ciclo While debería solucionar esa parte ya que lo que quiero es que retroceda hasta estar a 23 cm del obstáculo (no veo como podría hacer eso con un if).
Estuve informándome un poco sobre la función millis() pero no veo como me seria de utilidad aquí, el tiempo que puse en el delay es aproximadamente lo que toma en realizar un giro de 90° a la rueda sin cambiarle la potencia, por ejemplo, ejecuto la función para girar a la Izquierda y luego detengo el programa el tiempo suficiente para que gire 90° mientras que el timer con millis(), hasta donde yo sé, sirve para ejecutar una acción cada cierto tiempo.
El problema perciste, si me equivoco en algo de lo que escribí aquí agradecería una corrección :slight_smile:

Independientemente de lo mucho que se pueda mejorar el programa, un problema que tienes con el while (espacio <= 23) es que cuando se cumple la condición, y entra en el bucle, el valor de la variable espacio no cambia dentro del bucle. Con lo que la condición siempre se cumplirá y nunca saldrá del bucle. Se quedará retrocediendo “para siempre”. Una solución “rápida”: actualizar el valor de espacio dentro del bucle llamando a la función Distancia() dentro del bucle:

		Distancia();
		while (espacio <= 23)
		{
			Retroceder();
			Distancia();  // <--- Actualiza el valor de espacio, para saber cuándo salir del bucle
		}