Robotrack

Índice

  • Autores
  • Introducción
  • Materiales
  • Montaje
  • Código
  • Casos de uso
  • Problemas y soluciones
  • Conclusión

Autores

Grupo 17

Adrián Arlandis Alonso

Ignacio Martín Lorenzo

Introducción

Robotrack es un juguete controlado por Bluetooth que inicialmente iba a ser una especie de robot de vigilancia, contando con cámara y un modo automático con rutas definidas por el usuario, pero tanto los medios como el tiempo y la excesiva complejidad hicieron que tuviésemos que recortar nuestras expectativas e intentar adaptarnos a un proyecto más asequible.

A partir de este pensamiento decidimos fijarnos en algo más cotidiano como podría ser un coche de radio control y siguiendo esa línea de pensamiento llegamos a la conclusión de que podríamos hacer nosotros uno, pero añadiéndole un poco de «chicha». La idea final de este robot consiste en un vehículo controlado por una aplicación mediante conexión Bluetooth y que además cuenta con un sistema de detección y aviso de obstáculos en la trayectoria del robot mediante luces led y sonidos de alerta. Respecto al movimiento cuenta con un controlador para los dos motores de las ruedas delanteras y una rueda independiente para mantener la estabilidad.

Materiales

MaterialCantidadPrecioCoste
Cartón piedra21,5€3€
Motores + Ruedas42€/motor 1€/rueda12€
Multiplexor CD74HC406751,4€7€
Controlador L289N16€6€
Receptor BT HC-05111€11€
Soporte baterías12,5€2,5€
Cables1200,07€8,5€
Rueda independiente11,79€1,79€
Tornillos + Tuercas200,12€2,39€
Total54,18€

Ha habido materiales que por distintas razones han terminado siendo descartados y la lista que describe esta tabla es la lista de materiales final

Montaje

Con respecto al montaje hemos tenido varios diseños que incluían cosas como cámaras y pantallas LCD pero teniendo en cuenta los limitados pines que tiene la placa hemos tenido que adaptar la cantidad de componentes del sistema empotrado y en lo que a la estructura se refiere, inicialmente pensamos en hacer un modelo 3D e imprimirla en PLA, pero no dio tiempo a conseguir hacer un diseño imprimible que se adaptase al proyecto, asi que optamos por construir nosotros mismos la carcasa en plástico pero el plástico elegido era demasiado duro y se partía al intentar hacer agujeros o cortes, asi que finalmente elegimos cartón piedra por ser un material asequible para nuestros bolsillos y al alcance de nuestra mano.

Para el uso de los motores tuvimos que adaptar también el diseño de la carcasa para que las ruedas tuviesen el espacio necesario para poder hacer contacto con la superficie suficiente. Al no tener placas PCB de un tamaño más reducido, hemos tenido que hacer que el robot tenga un espacio interior suficiente y eso ha hecho que crezcan en gran medida las dimensiones del robot.

Para el apartado estético contamos con unos simples dibujos y en el hueco de las luces LED que indican la proximidad de los obstáculos hemos puesto un poco de papel de horno a modo de protección y también para que difumine la luz de forma que quede mejor a simple vista.

Código

#include <SoftwareSerial.h> 

int in1 = 2;
int in2 = 3;
int in3 = 4;
int in4 = 5;

int muxSig = 6;
int muxS3 = 7;
int muxS2 = 8;
int muxS1 = 9;
int muxS0 = 10;                   

int echoPin = 11;
int TrigPin = 12;

int buzzer = 13;

int flag1 = -1; // Estado de movimiento hacia adelante o reversa
int flag2 = -1; // Estado de giro o parada

SoftwareSerial bluetooth(A0, A1);//bluetooth
unsigned long lastDistanceCheck = 0; // Temporizador para distancia
const unsigned long distanceInterval = 100; // Intervalo de lectura en ms
int currentMuxChannel = 0; // Canal actual del multiplexor

void setup() {
  pinMode(echoPin, INPUT);
  pinMode(TrigPin, OUTPUT);
  pinMode(muxSig,OUTPUT);
  pinMode(muxS0,OUTPUT);
  pinMode(muxS1,OUTPUT);
  pinMode(muxS2,OUTPUT);
  pinMode(muxS3,OUTPUT);
  pinMode(buzzer, OUTPUT);
  playMelody();
  pinMode(in1, OUTPUT);
  pinMode(in2, OUTPUT);
  pinMode(in3, OUTPUT);
  pinMode(in4, OUTPUT);
  detenerMotores();
  bluetooth.begin(9600);
  activateMuxChannels(0,13);
  delay(3000);
  bluetoothConnection();
  activateMuxChannels(0,13);
  delay(3000);
}

bool activationTone = false;

