Hiparco

Recetas y trucos de GNU/Linux e informática en general

Alojado en http://guimi.net

Un robot con Arduino

1st Robot – Cómo se hizo

Hay un monton de información de robots económicos realizados con Arduino.
Este es el mio.

Con unos 320 gramos, este robot quedó tercero en la prueba de velocidad (sigue-lineas) del Olympic Robotic Challenge 2.14.
También hizo el tercer mejor tiempo en el laberinto (4.1 segundos), aunque al segundo intento, por lo que quedó quinto (penalización de 5 segundos, total 9.1 segundos).
Puedes ver el vídeo de la evolución del robot al final del artículo.

 

A quién va dirigido este escrito

Si lo que quieres es simplemente construir un robot económico, te recomiendo que compres alguno de los múltiples packs que se venden en tiendas y en internet. Están bien de precio y funcionan bien.

Por otra parte, si ya has construido tus propios robots antes, este artículo no te aportará mucho.

Pero si quieres aprender a construir tu propio robot, si quieres saber el tipo de problemas a los que te vas a enfrentar y cómo es el proceso, entonces este artículo es para ti.

La idea no es que construyas exactamente este robot. La idea es que construyas TU robot, con tus propias soluciones. Este artículo es una introducción a cómo hacer un robot, presentando los problemas que me encontré, no unas instrucciones para hacer un robot (aunque podría usarse como tal).

Si necesitas una introducción a Arduino puedes consultar las entradas sobre Arduino en Hiparco.

 

Primeras consideraciones sobre el robot

Comportamiento

Lo primero a considerar, aunque parezca evidente, es ¿qué queremos hacer?
Parece obvio: “un robot”.
Pero eso no es suficiente. ¿Qué tipo de robot? ¿Qué esperas que haga? ¿De que componentes dispones o estás dispuesto a comprar?
Por ejemplo hay robots sigue-líneas, luchadores, buscadores, vagabundos… terrestre, volador, acuático… móvil, quieto… y también puede ser teledirigido (controlado remotamente) o autónomo (actúa por su cuenta).

En mi caso nos vamos a centrar en un robot terrestre, con ruedas, autónomo de tipo sigue-lineas.
Esto es, un robot que actuando por su cuenta en base a sensores, sigue una línea negra sin dejarla.
Los sensores disponen de un emisor de luz y un receptor. Si la luz rebota en una superficie cercana y blanca el receptor la capta. En teoría, en otro caso el sensor no capta nada. Así podemos distinguir una línea negra sobre fondo blanco. En la práctica los reflejos y la alta iluminación en la competición nos causaron muchos problemas a un gran número de participantes.

Otras consideraciones que pesaron a la hora de realizar el robot fue que intenté utilizar material reciclado o muy barato y que era un proyecto efímero que iba a deshacer al acabar la participanción en el ORC. De hecho cada día montaba y desmontaba el robot.
Por tanto el robot es facilmente mejorable con mejores ruedas, optimizando el tamaño y forma del chasis, utilizando engranajes para la transmisión…


Si todavía no te queda claro puedes ver un vídeo de la evolución del robot al final del artículo.

 

Motores

Lo que más me costó fue decidir el tipo de motores a utilizar.
Básicamente hay tres tipos:

  1. Motores de corriente continua (Motores DC) que según la diferencia de voltaje aplicada se mueven más deprisa o más lentos (dos cables).
  2. Motores Servos de rotación continua que permiten indicar al motor la velocidad deseada mediante una señal (tres cables).
  3. Motores de pasos (Stepper) que permiten un control muy fino del movimiento, con un control más complicado (al menos cuatro cables).

De arriba abajo, cada tipo de motor permite un control más fino de la velocidad del mismo.

Y aquí nos topamos con una máxima: cuánto más velocidad menos control, cuánto más control menos velocidad (a precios/calidades similares).

Esto quiere decir que para motores similares, los DC son los más rápidos y los stepper los de mayor control.
Obviamente un motor stepper de gran calidad (y precio) puede ser mucho más rápido que un motor barato DC.

