Proyecto 12 Tanque Seguidor Ultrasónico

Descripción

En el proyecto 11, hicimos un coche que evita obstáculos. De hecho, solo necesitamos alterar un código de prueba para transformar un coche que evita obstáculos en un coche seguidor. En esta lección, haremos un robot seguidor ultrasónico. El sensor ultrasónico detecta la distancia entre el coche inteligente y el obstáculo para conducir el tanque.

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

Detección

Distancia medida de obstáculos frontales

Distancia (unidad: cm)

Configuración

Ángulo del servo 90°

Panel LED 8X16 muestra el icono “V”

Si

20≤ distancia ≤60

Estado

Avanzar(establecer PWM a 200)

Si

10<distancia<20

distancia>60

Estado

Detener

Si

distancia ≤10

Estado

Retroceder(establecer PWM a 200)

Diagrama de flujo

Diagrama de Conexión

Nota de conexión:

Panel LED 8x16

Escudo Sensor V5

GND

-(GND)

VCC

+(VCC)

SDA

SDA

SCL

SCL

Código de Prueba

 /*
 keyestudio Mini Tank Robot V2.1
 lección 12
 tanque seguidor ultrasónico
 http://www.keyestudio.com
*/ 
//Matriz, utilizada para almacenar los datos del patrón, puede calcularse por sí mismo u obtenerse de la herramienta de módulo
unsigned char start01[] = {0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80,0x80,0x40,0x20,0x10,0x08,0x04,0x02,0x01};
unsigned char front[] = {0x00,0x00,0x00,0x00,0x00,0x24,0x12,0x09,0x12,0x24,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char back[] = {0x00,0x00,0x00,0x00,0x00,0x24,0x48,0x90,0x48,0x24,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char left[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x44,0x28,0x10,0x44,0x28,0x10,0x44,0x28,0x10,0x00};
unsigned char right[] = {0x00,0x10,0x28,0x44,0x10,0x28,0x44,0x10,0x28,0x44,0x00,0x00,0x00,0x00,0x00,0x00};
unsigned char STOP01[] = {0x2E,0x2A,0x3A,0x00,0x02,0x3E,0x02,0x00,0x3E,0x22,0x3E,0x00,0x3E,0x0A,0x0E,0x00};
unsigned char clear[] = {0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
#define SCL_Pin  A5  //Establecer pin de reloj a A5
#define SDA_Pin  A4  //Establecer pin de datos a A4

#define ML_Ctrl 13  //definir el pin de control de dirección del motor izquierdo
#define ML_PWM 11   //definir pin de control PWM del motor izquierdo
#define MR_Ctrl 12  //definir el pin de control de dirección del motor derecho
#define MR_PWM 3   //definir pin de control PWM del motor derecho
#define Trig 5  //pin Trig ultrasónico
#define Echo 4  //pin Echo ultrasónico
int distance;
int pulsewidth;
#define servoPin 9  //pin del servo
void setup(){
  Serial.begin(9600);
  pinMode(SCL_Pin,OUTPUT);
  pinMode(SDA_Pin,OUTPUT);
  matrix_display(clear); //Limpiar la pantalla
  matrix_display(start01);  //mostrar patrón de inicio
  pinMode(servoPin, OUTPUT);
  procedure(90); //establecer 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(){
  distance = checkdistance();  //asignar la distancia detectada por el sensor ultrasónico a distance
  if (distance >= 20 && distance <= 60) //rango para avanzar
  {
    Car_front();
  }
  else if (distance > 10 && distance < 20)  //rango para detener
  {
    Car_Stop();
  }
  else if (distance <= 10)  //rango para retroceder
  {
    Car_back();
  }
  else  //otras situaciones, detener
  {
    Car_Stop();
  }
}
/***********función para el funcionamiento del 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,200);
  digitalWrite(ML_Ctrl,HIGH);
  analogWrite(ML_PWM,200);
}
void Car_right()
{
  digitalWrite(MR_Ctrl,HIGH);
  analogWrite(MR_PWM,200);
  digitalWrite(ML_Ctrl,LOW);
  analogWrite(ML_PWM,200);
}
void Car_Stop()
{
  digitalWrite(MR_Ctrl,LOW);
  analogWrite(MR_PWM,0);
  digitalWrite(ML_Ctrl,LOW);
  analogWrite(ML_PWM,0);
}

/******************matriz de puntos********************/
// función para mostrar la matriz de puntos
void matrix_display(unsigned char matrix_value[])
{
  IIC_start(); // llamar a la función que inicia la transmisión de datos
  IIC_send(0xc0);  //Elegir dirección
  
  for(int i = 0;i < 16;i++) //los datos del patrón tienen 16 bits
  {
     IIC_send(matrix_value[i]); //datos para transmitir patrones
  }

  IIC_end();   //finalizar la transmisión del patrón de datos
  
  IIC_start();
  IIC_send(0x8A);  //seleccionar ancho de pulso 4/16, controlar la pantalla
  IIC_end();
}

//La condición para comenzar a transmitir datos
void IIC_start()
{
  digitalWrite(SCL_Pin,HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin,HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin,LOW);
  delayMicroseconds(3);
}

// transmitir datos
void IIC_send(unsigned char send_data)
{
  for(char i = 0;i < 8;i++)  //Cada byte tiene 8 bits
  {
      digitalWrite(SCL_Pin,LOW);  //bajar el pin de reloj SCL para cambiar las señales de SDA      
delayMicroseconds(3);
      if(send_data & 0x01)  //establecer el nivel alto y bajo de SDA_Pin según el 1 o 0 de cada bit
      {
        digitalWrite(SDA_Pin,HIGH);
      }
      else
      {
        digitalWrite(SDA_Pin,LOW);
      }
      delayMicroseconds(3);
      digitalWrite(SCL_Pin,HIGH); //subir el pin de reloj SCL_Pin para detener la transmisión de datos
      delayMicroseconds(3);
      send_data = send_data >> 1;  // detectar bit por bit, así que desplazar los datos a la derecha por uno
  }
}
//La señal de que la transmisión de datos ha finalizado
void IIC_end()
{
  digitalWrite(SCL_Pin,LOW);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin,LOW);
  delayMicroseconds(3);
  digitalWrite(SCL_Pin,HIGH);
  delayMicroseconds(3);
  digitalWrite(SDA_Pin,HIGH);
  delayMicroseconds(3);
}
/***************fin de la pantalla de matriz de puntos******************/
//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 la función del sensor ultrasónico controlando ultrasónico
float checkdistance() {
  digitalWrite(Trig, LOW);
  delayMicroseconds(2);
  digitalWrite(Trig, HIGH);
  delayMicroseconds(10);
  digitalWrite(Trig, LOW);
  float distance = pulseIn(Echo, HIGH) / 58.20;  //58.20, es decir, 2*29.1=58.2
  delay(10);
  return distance;
}
//****************************************************************

Resultado de la Prueba

Código cargado exitosamente, el interruptor DIP se gira hacia el extremo derecho, el servo gira a 90°, “V” se muestra en el panel LED 8X16 y el coche inteligente se mueve según se mueve el obstáculo.