Proyecto 11 Tanque Evasor Ultrasónico

Descripción

En este programa, el sensor ultrasónico detecta la distancia del obstáculo para enviar señales que controlan el robot coche. A continuación, te mostraremos cómo hacer un coche que evita obstáculos.

La lógica específica del robot evasor ultrasónico se muestra a continuación:

Diagrama de flujo

Diagrama de conexión:

Nota: Los pines “-”, “+” y “S” del servo están conectados respectivamente a G(GND), V(VCC)y D9 de la placa de expansión. El VCC, Trig, Echo y Gnd del sensor ultrasónico están conectados con 5v(V), 5(S), Echo y Gnd(G) de la placa de expansión.

Código de prueba:

/*
 keyestudio Mini Tank Robot V2.1
 lección 11
 ultrasonic_avoid_tank
 http://www.keyestudio.com
*/
int random2;
int a;
int a1;
int a2;
#define ML_Ctrl 13  //define el pin de control de dirección del motor izquierdo
#define ML_PWM 11   //define el pin de control PWM del motor izquierdo
#define MR_Ctrl 12  //define el pin de control de dirección del motor derecho
#define MR_PWM 3   //define el pin de control PWM del motor derecho

#define Trig 5  //pin Trig ultrasónico
#define Echo 4  //pin Echo ultrasónico
int distance;
#define servoPin 9  //pin del servo
int pulsewidth;
/************la función para ejecutar el motor**************/
void Car_front()
{
  digitalWrite(MR_Ctrl,LOW);
  analogWrite(MR_PWM,200);
  digitalWrite(ML_Ctrl,LOW);
  analogWrite(ML_PWM,200);
}
void Car_back()
{
  digitalWrite(MR_Ctrl,HIGH);
  analogWrite(MR_PWM,200);
  digitalWrite(ML_Ctrl,HIGH);
  analogWrite(ML_PWM,200);
}
void Car_left()
{
  digitalWrite(MR_Ctrl,LOW);
  analogWrite(MR_PWM,255);
  digitalWrite(ML_Ctrl,HIGH);
  analogWrite(ML_PWM,255);
}
void Car_right()
{
  digitalWrite(MR_Ctrl,HIGH);
  analogWrite(MR_PWM,255);
  digitalWrite(ML_Ctrl,LOW);
  analogWrite(ML_PWM,255);
}
void Car_Stop()
{
  digitalWrite(MR_Ctrl,LOW);
  analogWrite(MR_PWM,0);
  digitalWrite(ML_Ctrl,LOW);
  analogWrite(ML_PWM,0);
}

//La función para controlar el servo
void procedure(int myangle) {
  for (int i = 0; i <= 50; i = i + (1)) {
    pulsewidth = myangle * 11 + 500;
    digitalWrite(servoPin,HIGH);
    delayMicroseconds(pulsewidth);
    digitalWrite(servoPin,LOW);
    delay((20 - pulsewidth / 1000));
  }
}
//La función para controlar el sensor ultrasónico
float checkdistance() {
  digitalWrite(Trig, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig, LOW);
  float distance = pulseIn(Echo, HIGH) / 58.00;  //58.20, es decir, 2*29.1=58.2
  delay(10);
  return distance;
}
  //****************************************************************
void setup(){
  pinMode(servoPin, OUTPUT);
  procedure(90); //establece el servo a 90°
  
  pinMode(Trig, OUTPUT);
  pinMode(Echo, INPUT);
  pinMode(ML_Ctrl, OUTPUT);
  pinMode(ML_PWM, OUTPUT);
  pinMode(MR_Ctrl, OUTPUT);
  pinMode(MR_PWM, OUTPUT);
}
void loop(){
  random2 = random(1, 100);
  a = checkdistance();  //asigna la distancia frontal detectada por el sensor ultrasónico a la variable a
  
  if (a < 20) //cuando la distancia frontal detectada es menor que 20 
  {
      Car_Stop();  //el robot se detiene
      delay(500); //retraso de 500ms
      procedure(160);  //la plataforma ultrasónica gira a la izquierda
      for (int j = 1; j <= 10; j = j + (1)) { //sentencia for, los datos serán más precisos si el sensor ultrasónico detecta varias veces.
        a1 = checkdistance();  //asigna la distancia izquierda detectada por el sensor ultrasónico a la variable a1
      }
      delay(300);
      procedure(20); //la plataforma ultrasónica gira a la derecha
      for (int k = 1; k <= 10; k = k + (1)) {
        a2 = checkdistance(); //asigna la distancia derecha detectada por el sensor ultrasónico a la variable a2
      }
      
      if (a1 < 50 || a2 < 50)  //el robot girará hacia el lado de mayor distancia cuando la distancia izquierda o derecha es menor que 50cm. 
      {
        if (a1 > a2) //la distancia izquierda es mayor que el lado derecho      
        {
          procedure(90);  //la plataforma ultrasónica gira hacia adelante a la derecha         
          Car_left();  //el robot gira a la izquierda
          delay(500);  //gira a la izquierda durante 500ms
          Car_front(); //avanza
        } 
        else 
        {
          procedure(90);
          Car_right(); //el robot gira a la derecha
          delay(500);
          Car_front();  //avanza
        }
      } 
      else  //Si ambos lados son mayores o iguales a 50cm, gira a la izquierda o derecha aleatoriamente
      {
        if ((long) (random2) % (long) (2) == 0)  //Cuando el número aleatorio es par
        {
          procedure(90);
          Car_left(); //el robot tanque gira a la izquierda
          delay(500);
          Car_front(); //avanza
        } 
        else 
        {
          procedure(90);
          Car_right(); //el robot gira a la derecha
          delay(500);
          Car_front(); //avanza
       }
     }
  } 
  else  //Si la distancia frontal es mayor o igual a 20cm, el robot coche avanzará
  {
      Car_front(); //avanza
  }
}

Resultado de la prueba

Carga el código exitosamente, coloca el interruptor DIP hacia el extremo derecho y enciende, el robot tanque avanza y evita automáticamente el obstáculo.