Nota 1: Algunos participantes no consiguieron acabar la prueba porque el robot no reaccionaba suficientemente rápido y perdía la pista. En la competición mi robot era el más lento, pero no perdía la pista. Así que de forma lenta y segura quedó tercero :-)

Nota 2: Los motores servo de rotación continua deben calibrarse. Para ello se envía a los motores la señal de “parados” (90) y mediante un regulador incorporado, utilizando un destornillador, se ajustan los motores para que queden efectivamente quietos.

 

Tracción y dirección

Existen dos formas básicas de gobernar el movimiento de un robot, una carretilla, un coche…

Una opción es usar un motor para generar el empuje de motor y otro motor para controlar la dirección.
Este es el sistema habitual de los coches, las motos, los camiones…

Si nos fijamos en un coche teledirigido (o RC: radio-control), normalmente tienen la tracción (el empuje, la fuerza motriz) en el eje trasero (ruedas motrices), y gobiernan la dirección con las ruedas del eje delantero (ruedas directrices).
En cambio las carretillas, en cuanto son un poco grandes, suelen tener las ruedas directrices detrás, algo que confunde a mucha gente.

Algunos coches “de verdad” también tienen tracción trasera, pero lo habitual es que las ruedas motrices y directrices sean las del eje delantero. Aún así, lo importante es que se utiliza un único motor para imprimir la misma velocidad a ambas ruedas motrices (el motor del vehículo) y otro motor para controlar la dirección (el propio conductor, usando el volante o manillar, habitualmente de forma asistida).

En definitiva este sistema utiliza dos motores -uno para empuje y otro para dirección-, tienen habitualmente un par de ejes y son “alargados”.
La cuestión es que el vehículo no puede girar sobre si mismo y maniobrar es algo complicado (piensa en las maniobras típicas de aparcamiento de un coche).

La otra forma de gobernar el vehículo es mediante lo que se denomina empuje diferencial (differential drive).
Este sistema utiliza dos ruedas con motores independientes. De nuevo tenemos dos motores pero con funciones diferentes, pero en este caso cada motor proporciona fuerza motriz independiente a una rueda (o conjunto de ruedas) en un lado del vehículo.
Para que el vehículo vaya recto se aplica la misma velocidad en ambos lados. Para que el vehículo gire, cada rueda establece una velocidad diferente. Incluso puede girar una rueda en una dirección y la otra al revés, realizando un giro sobre si mismo sin desplazamiento.
Este comportamiento es similar a una canoa o barca en la que remas a ambos lados de la misma. Según la diferencia de fuerza aplicada en cada lado, la nave avanzará recto, girará más o menos, o irá hacia atrás.

Este tipo de control es más sencillo y proporciona la mejor maniobrabilidad, especialmente con solo dos ruedas. En este caso, que es el habitual, el eje debe estar bastante centrado, lo que a su vez obliga a diseños de planta “cuadrada”.

Como se trataba de mi primer robot y pretendía hacerlo sencillo, al final opté por el empuje diferencial con dos ruedas.

 

Primeras pruebas

Primera prueba de concepto: Motores DC

Para mi primera prueba de concepto utilicé dos motores DC y comprobe que para el empuje diferencial no son la mejor opción.
Los motores DC giran a la máxima velocidad que les permite la diferencia de tensión. Cuando reduces la tensión para reducir la velocidad, la inercia de los motores hace que por un momento giren más rápido de lo indicado por el voltaje. Cómo decía: más velocidad = menos control.
Los motores de DC pueden ser una buena opción para el modelo tracción/dirección.

Por cierto, uno de los motores DC de la primera prueba, procedía de una muñeca que llevaba 25 años sin funcionar (una muñeca patinadora), pero el motor pude reutilizarlo.

 

Seguna prueba de concepto: Motores servo

En esta imagen muestro además el tercer punto de apoyo. Lo ideal es poner un rodamiento (sirve una bola de desodorante roll-on). En mi caso los motores Servo no eran muy rápidos pero sí suficientemente potentes. Así que use un tornillo como tercer apoyo. El rozamiento era mínimo y me permitía regular la altura de la plataforma para los sensores de líneas.

