Diseño y simulación de un robot con dos motores DC (2ª Parte)

Introducción

En la entrada anterior correspondiente a la primera parte, vimos cómo se podía utilizar de forma sencilla una placa arduino y un circuito integrado L293D para controlar el sentido de giro de un motor DC.

En esta entrada vamos a codificar el programa de control de forma que nos resulte más sencillo programar un robot cuando utilicemos sensores. Para ello, partiremos de la simulación que hemos realizado en la primera parte, por lo que si no lo has hecho debes empezar por ahí.

Identificación de los pines que controlan cada motor

La situación de partida es que tenemos dos motores DC controlados por la placa Arduino, cuyo diseño ya debes tener:

2 motores DC controlados por una placa Arduino

Antes que nada, debes hacer una copia en Tinkercad del diseño que hayas hecho en la entrada anterior para seguir con los ejercicios indicados aquí.

A continuación, puedes probar con un programa con el fin de identificar correctamente a qué pines corresponde cada motor. En el diseño en tinkercad es fácil comprobarlo, pero con un robot construido en el que los cables no se ven con facilidad por dónde circulan, es difícil. Lo mejor, es probar con los programas, ver si giran gira el motor derecho o el izquierdo y en qué sentido.

Convenio de signos: Debemos definir en la cuando el robot avanza hacia adelante entendemos que los motores giran con revoluciones positivas y cuando lo hace hacia atrás, lo hacen con revoluciones negativas. Supondremos también que el avance hacia adelante del robot significa que el diseño de Tinkercad va hacia arriba y cuando el robot retrocede el diseño va hacia abajo. Con esta convención, llamaremos motor Izquierdo al que está a la izquierda del diseño y motor derecho al que está a la derecha.

Ejemplo: Probar con un programa y determinar los motores y sus giros.

Para ello, vamos a encender sólo un motor. En la entrada anterior, debes tener un programa similar a este:

void setup()
{
  pinMode(3, OUTPUT); 
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT); 
  pinMode(6, OUTPUT);
  
  digitalWrite(3, HIGH);    //Prueba para identificar el motor
  digitalWrite(4, LOW);
  
}



void loop()
{
  //digitalWrite(3, HIGH);
  //digitalWrite(4, LOW);
  //delay(1000); // Wait for 1000 millisecond(s)
  //digitalWrite(3, LOW);
  //digitalWrite(4, HIGH);
  //delay(1000); // Wait for 1000 millisecond(s)
}

Al hacer la simulación, comprobamos que el motor conectado a los pines 3 y 4 es el motor izquierdo con revoluciones positivas. Por tanto, los pines 3 y 4 corresponden al motor izquierdo y los pines 5 y 6 al motor derecho.

Giro del motor izquierdo hacia adelante.

En esta situación, ponemos en el código los siguientes comentarios:

void setup()
{
  pinMode(3, OUTPUT); // Motor izquierdo
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT); // Motor derecho
  pinMode(6, OUTPUT);
  
  digitalWrite(3, HIGH);  // Motor izquierdo girando adelante
  digitalWrite(4, LOW);
  
}

Sin necesidad de hacer más pruebas, deducimos qué instrucciones hay que poner para que el motor gire hacia atrás, simplemente cambiando LOW por HIGH y viceversa:

digitalWrite(3, LOW);  // Motor izquierdo girando atrás
digitalWrite(4, HIGN);

Hacemos el cambio y podemos comprobarlo:

Motor izquierdo girando hacia atrás. Hemos cambiado HIGH por LOW y viceversa

Podemos hacer una comprobación similar para el motor derecho y encontramos que la forma de que gire hacia atrás es (ojo, en tu caso podría ser al revés, dependiendo de cómo tengas conectados los cables):

digitalWrite(5, LOW);  // Motor derecho girando atrás
digitalWrite(6, HIGH);

Por tanto, ya sabemos cómo hacer para que el motor izquierdo y el derecho giren hacia adelante y hacia atrás.

