Tankduino – tu primer tanque controlado desde tu smartphone

TANKDUINO

Contenidos

1. Introducción
2. Autoría
3. Componentes
4. Montaje
5. Código
6. Problemas encontrados
7. Mejoras
8. Conclusión

1.    Introducción

El proyecto consiste
en un tanque a control remoto mediante una conexión bluetooth.
La mayor parte de las
piezas del tanque están diseñadas e impresas en una impresora 3D, salvo el
cañón, que es una tubería de plástico adaptada en tamaño, y la plataforma
superior que es una madera, para poder atornillar bien los drivers y
controladores de Arduino.
En el siguiente Vídeo
mostramos el tanque en funcionamiento:

2.   
Autoría

Este Proyecto ha sido
realizado por los integrantes del grupo 3 de la asignatura Sistemas Empotrados
y Tiempo Real del año 2018/2019 en el Campus de Vicálvaro de la URJC:

  • Javier
    Rogina Gallego.
  •  Guillermo
    Castro Martínez.

3.    Componentes

Al ser un grupo de 2 personas
no se nos ha entregado ningún pack de Arduino, por lo que hemos tenido que
comprar todas las piezas. La inversión se ha realizado de la siguiente manera:
  • 2 x ELEGOO Conjunto
    Mas Completo y Avanzado de Iniciación a Arduino (55€/u). E
    ste pack incluye la
    placa de Arduino Mega 2560 y varios componentes que se suelen usar con mucha
    frecuencia.
  • 2x Motor Stepper con
    controlador (incluido en el pack Elengoo[1 en cada pack])
  • Placa de Arduino Mega 2560 (incluido
    en el pack Elengoo)
  • 4 x Motores 5-12V con estructura
    de engranaje (15,99€)
  • Driver L298 para motores DC (10€).
  • Module BT HC05 (13€).
  • 20x Pilas 9 Voltios. (2€/u).
  • Bobina PLA 1Kg (25€)
    • 64x Piezas de oruga (Diseño 3D). 
      • 4x Engranajes (Diseño 3D) 
      • 6x Conectores cuadrados (Diseño
        3D).
      • 2x Frontal (Diseño 3D).
      • 4x Guardabarros. (Diseño 3D).
      • 4x CubreRuedas. (Diseño 3D).
    • 2 x miniProtoplaca (incluido en el pack
      Elengoo).
    • Cables (incluido en el pack
      Elengoo).
    • Tubería de plástico 1cm de sección
      (0,5€).
    • Madera, tornillos, y pegamento
      (~12€).
    En total, unos 260€, teniendo en cuenta que no tengas ningún material desde el inicio.

    4.    Montaje

    Lo primer que hicimos
    para el montaje fue la parte inferior del tanque. Necesitábamos imprimir las
    piezas en la impresora 3D, lo que nos ha llevado alrededor de 9 días netos de
    Impresión:


    • 64x Piezas de oruga (1
      hora por pieza).
    • 4x Engranajes (3 horas
      por pieza).
    • 6X Conectores
      cuadrados (10 horas por pieza).
    • 2x Frontal (20 horas
      por pieza).
    • 4x Guardabarros. (5h por pieza).
    • 4x CubreRuedas. (5h por pieza).
    En el siguiente enlace se pueden descargar los diseños:
    https://mega.nz/#F!TEMzQAzK!UG1YQw-sWRlo1OBW4s0N8Q
    El tanque tiene 4
    motores DC montados en Paralelo 2 a 2, que provocan el movimiento de los
    engranajes de las orugas. Los Leds están todos montados en paralelo para
    encenderlos al mismo tiempo. A continuación, facilitamos unos bocetos del
    diseño final del tanque:
    Los componentes
    electrónicos están montados según se muestra en la siguiente imagen:




    Aquí ofrecemos unas imágenes del tanque real para que se
    aprecie cómo se ha montado:

    5.   
    Código

    Lo primero, vamos a
    explicar cómo configurar el Bluetooth HC-05, puesto que es necesario para tener
    la conectividad con el smartphone.


    Conexiones del HC-05
    para configurarlo:




    Código que debemos
    usar:


    #include
    <SoftwareSerial.h>
    SoftwareSerial
    mySerial (12, 13); // RX, TX
    void setup() {
      Serial.begin(9600);
      mySerial.begin(38400);
        while (!Serial) {
        ; // wait for serial port to connect.
    Needed for native USB port only
      }
      serial.print(“Configuración”);
    }
    void loop() {
      if (mySerial.available()) {
        Serial.write(mySerial.read());
      }
      if (Serial.available()) {
        mySerial.write(Serial.read());
      }
    }

    Antes de conectar el cable al pin de 5V, tras haber cargado el código en Arduino, debemos mantener pulsado el botón del dispositivo para entrar en AT (Modo configuración). Cuando el led del dispositivo parpadee levemente, es que hemos entrado.

    Abrimos el Serial (ponemos a “Ambos NL & CR” y 9600
    Baudios). Después ejecutamos los comandos en el siguiente Orden para ponerlo en
    modo esclavo:

    • AT+ORGL para hacer un
      reset de fábrica, por si tuviera ya una configuración puesta.
    • AT+NAME? Para
      comprobar el nombre del dispositivo.
    • AT+ROLE? Para ver si
      es Esclavo o Maestro. (0=Esclave, 1=Maestro)
    • AT+PSWD?  Para comprobar qué PIN tiene.
    • AT+UART? para
      comprobar la velocidad a la que se conectarán los BT (debe ser 9600).
    Si queremos cambiar
    alguno de esos parámetros debemos asignarle un nuevo valor. Ejemplo con
    AT+NAME:

    AT+NAME=Nombre

    Este es el nombre que
    aparecerá al buscarlo con nuestro smartphone.


    Tras esto, ya se puede
    conectar a la placa con todos los demás componentes, a la que hemos cargado el
    siguiente código:
    //@Autor Javier Rogina & Guillermo Castro
    // Pines del Motor Driver.
    int ena = 48;
    int enb = 53;
    int in1 = 49; //Primer Pin para manejar motor A.
    int in2 = 50; //Segundo Pin para manejar motor A.
    int in3 = 51; //Primer Pin para manejar motor B.
    int in4 = 52; //Segundo Pin para manejar motor B.
    //Pines del Stepper de la Torreta
    int s1 = 9;
    int s2 = 10;
    int s3 = 11;
    int s4 = 12;
    //Pines del Stepper del Cañón
    int s5 = 5;
    int s6 = 6;
    int s7 = 7;
    int s8 = 8;
        
    void setup() {
      //Declaramos todos los pines que
    vamos a usar.
      pinMode(13, OUTPUT);
      pinMode(s1, OUTPUT);
      pinMode(s2, OUTPUT);
      pinMode(s3, OUTPUT);
      pinMode(s4, OUTPUT);
      pinMode(s5, OUTPUT);
      pinMode(s6, OUTPUT);
      pinMode(s7, OUTPUT);
      pinMode(s8, OUTPUT);
      pinMode(ena, OUTPUT);
      pinMode(enb, OUTPUT);
      pinMode(in1, OUTPUT);
      pinMode(in2, OUTPUT);
      pinMode(in3, OUTPUT);
      pinMode(in4, OUTPUT);
      Serial.begin(9600); //iniciamos
    el serial que se comunicará con el dispositivo BT.
     }
    void cannon_Arriba() {
      //Mueve el Stepper del caón hacia
    arriba(si el tanque está en posición frontal) un paso.
     digitalWrite(s5, HIGH);
     digitalWrite(s6, LOW);
     digitalWrite(s7, LOW);
     digitalWrite(s8, LOW);
     delay(2); //Es obligatorio poner
    un delay de almenos 2, ya que sino no hace los pasos correctamente.
     digitalWrite(s5, HIGH);
     digitalWrite(s6, HIGH);
     digitalWrite(s7, LOW);
     digitalWrite(s8, LOW);
     delay(2);
     digitalWrite(s5, LOW);
     digitalWrite(s6, HIGH);
     digitalWrite(s7, LOW);
     digitalWrite(s8, LOW);
     delay(2);
      digitalWrite(s5, LOW);
     digitalWrite(s6, HIGH);
     digitalWrite(s7, HIGH);
     digitalWrite(s8, LOW);
     delay(2);
     digitalWrite(s5, LOW);
     digitalWrite(s6, LOW);
     digitalWrite(s7, HIGH);
     digitalWrite(s8, LOW);
     delay(2);
     digitalWrite(s5, LOW);
     digitalWrite(s6, LOW);
     digitalWrite(s7, HIGH);
     digitalWrite(s8, HIGH);
     delay(2);
     digitalWrite(s5, LOW);
     digitalWrite(s6, LOW);
     digitalWrite(s7, LOW);
     digitalWrite(s8, HIGH);
     delay(2);
     digitalWrite(s5, HIGH);
     digitalWrite(s6, LOW);
     digitalWrite(s7, LOW);
     digitalWrite(s8, HIGH);
     }
     void cannon_Abajo() {
      //Baja el cañón.
     digitalWrite(s5, LOW);
     digitalWrite(s6, LOW);
     digitalWrite(s7, LOW);
     digitalWrite(s8, HIGH);
     delay(2);
     digitalWrite(s5, LOW);
     digitalWrite(s6, LOW);
     digitalWrite(s7, HIGH);
     digitalWrite(s8, HIGH);
     delay(2);
     digitalWrite(s5, LOW);
     digitalWrite(s6, LOW);
     digitalWrite(s7, HIGH);
     digitalWrite(s8, LOW);
     delay(2);
     digitalWrite(s5, LOW);
     digitalWrite(s6, HIGH);
     digitalWrite(s7, HIGH);
     digitalWrite(s8, LOW);
     delay(2);
     digitalWrite(s5, LOW);
     digitalWrite(s6, HIGH);
     digitalWrite(s7, LOW);
     digitalWrite(s8, LOW);
     delay(2);
     digitalWrite(s5, HIGH);
     digitalWrite(s6, HIGH);
     digitalWrite(s7, LOW);
     digitalWrite(s8, LOW);
     delay(2);
     digitalWrite(s5, HIGH);
     digitalWrite(s6, LOW);
     digitalWrite(s7, LOW);
     digitalWrite(s8, LOW);
     delay(2);
     digitalWrite(s5, HIGH);
     digitalWrite(s6, LOW);
     digitalWrite(s7, LOW);
     digitalWrite(s8, HIGH);
     delay(2);
     }
    void torreta_Derecha() {
      //Mueve la torreta en sentido
    agujas del reloj un paso.
     digitalWrite(s1, HIGH);
     digitalWrite(s2, LOW);
     digitalWrite(s3, LOW);
     digitalWrite(s4, LOW);
     delay(2);
     digitalWrite(s1, HIGH);
     digitalWrite(s2, HIGH);
     digitalWrite(s3, LOW);
     digitalWrite(s4, LOW);
     delay(2);
     digitalWrite(s1, LOW);
     digitalWrite(s2, HIGH);
     digitalWrite(s3, LOW);
     digitalWrite(s4, LOW);
     delay(2);
      digitalWrite(s1, LOW);
     digitalWrite(s2, HIGH);
     digitalWrite(s3, HIGH);
     digitalWrite(s4, LOW);
     delay(2);
     digitalWrite(s1, LOW);
     digitalWrite(s2, LOW);
     digitalWrite(s3, HIGH);
     digitalWrite(s4, LOW);
     delay(2);
     digitalWrite(s1, LOW);
     digitalWrite(s2, LOW);
     digitalWrite(s3, HIGH);
     digitalWrite(s4, HIGH);
     delay(2);
     digitalWrite(s1, LOW);
     digitalWrite(s2, LOW);
     digitalWrite(s3, LOW);
     digitalWrite(s4, HIGH);
     delay(2);
     digitalWrite(s1, HIGH);
     digitalWrite(s2, LOW);
     digitalWrite(s3, LOW);
     digitalWrite(s4, HIGH);
     }
     void torreta_Izquierda() {
      //Mueve la torreta en sentido
    antihorario un paso.
     digitalWrite(s1, LOW);
     digitalWrite(s2, LOW);
     digitalWrite(s3, LOW);
     digitalWrite(s4, HIGH);
     delay(2);
     digitalWrite(s1, LOW);
     digitalWrite(s2, LOW);
     digitalWrite(s3, HIGH);
     digitalWrite(s4, HIGH);
     delay(2);
     digitalWrite(s1, LOW);
     digitalWrite(s2, LOW);
     digitalWrite(s3, HIGH);
     digitalWrite(s4, LOW);
     delay(2);
     digitalWrite(s1, LOW);
     digitalWrite(s2, HIGH);
     digitalWrite(s3, HIGH);
     digitalWrite(s4, LOW);
     delay(2);
     digitalWrite(s1, LOW);
     digitalWrite(s2, HIGH);
     digitalWrite(s3, LOW);
     digitalWrite(s4, LOW);
     delay(2);
     digitalWrite(s1, HIGH);
     digitalWrite(s2, HIGH);
     digitalWrite(s3, LOW);
     digitalWrite(s4, LOW);
     delay(2);
     digitalWrite(s1, HIGH);
     digitalWrite(s2, LOW);
     digitalWrite(s3, LOW);
     digitalWrite(s4, LOW);
     delay(2);
     digitalWrite(s1, HIGH);
     digitalWrite(s2, LOW);
     digitalWrite(s3, LOW);
     digitalWrite(s4, HIGH);
     delay(2);
     }
     void motor_alante(){
     digitalWrite(ena, 255); //Potencia
    del motor A (0-255).
     digitalWrite(enb, 255); //Potencia
    del motor B (0-255).
     digitalWrite(in1, HIGH); //Motor A
    sentido horario.
     digitalWrite(in2, LOW);
     digitalWrite(in3, HIGH); // Motor
    B sentido horario.
     digitalWrite(in4, LOW);
     }
     void motor_atras(){
     digitalWrite(ena, 255); //Potencia
    del motor A (0-255).
     digitalWrite(enb, 255); //Potencia
    del motor B (0-255).
     digitalWrite(in1, LOW);
     digitalWrite(in2, HIGH); // Motor
    A sentido antihorario.
     digitalWrite(in3, LOW);
     digitalWrite(in4, HIGH); // Motor
    B sentido antihorario.
     }
     void motor_derecha(){
      //Se apagan los motores derechos,
    de manera que la oruga izquierda hace el movimiento y simula el giro.
     digitalWrite(ena, 255);  //Potencia del motor A (0-255).
     digitalWrite(enb, 0);    //Motor B apagado.
     digitalWrite(in1, HIGH); //Motor A
    sentido horario.
     digitalWrite(in2, LOW);
     digitalWrite(in3, LOW); //Motor B
    apagado.
     digitalWrite(in4, LOW); //Motor B
    apagado.
     }
     void motor_izquierda(){
      //Se apagan los motores
    izquierdos para simular el giro a la derecha.
     digitalWrite(ena, 0); //Motor B
    apagado.
     digitalWrite(enb, 255); //Potencia
    del motor B (0-255).
     digitalWrite(in1, LOW); //Motor A
    apagado.
     digitalWrite(in2, LOW); //Motor A
    apagado.
     digitalWrite(in3, HIGH);
    //Potencia del motor A (0-255).
     digitalWrite(in4, LOW);
     }
     void disparar(){
      //Enciende el Led 2 segundos y
    luego lo apaga (simula el disparo).
      digitalWrite(13, 255);
      delay(2000);
      digitalWrite(13, 0);
      }
     void pausa(){
     //Apaga todos los motores para que
    el tanque permanezca en el sitio.
     digitalWrite(ena, 0);
     digitalWrite(enb, 0);
     digitalWrite(in1, LOW);
     digitalWrite(in2, LOW);
     digitalWrite(in3, LOW);
     digitalWrite(in4, LOW);
      }
     void loop(){
      int varBT = Serial.read();
    //Leemos lo que manda el smartphone.
      int vari = varBT – 48; //Al ser
    un Char ASCII, restamos 48 para simular números del 1 al 9.
      switch (varBT) { //Dependiendo de
    lo que hayamos recibido:
        case ‘0’:
          motor_derecha(); //Giro a la derecha
          break;
        case ‘1’:
          motor_izquierda(); //Giro a
    la izquierda
          break;
        case ‘2’:
          motor_atras(); //Marcha atrás
          break;
        case ‘3’:
          motor_alante(); //Avanzar
          break;
        case ‘4’:
          cannon_Arriba(); //Sube el
    cañón.
          break;      
        case ‘5’:
          cannon_Abajo(); //Baja el
    cañon.
          break;
        case ‘6’:
          torreta_Derecha(); //Gira la
    torreta sentido horario.
          break;
        case ‘7’:
          torreta_Izquierda(); //Gira
    la torreta sentido antihorario.
          break;
        case ‘8’:
          disparar(); //Enciende el Led
    del cañon.
          break;  
        case ‘9’:
          pausa(); //Para los motores.
          break;          
        default:
          //Nada. Si recibimos datos
    erróneos (el -1 se recibe si se pierde la conexión hasta que se conecta de
    nuevo)
          break;
      }
     }
    Para controlar el
    tanque, hemos usado la aplicación Arduino BlueTooth Control. Para conectarlo,
    debemos emparejarnos con el dispositivo HC-05 que hemos usado,

    Usamos la opción
    Controller mode.



    En la configuración,
    hemos puesto lo siguiente:

    • Flecha Arriba: 3
    • Flecha Abajo: 2
    • Fecha derecha: 0
    • Flecha izquierda: 1
    • Triángulo: 4
    • Cuadrado:  7
    • Círculo: 5
    • Equis: 6
    • Select: 8
    • Start: 9
    Que corresponde con
    los distintos “Case” del código del tanque.


    6.   
    Problemas encontrados

    6.1 Disparo del tanque

    En un principio teníamos pensado hacer que el tanque
    disparase pelotas de goma, o de caucho. Probamos usando un solenoide de 32V,
    pero no tenía la fuerza suficiente como percusor para disparar. Este problema
    intentamos reconducirlo con dos ruedas que girasen y aumentaran la velocidad
    instantánea de la pelota al entrar en contacto con ellas (Como un lanzapelotas
    de Golf o Tenis), pero la potencia que se necesitaba era demasiado alta, y las
    pilas caían como moscas. Entonces se nos vino a la cabeza usar un sistema de
    ballesta o catapulta, pero ocupaba demasiado espacio en la plataforma del
    tanque, y los servos que usábamos (sg90) no aguantaban la tensión de la cuerda/goma
    elástica.

    Finalmente, decidimos poner un led al final del cañón para
    simular el disparo con luz.

    6.2  Espacio

    Tras imprimir las piezas de la parte inferior del tanque,
    nos dimos cuenta de que no tenía espacio suficiente para albergar los 4
    motores, la protoplaca y la placa Arduino. Para solucionarlo, pusimos un
    separador más (inicialmente 3), y tuvimos que sumarle 2 piezas más a la oruga.

    6.3  Parte
    Superior

    Solucionar el problema anterior originó un nuevo problema.
    La parte superior del tanque que habíamos impreso no encajaba. Al haber gastado
    tanto PLA (1Kg aproximadamente), y por falta de tiempo y recursos, decidimos
    suplirlo con una madera en la que encajamos todos los controladores en la parte
    inferior.

    6.4  Potencia
    Motores

    Tras incorporar todos los componentes en el tanque, y hacer
    la primera prueba con todo el peso, vimos que una pila de 9V no era suficiente
    para los motores. Por eso mismo usamos 2 pilas de 9V en serie (18V)  lo que aumentó el rendimiento
    considerablemente.

    6.5  Mando
    Bluetooth

    Una de las partes de este proyecto era construir un mando a
    distancia con 2 JoySticks y un módulo BT para manejar el tanque. El problema
    que encontramos fue que la sincronización de ambos módulos BT no se realizaba
    correctamente, cada pocos segundos se perdía la conexión. Tras consultar en
    Foros de Arduino, vimos que parecía un problema de fábrica de algunas unidades
    del módulo HC-05 que impedía conectarse Master-Slave con otro HC-05, y que era
    necesario un HC-06. Por eso mismo, decidimos usar la aplicación Arduino
    Bluetooth Control, que solucionó el problema en su totalidad.

    6.6  Servo
    VS Stepper

    La parte del tanque y del cañón, en un principio, eran dos
    servos. Uno manejaba el eje X y el otro el Eje y. Sin embargo, en cuanto le
    pusimos la tubería, el Servo ya no podía levantar el Peso, y el giro de la
    torreta era irregular. Esto lo solucionamos con 2 motores Steppers, que giraban
    360º y tienen mayor fuerza si se programan adecuadamente.

    6.7  Consumo
    de Pilas

    Durante el proyecto, usamos una gran cantidad de pilas de 9V
    para pruebas, alrededor de 20. Este problema pensamos en solucionarlo con un
    PowerBank de 20mil mAh para conectarlo a la placa, pero el peso era demasiado y
    hacía oscilar al tanque. Como el consumo de pila es, en su mayoría, por el
    controlador de los motores, decidimos dejarlo como estaba.

    7.   
    Mejoras que se podrían hacer.

    Una de las cosas que se nos ha quedado pendientes de este
    proyecto es hacer el movimiento del tanque progresivo. Es decir, que se pueda
    elegir la velocidad de los motores DC. Esto se haría con los pines ENA y ENB del driver, indicándoles
    un valor de 0 a 255.

    Para disparar el tanque vimos, demasiado tarde para
    probarlo, que se puede hacer con aire comprimido, y se le puede regular la
    potencia.

    Las orugas son de PLA, y resbala en superficies lisas. Se
    podría incorporar cierta adherencia con puntos de silicona colocados en cada
    pieza (pero no en las juntas), o usando FilaFlex en vez de PLA. Nosotros no
    pudimos hacerlo por falta de tiempo y dinero.

    8.   
    Conclusión.

    El tanque es bastante complejo, y quizá ha sido un proyecto
    muy largo para hacer en estos 2-3 meses. Si hubiésemos sabido el tiempo de
    impresión de las piezas lo hubiéramos priorizado, aunque era difícil saber qué
    imprimir sin tener claro qué componentes íbamos a usar.
    En cualquier caso, este proyecto nos ha servido para optimizar
    el espacio y los pines de la placa de Arduino, y nos ha ayudado a ver lo fácil
    que es hacer cualquier cosa con este tipo de sistemas si le pones empeño y
    tiempo, y la versatilidad con la que se solucionan los problemas gracias al
    Open Source.

    También te podría gustar...

    Deja un comentario

    Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *