RoboAraña

RoboAraña: Robot Articulable Controlado por Bluetooth

1. Introducción

Nuestro proyecto consiste en una Robo Araña articulable movida mediante servomotores y controlada vía Bluetooth. Esta tiene diversos movimientos precargados que simulan movimientos típicos de una araña. La principal motivación para la ejecución de este proyecto era desarrollar un proyecto que fuese un sustituto de los proyectos de iniciación para el entorno Arduino, de forma que este fuese más completo ya que consta de nuevos retos como la soldadura y la creación de apps. Este proyecto a su vez ofrece muchas opciones de ampliación como podría ser un control por voz o un modo de búsqueda.

2. Descripción del Proyecto

La RoboAraña es un conjunto de 8 servomotores controlado por un cerebro, el ESP32. Los 8 motores hacen de brazos y pies para la araña permitiendo articular los pies un máximo de 80º y un máximo de 110º los brazos. Todo esto se encuentra unido gracias a una sólida estructura 3D impresa en PLA resistente para una mayor durabilidad. Con todo ello podemos conseguir la modularidad y ampliabilidad deseada para el proyecto.

Objetivos

  • Diseñar y construir un robot araña funcional con movimientos coordinados.
  • Integrar hardware (ESP32, servomotores, PCB) y software (código en C++) de manera eficiente.
  • Conseguir un control inalámbrico.
  • Ensamblar todos los componentes en un entorno empotrado.

3. Implementación

3.1. Hardware

El hardware del robot se diseñó para ser modular, ampliable y resistente. Los componentes principales son:

  • Microcontrolador: ESP32, seleccionado por su capacidad de procesamiento, conectividad Wi-Fi/Bluetooth y 30 pines GPIO disponibles, perfecto para controlar los 8 servomotores.
  • Servomotores: 8x SG90 (dos por pata), responsables de las articulaciones de las patas. Los 8 de 120º.
  • Estructura: Cuerpo y patas fabricados mediante impresión 3D con filamento PLA resistente, diseños probados y fabricados gracias a un compañero de ingeniería industrial.
  • PCB personalizada: Fabricada por PCBWay, nos hace de conector entre todos los servomotores ayudando a la limpieza del proyecto y a que las conexiones sean más simples.
  • Baterías: Debido a problemas se decidió usar dos portapilas modificados para usar 4 pilas cada uno AA.
  • Otros componentes: Cables propios de los servomotores, otros modificados para alimentar el circuito y la ESP32 además de tornillos.
RoboAraña Hardware

3.2. Software

El software se desarrolló en el entorno Arduino IDE, utilizando la biblioteca ESP32 Servo para controlar los servomotores y la biblioteca BluetoothSerial para permitir la conexión entre la araña y la app diseñada para controlarla. La lógica del movimiento se basa en secuencias predefinidas que coordinan los ángulos de los servos para simular el caminar de una araña. El código incluye funciones para avanzar, girar a la izquierda/derecha, subir y bajar, y detenerse. Además de una función para hacer parpadear unos LEDs.

Código principal:

#include "BluetoothSerial.h"
#include 

// Constantes de configuración
const char* NOMBRE_BLUETOOTH = "@G4";
const int BAUD_RATE = 115200;
const int PIN_LED = 23;

// Pines de los servomotores
const int PIN_PIE_A = 13;
const int PIN_BRAZO_A = 12;
const int PIN_PIE_B = 15;
const int PIN_BRAZO_B = 2;
const int PIN_PIE_C = 26;
const int PIN_BRAZO_C = 25;
const int PIN_PIE_D = 17;
const int PIN_BRAZO_D = 5;

// Límites de movimiento y velocidad
const int LIMITE_PIE_ABAJO = 60;  // Límite inferior del pie
const int LIMITE_PIE_ARRIBA = 80; // Límite superior del pie
const int LIMITE_BRAZO_ATRAS = 70; // Límite trasero del brazo
const int LIMITE_BRAZO_ADELANTE = 110; // Límite delantero del brazo
const int VELOCIDAD_MOVIMIENTO = 4; // Velocidad

// Comandos Bluetooth
enum ComandosBluetooth {
  ARRIBA = 50,
  ABAJO = 51,
  CAMINAR = 52,
  GIRAR = 53,
  PARPADEAR = 54,
  DETENER = 55,
  RETROCEDER = 56,
  DERECHA = 57,
  IZQUIERDA = 58
};