En mi caso el tamaño del robot lo marcó el tamaño de la tabla de madera en que tenía atornillado el Arduino, porque no me apetecía desmontarlo de ahí.
Además, como se aprecia en la imagen superior, la disposición elegida me permitía dejar la pila de 9V entre los motores.

Por otra parte el diseño de la electrónica ya estaba bastante terminado (ver al final del artículo).
Le incorporé luces y un altavoz por dos motivos: porque soy un hortera y porque las luces y los sonidos me permitían saber en qué parte del programa se encontraba el robot, haciendo “debug” del programa.
El potenciómetro me permitía establecer una velocidad de motor más alta o más baja sin tener que modificar el programa.
El programa que utilicé en la prueba está al final, pero se basa en mi programa básico que muestro aquí:
Arduino: Sensores de linea

 

Notas sobre Chasis y Ruedas

Hasta la elección de ruedas puede ser dificil.
Primero usé un chasis de cartón y unas ruedas de plástico duro de un juguete (se ven en “Motores DC”). Estas ruedas no tenían ninguna tracción. Es decir, “resbalaban” en el suelo y giraban sin mover apenas el robot.

Después realicé un chasis y usé unas ruedas de goma de una caja de Meccano que tenía ¡hace más de 20 años! (ver fotos del punto anterior).

Pero no conseguía fijar adecuadamente las ruedas a los motores así que en la siguiente versión utilicé de ruedas uno de los propios enganches de los motores.

Además se aprecia que cambié la parte delantera del chasis para poder incorporar más facilmente los sensores.

En todo caso el problema seguía siendo la baja velocidad de giro de las ruedas. Además como las “ruedas” no eran tales tampoco tenían tracción.
A grandes males, grandes remedios.
La solución más sencilla fue aumentar el tamaño de rueda. Para ello hice ruedas de cartulina, dibujandolas con un CD y recortándolas. Además dejé intencionadamente un corte “sucio” de los bordes de la cartulina para mejorar la tracción.
Al tener el eje más alto, tuve que modificar ligeramente el chasis.

 

El diseño final

Este fue el primer prototipo del robot final.

Para las primeras pruebas puse los sensores arriba del robot. Son las luces moradas, que curiosamente a simple vista no se ven, pero la cámara sí que las capta.

Para la versión final de las ruedas utilicé cartón procedente de una caja de leche (una caja de las que contienen seis tetrabricks de un litro), utilizando dos capas pegadas de cartón para cada rueda, y le pedí a mis hijos que las decoraran. Este fue el resultado:

 

Solventando problemas

Como se puede apreciar en el video, me encontré principalmente con dos problemas: sensores erráticos y problemas de tensión.

 

Problemas con los sensores

Al realizar pruebas, los sensores a veces funcionaban y a veces no.
El problema era que la altura de los sensores y, sobretodo, las condiciones de iluminación afectaban mucho a los sensores. Así que tras varios intentos solventé el problema encapsulando los sensores y dejandolos a ras de suelo.
Eliminé el tercer punto de apoyo (el tornillo) y con cartulina y cinta aislante negra encapsule por separado los sensores. Aunque en la foto no se aprecia bien, entre ambos sensores hay una cartulina separándolos para evitar interferencias.
El propio encapsulamiento de cartulina hace de tercer apoyo, dejando los sensores a un milímetro del suelo y totalmente a oscuras.

 

Problemas con la tensión

Los motores que utilicé eran motores Servo que permiten una tensión de entrada de entre 4V y 6V.
La pila que usaba era de 9V, por lo que no podía alimentarlos directamente.

Así que todos los elementos, incluidos los motores, estaban alimentados desde la placa Arduino a 5V. Teniendo en cuenta además que las pilas de 9V tienen una capacidad de unos 400 mAh, esto hacía que la pila se fundiese a gran velocidad, y que cuando la pila no rendía al 100% los picos de tensión producidos por los motores reseteasen la placa.

