Carrito evita obstaculos

Tengo este codigo utilizo una placa de arduino uno, un modulo L298N, dos motores es un pero al momento de avanzar solo gira una rueda y cuando detecta giran independientemente las ruedas en ningun momento se activan los dos ruedas cual puede ser el problema.

/ ==========================================
// CONFIGURACIÓN DE PINES (TU CONEXIÓN REAL FÍSICA)
// ==============

============================
const int Trigger = 7; // Ajustado a tu cable real
const int Echo = 6; // Ajustado a tu cable real
int t;
int tiempo = 5000;
#define MAX_DISTANCE 200

// Pines de motores mapeados exactamente a tu fila física (5, 4, 3, 2)
#define IN1 2 // Rueda Derecha (Cable Morado)
#define IN2 3 // Rueda Derecha (Cable Naranja - Soporta PWM ~)
#define IN3 4 // Rueda Izquierda (Cable Amarillo)
#define IN4 5 // Rueda Izquierda (Cable Verde - Soporta PWM ~)

// Máquina de estados
enum EstadoRobot {
AVANZANDO,
RETROCEDIENDO,
ESQUIVANDO,
ATASCADO
};

EstadoRobot estado = AVANZANDO;

// Control de movimiento (Usamos 255 para máxima tracción inicial en tus motores)
int velocidad = 255;
int distancia = 100;
int contadorFallo = 0;
unsigned long tiempoCambio = 0;

void setup() {
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);

pinMode(Trigger, OUTPUT);
pinMode(Echo, INPUT);
digitalWrite(Trigger, LOW);

// Pines de tus LEDs de diagnóstico (Mantén tus conexiones actuales)
pinMode(9, OUTPUT);
pinMode(12, OUTPUT);
pinMode(13, OUTPUT);

Serial.begin(9600);
detener();
}

void loop() {
// 1. MEDICIÓN DEL SENSOR ULTRASÓNICO
digitalWrite(Trigger, HIGH);
delayMicroseconds(10);
digitalWrite(Trigger, LOW);

t = pulseIn(Echo, HIGH, 20000); // Mide con seguro anti-congelamiento

// Guardamos la lectura real en "distancia" para la máquina de estados
distancia = round(t / 59);

if (distancia == 0) {
distancia = 100; // Si falla la lectura, asume camino despejado
}

Serial.print("Distancia: ");
Serial.print(distancia);
Serial.println(" cm");

mostrarEstado();

// 2. MÁQUINA DE ESTADOS (TUS DECISIONES INTACTAS)
switch (estado) {
case AVANZANDO:
if (distancia < 25) { // Detecta obstáculo a menos de 25cm
detener();
estado = RETROCEDIENDO;
tiempoCambio = millis();
contadorFallo++;
} else {
moverAdelante(velocidad);
}
break;

case RETROCEDIENDO:
  moverAtras(velocidad);
  if (millis() - tiempoCambio > 500) { // Retrocede por medio segundo
    detener();
    estado = ESQUIVANDO;
    tiempoCambio = millis();
  }
  break;

case ESQUIVANDO:
  if (distancia < 25) {
    girarAleatorio(); 
    tiempoCambio = millis();
  } else {
    estado = AVANZANDO;
    contadorFallo = 0; 
  }

  if (contadorFallo >= 3) {
    estado = ATASCADO;
    tiempoCambio = millis();
  }
  break;

case ATASCADO:
  detener();
  Serial.println("⚠ ATASCADO. Esperando reinicio...");
  
  // Destello del LED indicador de atasco (Pin 9)
  for(int i = 0; i < 5; i++){
    digitalWrite(9, HIGH); delay(200);
    digitalWrite(9, LOW); delay(200);
  }
  
  contadorFallo = 0;
  estado = AVANZANDO;
  break;

}

delay(60); // Breve pausa de estabilidad térmica y de procesamiento
}

// ====================================================================
// FUNCIONES DE MOVIMIENTO ADAPTADAS A TU MATRIZ DE PINES FÍSICOS (2,3,4,5)
// ====================================================================

void moverAdelante(int vel) {
// Configuración unificada: Ambos motores reciben la orden de empujar al frente.
// Usamos el estado LOW/HIGH coordinado que descubrimos en la prueba anterior.
digitalWrite(IN1, LOW);
analogWrite(IN2, vel);

delay(10); // Pausa milimétrica para evitar caídas de tensión en el chip L298N

digitalWrite(IN3, LOW);
analogWrite(IN4, vel);
}

void moverAtras(int vel) {
// Invierte el sentido exacto de la marcha hacia atrás de forma segura
analogWrite(IN2, 0);
digitalWrite(IN1, HIGH);

delay(10);

analogWrite(IN4, 0);
digitalWrite(IN3, HIGH);
}

void detener() {
// Freno electrónico absoluto e inmediato
digitalWrite(IN1, LOW);
analogWrite(IN2, 0);
digitalWrite(IN3, LOW);
analogWrite(IN4, 0);
}

void girarAleatorio() {
detener();
delay(200);

if (random(0, 2) == 0) {
// Giro Izquierda rápido sobre su propio eje
digitalWrite(IN1, LOW);
analogWrite(IN2, velocidad);
digitalWrite(IN3, HIGH);
analogWrite(IN4, 0);
delay(450);
} else {
// Giro Derecha rápido sobre su propio eje
digitalWrite(IN1, HIGH);
analogWrite(IN2, 0);
digitalWrite(IN3, LOW);
analogWrite(IN4, velocidad);
delay(450);
}
detener();
delay(100);
}

// === VISUALIZACIÓN POR LEDS (MANTIENE TU DISEÑO ORIGINAL) ===
void mostrarEstado() {
switch (estado) {
case AVANZANDO:
digitalWrite(12, HIGH);
digitalWrite(13, LOW);
digitalWrite(9, LOW);
break;

case RETROCEDIENDO:
case ESQUIVANDO:
  digitalWrite(12, LOW);
  digitalWrite(13, HIGH);
  digitalWrite(9, LOW);
  break;

case ATASCADO:
  digitalWrite(12, LOW);
  digitalWrite(13, LOW);
  digitalWrite(9, HIGH);
  break;

}
}

He trasladado su tema de una categoría de idioma inglés del foro a la categoría International > Español @gustavolojan.

En adelante por favor usar la categoría apropiada a la lengua en que queráis publicar. Esto es importante para el uso responsable del foro, y esta explicado aquí la guía "How to get the best out of this forum".
Este guía contiene mucha información útil. Por favor leer.

De antemano, muchas gracias por cooperar.

Seguramente ese código te lo sugirió una IA, está mal.

Te dejo el link a un tutorial sobre el 298.