// Objetos globales
BluetoothSerial SerialBT;
Servo servo_pieA, servo_brazoA;
Servo servo_pieB, servo_brazoB;
Servo servo_pieC, servo_brazoC;
Servo servo_pieD, servo_brazoD;
int datoBluetooth;

#if !defined(CONFIG_BT_ENABLED) || !defined(CONFIG_BLUEDROID_ENABLED)
#error ¡Bluetooth no está habilitado! Ejecute `make menuconfig` para activarlo.
#endif

void setup() {
  servo_pieA.attach(PIN_PIE_A);
  servo_brazoA.attach(PIN_BRAZO_A);
  servo_pieB.attach(PIN_PIE_B);
  servo_brazoB.attach(PIN_BRAZO_B);
  servo_pieC.attach(PIN_PIE_C);
  servo_brazoC.attach(PIN_BRAZO_C);
  servo_pieD.attach(PIN_PIE_D);
  servo_brazoD.attach(PIN_BRAZO_D);

  pinMode(PIN_LED, OUTPUT);
  Serial.begin(BAUD_RATE);
  SerialBT.begin(NOMBRE_BLUETOOTH);
  Serial.println("¡Bluetooth iniciado! Listo para emparejar...");

  detener();
  delay(1000);
}

void loop() {
  if (SerialBT.available()) {
    datoBluetooth = SerialBT.read();
  }

  switch (datoBluetooth) {
    case GIRAR:
      digitalWrite(PIN_LED, HIGH);
      girar();
      digitalWrite(PIN_LED, LOW);
      break;
    case CAMINAR:
      digitalWrite(PIN_LED, HIGH);
      caminar();
      digitalWrite(PIN_LED, LOW);
      break;
    case PARPADEAR:
      inclinar(true);
      digitalWrite(PIN_LED, HIGH);
      break;
    case ARRIBA:
      subir_plano();
      break;
    case ABAJO:
      bajar_plano();
      subir_plano();
      break;
    case DETENER:
      detener();
      digitalWrite(PIN_LED, LOW);
      break;
    case RETROCEDER:
      digitalWrite(PIN_LED, HIGH);
      retroceder();
      digitalWrite(PIN_LED, LOW);
      break;
    case DERECHA:
      digitalWrite(PIN_LED, HIGH);
      moverDerecha();
      digitalWrite(PIN_LED, LOW);
      break;
    case IZQUIERDA:
      digitalWrite(PIN_LED, HIGH);
      moverIzquierda();
      digitalWrite(PIN_LED, LOW);
      break;
  }
}

// Movimientos agrupados
void caminar() {
  avanzar();
  mover_pie(servo_pieA, true);
  mover_brazo(servo_brazoA, true);
  mover_pie(servo_pieA, false);
  mover_pie(servo_pieC, true);
  mover_brazo(servo_brazoC, false);
  mover_pie(servo_pieC, false);
  mover_pie(servo_pieB, true);
  mover_brazo(servo_brazoB, false);
  mover_pie(servo_pieB, false);
  mover_pie(servo_pieD, true);
  mover_brazo(servo_brazoD, true);
  mover_pie(servo_pieD, false);
}

void girar() {
  mover_brazo(servo_brazoA, true);
  mover_brazo(servo_brazoB, true);
  mover_brazo(servo_brazoC, true);
  mover_brazo(servo_brazoD, true);
  mover_pie(servo_pieA, true);
  mover_brazo(servo_brazoA, false);
  mover_pie(servo_pieA, false);
  mover_pie(servo_pieB, true);
  mover_brazo(servo_brazoB, false);
  mover_pie(servo_pieB, false);
  mover_pie(servo_pieC, true);
  mover_brazo(servo_brazoC, false);
  mover_pie(servo_pieC, false);
  mover_pie(servo_pieD, true);
  mover_brazo(servo_brazoD, false);
  mover_pie(servo_pieD, false);
}

void mover_servo(Servo &servo, int inicio, int fin) {
  int paso = (fin > inicio) ? 1 : -1;
  for (int i = inicio; i != fin; i += paso) {
    servo.write(i);
    delay(VELOCIDAD_MOVIMIENTO);
  }
}