Intenté reducir el problema añadiendo capacitadores, pero no era suficiente.

Solución buena: alimentar los motores por separado, no desde la placa Arduino.
Para ello una opción es utilizar un grupo de 5 baterías AA que sumasen 6V (1,2Vx5), modificando el chasis para hacer sitio.
Otra opción es utilizar una batería con otro voltaje y utilizar un regulador de tensión.

Para seleccionar una buena batería (o conjunto) debemos tener en cuenta el voltaje y la corriente que necesitamos. Así una batería de 9V de menos de 500 mAh no es una buena opción para alimentar dos motores servos como los que lleva 1st Robot.
Ver información sobre baterías.

Solución adoptada: Dado que partíamos de un fallo de diseño (usar una batería de 9V y menos de 500 mAh), la única opción el día de la competición era cambiar la pila para cada prueba y modificar el programa para que acelerara y frenara poco a poco. Además los cambios al programa los hice el día mismo de la competición, por lo que no tuve mucho tiempo de optimizar y limpiar el código. Así que el programa final es algo farragoso.
Si quieres usar mi código, recomiendo partir del programa base (Arduino: Sensores de linea) y no del programa final que utilicé.

 

1st Robot – Resultado

En plena participación:

1st Robot desde diferentes ángulos:




 

Vídeo de la evolución de 1st Robot

Vídeo de 4 minutos. Ver 1st Robot en Youtube.

 

Nth Robot – El futuro

Para próximas versiones del robot, como ya he dicho probablemente utilice alimentación independiente para los motores, ya sea mediante un regulador de tensión o utilizando un conjunto que sume 6V.

También es probable que utilice más sensores de línea y así tener más flexibilidad a la hora de localizar la línea y reaccionar.

Quizá utilice ruedas más grandes o engranajes para obtener más velocidad, ya que los motores tienen fuerza de sobra para mover el robot con su peso actual e incluso para transportar pequeñas cargas.

Definitivamente necesito una forma mejor de conectar las ruedas a los motores que un poco de cinta islante.

Además estoy preparando una versión del robot por control remoto utilizando un módulo Bluetooth hc-05 y un móvil con Android.

 

Anexos

Anexo I: Componentes

  • 2 IR Infrared Line Track Tracker Follower Sensor 5V Shield
  • 1 Arduino UNO board rev.3
  • 1 Breadboard
  • 20-30 jumper wires
  • 1 Potentiometer 10kilohm
  • 3 LEDs (2 yellow, 1 green)
  • Un poco de Cinta aislante
  • 1 Piezo capsule [PKM17EPP-4001-B0]
  • 2 Capacitors 100uF
  • 3 Resistors 220 ohm
  • 1 Madera de montaje
  • 2 Servo digital de rotación contínua 360º
  • 1 Pila de 9V + conector
  • 2 Ruedas de cartón (decoradas por Pau y Lúa)
  • 1 Chasis realizado con viejas piezas de Meccano
  • 2 Gomas de pelo (aportadas por Lúa)
  • 1 encapsulamiento para sensores realizado con cartulina y cinta aislante

Coste aproximado: Entre 60 y 70 €

Así es como se conecta todo esto:

 

Anexo II: El programa

El código final, como ya he comentado, lo realicé el mismo día de las pruebas por lo que no quedó muy limpio.
Utiliza mi libreria TocaMelodia, para tocar melodias, pero puede eliminarse fácilmente comentado las lineas correspondientes.

Además tiene dos modos de funcionamiento. Para alternar entre ellos hay que modificar por código el valor de la variable modo y cargar el programa.
El modo 0 es el programa sigue-lineas utilizado en la prueba. Ambos sensores se encuentran delante y juntos, sobre la línea negra.
El modo 2 permite probar y calibrar los motores. En este modo el robot varía la velocidad de los motores en base a la lectura del potenciómetro, indicando además con luces el sentido de giro. Esto permite calibrar los motores cuando el potenciómetro envía la señal de parado (90), lo que se aprecia porque los dos LEDs de giro quedan encendidos (ver nota 2 en la sección de motores).