void loop() {
  if (bluetooth.available()) {
    char toSend = (char)bluetooth.read();
    BluetoothCommand(toSend);
  }
  if (millis() - lastDistanceCheck >= distanceInterval) {//si el valor de millis - lastdistancecheck es mayor que el intervalo de 100ms, entonces se ejecuta la funcion distancedetection
    lastDistanceCheck = millis();
    DistanceDetection();
  }
}

void BluetoothCommand(char command) {//En funcion del comando recibido, hara el que coincida
  if (command == 'S') { //Parar
    flag1 = flag2 = 0;
    stopMotors();
  }
  else if (command == 'F' || command == 'G' || command == 'I') { //Hacia adelante
    if (flag1 != 1) {
      flag1 = 1;
      forward();
    }
  }
  else if (command == 'B' || command == 'H' || command == 'J') {//Marcha atras
    if (flag1 != 2) {
      flag1 = 2;
      backward();
    }
  }
  else if (command == 'L' || command == 'G' || command == 'H') {//Izquierda
    if (flag2 != 1) {
      flag2 = 1;
      left();
    }
  }
  else if (command == 'R' || command == 'I' || command == 'J') {//Derecha
    if (flag2 != 2) {
      flag2 = 2;
      right();
    }
  }
}

void DistanceDetection() {
  int distance = calculateDistance(TrigPin, echoPin);
  if (distance <= 4) {// Detener motores si está demasiado cerca (3-4 cm)
    stopMotors(); 
    if (!activationTone) {
      tone(buzzer, 2000);
      activationTone = true;
    }
    activateMuxChannels(0, 13); // Encender todos los leds en secuencia
  } else if (distance <= 35 && distance > 15) {//Solo los leds verdes
    noTone(buzzer);
    activationTone = false;
    activateMuxChannels(0, 4);
    tone(buzzer, 500, 200);
  } else if (distance <= 15 && distance > 7) {//Solo los leds verdes y amarillos
    noTone(buzzer);
    activationTone = false;
    activateMuxChannels(0, 8);
    tone(buzzer, 1000, 200);
  } else {//Todo sin hacer nada, ni buzzer ni leds.
    noTone(buzzer);
    activationTone = false;
    deactivateMuxChannels();
  }
}

void deactivateMuxChannels() {//Apagar los canales del mux
  digitalWrite(muxSig, LOW);
}

void activateMuxChannels(int start, int end) {//Encender de manera lineal los leds conectados al mux
  if (currentMuxChannel < start || currentMuxChannel >= end) {//Empieza desde el primero
    currentMuxChannel = start;
  }
  setMuxChannel(currentMuxChannel);
  digitalWrite(muxSig, HIGH);
  delay(20);
  currentMuxChannel++;
  if (currentMuxChannel >= end) {
    currentMuxChannel = start;//Lo reinicia al primero
  }
}

int calculateDistance(int TrigPin, int EchoPin) {//Leemos la distancia al sensor, mandando señales.
  long duration, distance;
  digitalWrite(TrigPin, LOW);
  delayMicroseconds(2);
  digitalWrite(TrigPin, HIGH);
  delayMicroseconds(10);
  digitalWrite(TrigPin, LOW);
  duration = pulseIn(EchoPin, HIGH);//Calculamos el tiempo entre señales.
  distance = ((duration * 10) / 292) / 2;
  return distance;
}

void setMuxChannel(byte channel) {//
  digitalWrite(muxS0, bitRead(channel, 0));
  digitalWrite(muxS1, bitRead(channel, 1));
  digitalWrite(muxS2, bitRead(channel, 2));
  digitalWrite(muxS3, bitRead(channel, 3));
}

void stopMotors() {//Parar motores
  digitalWrite(in1, LOW);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, LOW);
}

void forward() {//Hacia adelante
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
}

void backward() {//Marcha atras
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
}

void left() {//Izquierda
  digitalWrite(in1, HIGH);
  digitalWrite(in2, LOW);
  digitalWrite(in3, LOW);
  digitalWrite(in4, HIGH);
}

void right() {//Derecha
  digitalWrite(in1, LOW);
  digitalWrite(in2, HIGH);
  digitalWrite(in3, HIGH);
  digitalWrite(in4, LOW);
}

void playMelody() {//Cancion de robot encendido
  tone(buzzer, 262, 200);
  delay(250);
  tone(buzzer, 294, 200);
  delay(250);
  tone(buzzer, 330, 200);
  delay(250);
  tone(buzzer, 392, 200);
  delay(250);
  tone(buzzer, 523, 300);
  delay(350);
  noTone(buzzer);
}

void playMelody2() {//Cancion Bluetooth ON
  tone(buzzer, 523, 200);
  delay(200);
  tone(buzzer, 659, 200);
  delay(200);
  tone(buzzer, 784, 200);
  delay(200);
  tone(buzzer, 659, 200);
  delay(200);
  noTone(buzzer);
  delay(100);
}

void bluetoothConnection() { //Esperamos a que se conecte al bluetooth
  while (!bluetooth.available()) {
    delay(100);
  }
  playMelody2();
}