void avanzar() {
  for (int i = LIMITE_BRAZO_ATRAS; i <= LIMITE_BRAZO_ADELANTE; i++) {
    servo_brazoA.write(i);
    servo_brazoD.write(i);
    int y = LIMITE_BRAZO_ATRAS + LIMITE_BRAZO_ADELANTE - i;
    servo_brazoC.write(y);
    servo_brazoB.write(y);
    delay(VELOCIDAD_MOVIMIENTO);
  }
}

void subir_plano() {
  int inicio = LIMITE_PIE_ABAJO + 5;
  int fin = LIMITE_PIE_ARRIBA + 55;
  servo_pieA.write(inicio);
  servo_pieB.write(inicio);
  servo_pieC.write(inicio);
  servo_pieD.write(inicio);
  delay(500);
  for (int i = inicio; i <= fin; i++) {
    servo_pieA.write(i);
    servo_pieB.write(i);
    servo_pieC.write(i);
    servo_pieD.write(i);
    delay(VELOCIDAD_MOVIMIENTO);
  }
  delay(500);
}

void inclinar(bool haciaDerecha) {
  int inicioDerecha = haciaDerecha ? LIMITE_PIE_ARRIBA + 5 : LIMITE_PIE_ABAJO + 5;
  int finDerecha = haciaDerecha ? LIMITE_PIE_ABAJO + 5 : LIMITE_PIE_ARRIBA + 5;
  int inicioIzquierda = haciaDerecha ? LIMITE_PIE_ABAJO + 5 : LIMITE_PIE_ARRIBA + 5;
  int finIzquierda = haciaDerecha ? LIMITE_PIE_ARRIBA + 5 : LIMITE_PIE_ABAJO + 5;

  servo_pieA.write(inicioDerecha);
  servo_pieB.write(inicioDerecha);
  servo_pieC.write(inicioIzquierda);
  servo_pieD.write(inicioIzquierda);
  delay(500);

  for (int i = 0; i <= abs(finDerecha - inicioDerecha); i++) {
    int anguloDerecha = haciaDerecha ? (inicioDerecha - i) : (inicioDerecha + i);
    int anguloIzquierda = haciaDerecha ? (inicioIzquierda + i) : (inicioIzquierda - i);
    servo_pieA.write(anguloDerecha);
    servo_pieB.write(anguloDerecha);
    servo_pieC.write(anguloIzquierda);
    servo_pieD.write(anguloIzquierda);
    delay(VELOCIDAD_MOVIMIENTO);
  }
  delay(2000);

  int posicionNeutra = LIMITE_PIE_ABAJO + 5;
  for (int i = 0; i <= abs(finDerecha - posicionNeutra); i++) {
    servo_pieA.write(posicionNeutra);
    servo_pieB.write(posicionNeutra);
    servo_pieC.write(posicionNeutra);
    servo_pieD.write(posicionNeutra);
    delay(VELOCIDAD_MOVIMIENTO);
  }
  delay(500);
}

void detener() {
  parpadear();
  servo_brazoA.write(90);
  servo_pieA.write(60);
  servo_brazoB.write(90);
  servo_pieB.write(60);
  servo_brazoC.write(90);
  servo_pieC.write(60);
  servo_brazoD.write(90);
  servo_pieD.write(60);
  digitalWrite(PIN_LED, LOW);
}

void parpadear() {
  for (int i = 0; i = LIMITE_BRAZO_ATRAS; i--) {
    servo_brazoA.write(i);
    servo_brazoD.write(i);
    int y = LIMITE_BRAZO_ATRAS + LIMITE_BRAZO_ADELANTE - i;
    servo_brazoC.write(y);
    servo_brazoB.write(y);
    delay(VELOCIDAD_MOVIMIENTO);
  }
}

void moverIzquierda() {
  for (int i = LIMITE_BRAZO_ATRAS; i = LIMITE_BRAZO_ATRAS; i--) {
    servo_brazoA.write(i);
    servo_brazoD.write(i);
    int y = LIMITE_BRAZO_ATRAS + (LIMITE_BRAZO_ADELANTE - i);
    servo_brazoC.write(y);
    servo_brazoB.write(y);
    delay(VELOCIDAD_MOVIMIENTO);
  }
}

void bajar_plano() {
  int inicio = LIMITE_PIE_ARRIBA + 55;
  int fin = LIMITE_PIE_ABAJO + 5;
  servo_pieA.write(inicio);
  servo_pieB.write(inicio);
  servo_pieC.write(inicio);
  servo_pieD.write(inicio);
  delay(500);
  for (int i = inicio; i >= fin; i--) {
    servo_pieA.write(i);
    servo_pieB.write(i);
    servo_pieC.write(i);
    servo_pieD.write(i);
    delay(VELOCIDAD_MOVIMIENTO);
  }
  delay(500);
}