Para comprobarlo, escribimos un programa que haga la siguiente secuencia una única vez en intervalos de 3 segundos para apreciarlo bien:

Motor Izquierdo adelante-Motor izquierdo atrás-Motor izquierdo paro-Motor derecho adelante-Motor derecho atrás-Motor derecho paro

El programa es parecido a este (los comentarios se ponen cuando se comprueba que la secuencia es correcta):

void setup()
{
  pinMode(3, OUTPUT); // Motor izquierdo
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT); // Motor derecho
  pinMode(6, OUTPUT);
  
  digitalWrite(3, HIGH);  // Motor izquierdo girando ADELANTE
  digitalWrite(4, LOW);
  delay(3000);
 
  digitalWrite(3, LOW);  // Motor izquierdo girando ATRÁS
  digitalWrite(4, HIGH);
  delay(3000);
  
  digitalWrite(3, LOW);  // Motor izquierdo PARO
  digitalWrite(4, LOW);
  delay(3000);
  
  digitalWrite(5, HIGH);  // Motor derecho girando ADELANTE
  digitalWrite(6, LOW);
  delay(3000);
    
  
  digitalWrite(5, LOW);  // Motor derecho girando ATRÁS
  digitalWrite(6, HIGH);
  delay(3000);
  
  digitalWrite(5, LOW);  // Motor derecho girando PARO
  digitalWrite(6, LOW);
  delay(3000);
}



void loop()
{
  //digitalWrite(3, HIGH);
  //digitalWrite(4, LOW);
  //delay(1000); // Wait for 1000 millisecond(s)
  //digitalWrite(3, LOW);
  //digitalWrite(4, HIGH);
  //delay(1000); // Wait for 1000 millisecond(s)
}

Observar que lo hemos puesto todo en la función setup() porque queremos que se ejecute una sóla vez la secuencia. El código que hemos puesto en la función loop() está comentado y es como si no hubiéramos puesto nada.

Ejercicio 1:

Crea el programa correspondiente a tu diseño de tal forma que ejecute una sola vez la secuencia indicada anteriormente con el convenio de signos que hemos adoptado:

Motor Izquierdo adelante-Motor izquierdo atrás-Motor izquierdo paro-Motor derecho adelante-Motor derecho atrás-Motor derecho paro

Codificando el robot con los movimientos básicos

Ya tenemos las bases para hacer un programa que haga algunos movimientos básicos:

  • Robot detenido
  • Robot hacia adelante
  • Robot hacia atrás
  • Robot curva hacia la derecha
  • Robot curva hacia la izquierda

Antes de proseguir, conviene hacer una tabla que concrete los movimientos:

Movimiento básico del robotMotor IzquierdoMotor derecho
Robot detenidoPAROPARO
Robot hacia adelanteADELANTEADELANTE
Robot hacia atrásATRÁSATRÁS
Robot curva hacia la derechaADELANTEPARO
Robot curva hacia la izquierdaPAROADELANTE

Ejemplo 1: robot detenido

En este caso, los dos motores están parados y el código es:

digitalWrite(3, LOW);  // Motor izquierdo PARO
digitalWrite(4, LOW);

digitalWrite(5, LOW);  // Motor derecho  PARO
digitalWrite(6, LOW);

Ejemplo 2: robot moviéndose hacia adelante

digitalWrite(3, HIGH);  // Motor izquierdo girando ADELANTE
digitalWrite(4, LOW);

digitalWrite(5, HIGH);  // Motor derecho girando ADELANTE
digitalWrite(6, LOW);


Ejemplo 3: robot moviéndose hacia atrás

Los dos motores giran hacia atrás

digitalWrite(3, LOW);  // Motor izquierdo girando ATRÁS
digitalWrite(4, HIGH);

digitalWrite(5, LOW);  // Motor derecho girando ATRÁS
digitalWrite(6, HIGH);