El código fuente final:

/*
 * 1st Robot by Guimi
 *
 * Este programa implemente un robot que permite varios modos de funcionamiento:
 * [0 sigue-lineas; 2 prueba de motores]
 *
 * Dispone de dos ruedas con un motor servo cada uno (differential drive)
 * 
 * Dispone de dos sensores de linea que indican cuando se detecta la linea.
 *
 * Tambien dispone de dos LEDs (derecho e izquierdo) para indicar adelante (ambos apagados), giro a un lado o parado (ambos encendidos).
 *
 * Por ultimo utiliza un altavoz o piezoelectrico para emitir melodias predeterminadas.
 *
 * 2014 - Guimi (http://guimi.net)
 *
 */


// LIBRERIAS
//----------
#include <TocaMelodia.h> // Libreria para tocar melodias pre-determninadas (disponible en http://guimi.net/blogs/hiparco/arduino-libreria-tocamelodia-para-tocar-melodias-predeterminadas/)
#include <Servo.h> // Incluimos la libreria de gestin de los motores servo


// CONSTANTES
//----------
const byte sensorDer=2; // Pin del sensor Derecho
const byte sensorIzq=3; // Pin del sensor Izquierdo

const byte pinMotorDer=6; // Pin [PWM] de la señal de velocidad del motor Derecho
const byte pinMotorIzq=9; // Pin [PWM] de la señal de velocidad del motor Izquierdo

const byte pinGiroDer=10; // Pin del LED derecho
const byte pinGiroIzq=11; // Pin del LED izquierdo
const byte pinAltavoz=12; // Pin del altavoz
const byte pinEstado=13; // Pin del LED que marca el estado

const byte pinPotenciometro=A0; // Pin del potenciometro (que establece en el setup la variacin de velocidad)


// VARIABLES
//----------
byte valorIzq=0; // Variable para guardar el valor del sensor Izquierdo [0 Negro; 1 Blanco]
byte valorDer=0; // Variable para guardar el valor del sensor Derecho [0 Negro; 1 Blanco]

byte modo=0; // Variable para guardar el modo del programa [0 sigue-lineas; 1 camino complejo; 2 prueba de motores]
byte direccion=2; // Variable para guardar la ultima direccion valida [0 recto, 1 izquierda; 2 derecha]

int valorPotenciometro = 0; // Variable para guardar el valor del potenciometro [0-1023]
int variacionVelocidad = 90; // [0 - 90] Variable que indica la variacion de velocidad de giro a imprimir en los motores. Cuanto mas alto el valor, mayor la velocidad.

unsigned long tiempoDesde = 0; // Variables para medir tiempos
unsigned long tiempoHasta = 0; // Variables para medir tiempos
long tiempoLinea = 3000; // Indica el tiempo que se tarda en recorrer una linea corta (para la larga tarda 3500 aprox)

Servo motorIzq; // Gestor del motor izquierdo
Servo motorDer; // Gestor del motor derecho

TocaMelodia tocaMelodia(pinAltavoz); // Inicializamos el altavoz, indicando el pin