void mover_pie(Servo &servo, bool arriba) {
  int angulo = arriba ? LIMITE_PIE_ARRIBA : LIMITE_PIE_ABAJO;
  servo.write(angulo);
  delay(VELOCIDAD_MOVIMIENTO);
}

void mover_brazo(Servo &servo, bool adelante) {
  int angulo = adelante ? LIMITE_BRAZO_ADELANTE : LIMITE_BRAZO_ATRAS;
  servo.write(angulo);
  delay(VELOCIDAD_MOVIMIENTO);
}
        

5. Costes

El presupuesto del proyecto se detalla en la siguiente tabla, incluyendo todos los materiales y servicios utilizados:

Componente Cantidad Coste Unitario (€) Coste Total (€)
ESP32 1 11 11
Servomotor SG90 120º 8 4 32
Filamento PLA (200g) 1 20 20
PCB personalizada 5 1 5
Portapilas 2 5 10
Cables y tornillos (kit) 1 15 15
Total 93

6. Problemas y Soluciones

Durante el desarrollo, surgieron distintos problemas que nos obligaron a sacar soluciones creativas:

  1. Problema: Decisión del material empleado para el esqueleto de la araña.
    Solución: Gracias a la ayuda de un compañero de otra carrera se nos abrió la oportunidad de usar el PLA como material, de forma que este era resistente y altamente personalizable.
  2. Problema: Soldadura de los componentes a la PCB.
    Solución: Pese a la falta de experiencia, con paciencia y delicadeza conseguimos soldar exitosamente todos los componentes a la PCB.
  3. Problema: Conexión con la araña.
    Solución: Gracias a la web de MIT App Inventor pudimos desarrollar una app simple pero efectiva que nos permitía conectar y comandar la araña a distancia.
  4. Problema: Simular los movimientos de la araña.
    Solución: La simulación de los movimientos de la araña fue costosa, pero a prueba y error conseguimos unos movimientos que nos parecían aceptables.
  5. Problema: Alimentación de la araña.
    Solución: Debido a los picos de voltaje generados por los servomotores, la alimentación no era suficiente como para mantener el proyecto encendido, así que hemos decidido modificar los portapilas para alimentar el ESP32 y los servomotores por otro lado.

7. Casos de Uso

El robot araña tiene múltiples aplicaciones prácticas:

  1. Subir: La araña sube las patas.
  2. Bajar: La araña realiza una flexión.
  3. Caminar: La araña realiza la acción de caminar.
  4. Girar: La araña realiza un giro.
  5. Detener: La araña se detiene y se pone en posición inicial.
  6. Iluminar: Los LEDs que tiene la araña parpadean.
  7. Mando: La araña se puede mover en las cuatro direcciones siguiendo las órdenes de la cruz de movimiento.

8. App

Para controlar la araña hemos desarrollado una app en la web MIT App Inventor, esta es una web que permite crear una aplicación mediante bloques, cosa que nos ha facilitado mucho el desarrollo ya que no hemos tenido que programar dicha aplicación. En cuanto a la aplicación, esta es bastante simple, tiene un menú inicial que nos llevará a una pantalla en la que podemos ver todos los movimientos precargados disponibles. Además, en esta pantalla, seleccionando dispositivos disponibles podremos seleccionar el dispositivo Bluetooth disponible que deseemos para conectar la araña. Adicionalmente, podemos seleccionar controles de forma que tendremos un mando con el que podremos elegir la dirección en la que queremos que se mueva la araña como si de un mando radiocontrol se tratase.

App Pantalla 1 App Pantalla 2 App Pantalla 3

9. Vídeo Explicativo

10. Conclusiones

Este proyecto ha sido muy interesante de realizar, ya que nos ha permitido poner en práctica conocimientos de distintos ámbitos como son el Hardware, el Software y el desarrollo de aplicaciones, además de darnos experiencia a la hora de fusionar todos estos conceptos. También nos ha aportado una experiencia muy valiosa a la hora de resolver problemas en la vida real. Además, creemos que la aportación de esta idea tiene aplicaciones muy útiles para la vida real.

RoboAraña Final

También te podría gustar...

Deja una respuesta

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