Ejemplo 4: robot girando hacia la derecha

El motor izquierdo avanza y el derecho está detenido.

digitalWrite(3, HIGH);  // Motor izquierdo girando ADELANTE
digitalWrite(4, LOW);

digitalWrite(5, LOW);  // Motor derecho  PARO
digitalWrite(6, LOW);


Ejemplo 5: robot girando hacia la izquierda

El motor derecho avanza mientras que el izquierdo se encuentra detenido.

digitalWrite(5, HIGH);  // Motor derecho girando ADELANTE
digitalWrite(6, LOW);

digitalWrite(3, LOW);  // Motor izquierdo PARO
digitalWrite(4, LOW);

Ejercicio 2: robot girando sobre sí mismo a derechas

Escribe el código y simula de forma similar a los ejemplos anteriores de forma que tu robot gire a sí mismo a derechas.

Ejercicio 3: robot girando sobre sí mismo a izquierdas

Escribe el código y simula de forma que el robot gire sobre sí mismo a izquierdas.

Ejercicio 4: robot en zig-zag

Escribe y simula el código de un robot que se desplaza en zig-zag hacia adelante.

Simplificando el código mediante funciones

Como ves, para que el robot efectúe un movimiento básico es necesario codificar cuatro instrucciones (dos por cada motor). Este hecho puede llegar a complicar la programación y las pruebas haciendo que los errores se multipliquen.

Lo que vamos a hacer ahora es agrupar en una función las cuatro instrucciones de cada movimiento básico. Veamos.

El siguiente sería un programa que hace que el robot avance de manera contínua (introducimos las instrucciones en el void loop():

void setup()
{
  pinMode(3, OUTPUT); // Motor izquierdo
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT); // Motor derecho
  pinMode(6, OUTPUT);
   
}

void loop()
{
  digitalWrite(3, HIGH);  // Motor izquierdo girando ADELANTE
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);  // Motor derecho girando ADELANTE
  digitalWrite(6, LOW);
  
}


  

Podemos simplificar este código asignando las cuatro instrucciones que corresponden a que el robot avance a una nueva función que podemos llamar void avance(), con lo que el programa quedaría, de forma simplificada, así:

Ejemplo 6: Uso de funciones

void setup()
{
  pinMode(3, OUTPUT); // Motor izquierdo
  pinMode(4, OUTPUT);
  pinMode(5, OUTPUT); // Motor derecho
  pinMode(6, OUTPUT);
   
}

void loop()
{
  avance();

}

//////////  Funciones definidas  ///////////
void avance()
{
  digitalWrite(3, HIGH);  // Motor izquierdo girando ADELANTE
  digitalWrite(4, LOW);
  digitalWrite(5, HIGH);  // Motor derecho girando ADELANTE
  digitalWrite(6, LOW);
}




Por tanto, siempre que queramos que el robot avance, es suficiente con escribir en void loop() la siguiente única instrucción:

avance();

en lugar de las cuatro instrucciones digitalWrite.

Ejercicio 5: Programa utilizando funciones

Como ejercicio, debes crear un programa, similar al ejemplo 6, en el que el robot realice la secuencia de movimientos básicos que hemos visto anteriormente, pero definiendo una función por cada movimiento básico:

  • Robot detenido
  • Robot hacia adelante
  • Robot hacia atrás
  • Robot curva hacia la derecha
  • Robot curva hacia la izquierda

Para ello, debes definir cinco funciones y programar en el void loop() la siguiente secuencia con intervalos, por ejemplo, de 3 segundos:

Detenido-3 segundos-adelante-3 segundos-atrás-3 segundos-curva derecha-3 segundos-curva-izquierda-3 segundos-Detenido-… y así sucesivamente.

A partir de aquí, ya tenemos probado los movimientos básicos del robot y hemos sentado las bases para realizar programas más complejos con sensores, etc. Esto lo veremos en la próxima entrada.