// FUNCION SETUP
//--------------
void setup(){
  // Definimos cada pin como entrada o salida
  pinMode(sensorDer,INPUT);
  pinMode(sensorIzq,INPUT);

  pinMode(pinGiroDer,OUTPUT);
  pinMode(pinGiroIzq,OUTPUT);
  pinMode(pinAltavoz,OUTPUT);
  pinMode(pinEstado,OUTPUT);

  // Conectamos los motores a sus pines
  motorIzq.attach(pinMotorIzq);
  motorDer.attach(pinMotorDer);
  // Paramos los motores
  velocidadMotores(90, 90);

  // Apagamos la luz de estado mientras esperamos un tiempo inicial para ajustarnos a la normativa del concurso
  digitalWrite(pinEstado, LOW);
  for (int i = 0; i<4; i++) {
    // Indicamos el estado mediante una intermitencia del pin de estado
    digitalWrite(pinEstado, LOW);
    digitalWrite(sensorDer, LOW);
    digitalWrite(sensorIzq, LOW);
    delay(250);
    digitalWrite(pinEstado, HIGH);
    digitalWrite(sensorDer, HIGH);
    digitalWrite(sensorIzq, HIGH);
    delay(250);
  }
  // Iniciamos con un poco de fanfarria ;-P  Esto permite detectar facilmente cuando el sistema se resetea.
  tocaMelodia.melodia(MELODIA_PODER_PERRUNO);

  // Indicamos el inicio
  digitalWrite(pinEstado, HIGH);

  // Leemos el valor del potenciometro [0-1023]
  valorPotenciometro=analogRead(pinPotenciometro);
  // Establecemos una variacion de velocidad a utilizar
  // Esto nos permite ajustar la velocidad efectiva segun sea necesario por el angulo de las curvas del circuito
  variacionVelocidad=map(valorPotenciometro,0,1023,0,89);

  // Leemos el valor de los sensores [0-1]
  valorIzq=digitalRead(sensorIzq);
  valorDer=digitalRead(sensorDer);

  // Preparamos la comunicacion mediante el puerto serie
  //Serial.begin(9600);
}


// FUNCION LOOP
//-------------
void loop(){
  //*****************************************************************************************************************
  //-----------------------------------------------------------------------------------------------------------------
  // S I G U E   L I N E A S   (modo == 0)
  //-----------------------------------------------------------------------------------------------------------------
  //*****************************************************************************************************************
  // Mientras el modo sea "sigue-lineas"
  while (modo == 0) {
    // Mientras detectamos linea con algun sensor, la seguimos
    while (!valorIzq || !valorDer) {
      // Establecemos direccion en base a las lecturas
      if (!valorIzq && !valorDer) { // Recto
        direccion=0;
        indicaDireccion(direccion);
  
        // Si hace poco que nos hemos reincorpordao a la linea, avanzamos despacio
        // por dos motivos: como en las curvas este proceso (dentro-fuera de linea) se repite muchas veces
        // lo normal es que si venimos de fuera nos volvamos a salir y ademas muchos cambios bruscos seguidos resetean la placa (problemas de tension)
        tiempoHasta = millis();
        if (tiempoHasta - tiempoDesde < 1000) {
          velocidadMotores(90 - (variacionVelocidad/4), 90 + (variacionVelocidad/4));
        } else { // Si llevamos un tiempo en la linea vamos a toda velocidad
          velocidadMotores(90 - variacionVelocidad, 90 + variacionVelocidad);
        }
        
      } else if (!valorDer) { // Derecha
        direccion=2;
        indicaDireccion(direccion);
        velocidadMotores(90 - variacionVelocidad, 90 + (variacionVelocidad/4));
      } else { // Izquierda
        direccion=1;
        indicaDireccion(direccion);
        velocidadMotores(90 - (variacionVelocidad/4), 90 + variacionVelocidad);
      }
      // Esperamos un tiempo de reaccion para los componentes
      delay(50);
  
      // Leemos el valor de los sensores [0-1]
      valorIzq=digitalRead(sensorIzq);
      valorDer=digitalRead(sensorDer);
    }
  
    // Reducimos velocidad antes de parar, para evitar que la placa se resetee por problemas de potencia
    velocidadMotores(90 - (variacionVelocidad/8), 90 + (variacionVelocidad/8)); delay(50);
    // Paramos
    Parar(); delay(80);
  
    // Si no detectamos linea la buscamos en la ultima direccion conocida (o al inicio en la predeterminada)
    while (valorIzq && valorDer) {
      indicaDireccion(direccion);
      if (direccion == 1) { // Rotacion a Izquierda
        velocidadMotores(90 + (8), 90 + (8));
      } else if (direccion == 2) { // Rotacion a Derecha
        velocidadMotores(90 - (8), 90 - (8));
      } else  if (direccion == 0) { // Recto
      //   // Hemos localizado el final de linea
      //   // Dejamos el robot quieto hasta que los sensores vuelvan a detectar linea
      //  tocaMelodia.melodia(MELODIA_FANFARRIA);
      //  direccion = 3; // Solo suena la melodia la primera vez
        // En este circuito no hay final de linea, buscamos una linea
        direccion = 1; // Indicamos que busque hacia la izquierda
      }
      // Esperamos un tiempo de reaccion para los componentes
      delay(30);
  
      tiempoDesde = millis(); // Tomamos el tiempo en el que retomamos la pista
  
      // Leemos el valor de los sensores [0-1]
      valorIzq=digitalRead(sensorIzq);
      valorDer=digitalRead(sensorDer);
    }
  
    delay(30); // Mantenemos el giro un poco para que se centren los sensores en la linea
    Parar(); delay(80); // Paramos para dar tiempo a la tesion a estabilizarse

  } // while (modo == 0)



  //*****************************************************************************************************************
  //-----------------------------------------------------------------------------------------------------------------
  // P R U E B A   D E   M O T O R E S   (modo == 2)
  //-----------------------------------------------------------------------------------------------------------------
  //*****************************************************************************************************************
  // Mientras el modo sea "prueba de motores"
  while (modo == 2) {
    // Leemos el valor del potenciometro [0-1023]
    valorPotenciometro=analogRead(pinPotenciometro);
    valorPotenciometro=map(valorPotenciometro,0,1023,0,179);
    //Serial.println(variacionVelocidad);
    // Usamos los LEDs de giro para indicar la lectura del potenciometro
    if (valorPotenciometro == 90) {
      digitalWrite(pinGiroIzq, HIGH);
      digitalWrite(pinGiroDer, HIGH);
    } else if (valorPotenciometro > 90) {
      digitalWrite(pinGiroIzq, LOW);
      digitalWrite(pinGiroDer, HIGH);
    } else {
      digitalWrite(pinGiroIzq, HIGH);
      digitalWrite(pinGiroDer, LOW);
    }
    // Variamos la velocidad de los motores en base a la lectura del potenciometro
    velocidadMotores(valorPotenciometro, valorPotenciometro);
    delay(100);
  } // while (modo == 2) 

} // LOOP