Cabe destacar, que lo más complicado a la hora de programar, fue el multiplexor, en lo relacionado con el encendido de los leds, ya que es secuencial y no se podía cambiar, también que tanto el bluetooth como el sensor de distancia, funcionasen de manera concurrente, ya que ambos sistemas debían de compartir el tiempo de uso del microcontrolador, haciendo así que los comandos por Bluetooth se procesaran de manera rápida, mientras que el sensor de distancia seguía monitoreando sus alrededores, con pequeños intervalos, evitando bloqueos o retrasos muy notables.

Casos de uso

Primero se enciende el sistema y, a modo de indicación de encendido, suena una melodía y se enciende un LED, a continuación, se espera a que el bluetooth este emparejado. Una vez emparejado el bluetooth suena una melodía distinta a la del encendido y se puede comenzar el uso.

A partir de ahora el robot responde a los movimientos que se manden usando los botones de la aplicación móvil. Durante el uso el sensor de distancia recoge información y dependiendo de la separación con respecto al obstáculo se encenderán, de manera secuencial, los LEDS de distintos colores indicando el nivel de peligro. Si se diese el caso de que la distancia fuese menor que 4cm aproximadamente, los motores están programados para bloquearse. Además de la señalización lumínica, RoboTRACK cuenta con un aviso sonoro que aumenta en frecuencia e intensidad según la distancia con el objeto.

Problemas y soluciones

Voltaje de la Batería

El principal problema que hemos tenido en el proyecto ha sido que fuente de energía usar. Originalmente pensamos en probar a usar la pila que incluía el kit que nos dieron en clase, pero no funcionaba y descubrimos que el voltaje era insuficiente, intentamos averiguar un voltaje aceptable para que los componentes funcionasen utilizando pilas 4,5V-5V aproximadamente en serie y llegamos a la conclusión de que necesitaríamos más o menos unos 10V-11V y la solución que encontramos fue probar con una batería Lipo de 11,1V prestada y tuvimos problemas a la hora de adaptar el conector a la placa, que hizo mal contacto y ocasionó problemas con esa batería, asi que decidimos usar algo más cotidiano y nos decantamos por un soporte de pilas AA que nos permite llegar al voltaje deseado sin tanta complicación.

Tiempos de entrega

Habiendo ya decidido los componentes que íbamos a utilizar para el robot, emprendimos la búsqueda de estos online y nuestras opciones quedaron bastamente reducidas por los tiempos excesivos de envío de las opciones de compra más baratas. También nos vimos afectados en este aspecto por la DANA porque uno de los componentes lo encontramos a un precio bastante reducido en una empresa valenciana, hicimos el pedido, pero tuvimos que cancelarlo al ver que las fechas pasaban y no había información de dicho envío.

Pines insuficientes

A la hora de decidir que componentes incluiríamos en este proyecto nos dimos cuenta de que los pines digitales de la placa eran muy pocos para los componentes que pensábamos utilizar y tuvimos que reducir la lista en base a esto, como por ejemplo con el uso de la pantalla LCD o cámaras entre otros.

Complicaciones con el multiplexor

Viendo el anterior problema, preguntamos al profesor y nos aconsejo el uso de un multiplexor. Cuando fuimos a buscar donde comprarlos nos dimos cuenta de que los pines del multiplexor vienen sin soldar y tuvimos que soldarlos nosotros. Una vez soldados tuvimos problemas con que el contacto que hacían los pines con la PCB eran insuficientes y eso generaba que algunas salidas no funcionasen. Además de todo esto no nos percatamos de que un multiplexor funciona de manera secuencial y no puede tener varias salidas activas de manera simultánea, asi que lo aprovechamos para la conexión de los LEDS que indican la proximidad.

Implementación de la aplicación móvil

Inicialmente planteamos la idea de programar nosotros mismos una aplicación con las funcionalidades que consideramos necesarias pero al empezar a investigar nos dimos cuenta de que gastaríamos más tiempo de lo que creíamos asi que optamos por buscar un modelo ya creado, que por suerte no fue muy difícil de encontrar, y adaptarlo al proyecto de RoboTRACK.

Conclusión

En conclusión, la experiencia de desarrollar este proyecto ha sido muy gratificante, especialmente al ver el proyecto finalizado y comprobar que todo funcionaba tal como lo habíamos planeado. A lo largo del proceso, hemos aprendido que, para este tipo de trabajos, es necesario tener una visión clara de lo que se desea lograr e invertir bastante tiempo en su desarrollo.

Además, al trabajar con Arduino, hemos mejorado en la resolución de problemas encontrados durante el desarrollo, ya sean de software, hardware o creatividad. También hemos adquirido conocimientos técnicos, como programar pantallas, multiplexores, sensores y otros componentes.

Finalmente, este proyecto no solo nos ha ayudado a aprender sobre Arduino, sino que también nos ha dejado con ganas de seguir creando proyectos en el futuro.

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 *