// MOVIMIENTOS
//-------------
// Ambos motores son iguales, pero se montan simetricamente (uno a cada lado)
// Asi por ejemplo, para ir adelante cada motor debe girar en una direccion
// En este caso el motor izquierdo avanza con [90-180] y el derecho con [0-90]
// en ambos casos cuanto mas alejado de 90 sea el valor, mas deprisa
//----------------------------------------------------------------------------
void indicaDireccion(int direccion) {
  switch (direccion) {
  case 0:
    //Serial.println("Adelante");
    // Apagamos las luces de giro
    digitalWrite(pinGiroIzq, LOW);
    digitalWrite(pinGiroDer, LOW);
    break;
  case 1:
    //Serial.println("Izquierda");
    // Encendemos la luz de giro
    digitalWrite(pinGiroIzq, HIGH);
    digitalWrite(pinGiroDer, LOW); 
    break;
  case 2:
    //Serial.println("Derecha");
    // Encendemos la luz de giro
    digitalWrite(pinGiroIzq, LOW);
    digitalWrite(pinGiroDer, HIGH); 
    break;
  } 
}

void Parar(){
  //Serial.println("Parar");
  // Encendemos las luces de giro
  digitalWrite(pinGiroIzq, HIGH);
  digitalWrite(pinGiroDer, HIGH);

  // Indicamos la velocidad
  //velocidadMotores(90, 90);
  // Si paramos los dos motores a la vez el pico de corriente hace que se resetee la placa
  // Asi que paramos uno un poco antes que el otro.
  motorIzq.write(90);
  delay(100);
  motorDer.write(90);
  delay(20);
}

// Establece la velocidad solicitada en los motores
void velocidadMotores(int izquierda, int derecha) {
  //Serial.print("Velocidad Motores:");
  //Serial.println(variacionVelocidad);
  motorIzq.write(izquierda);
  delay(20);
  motorDer.write(derecha);
  delay(20);
}