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:

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.

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:

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 robot | Motor Izquierdo | Motor derecho |
Robot detenido | PARO | PARO |
Robot hacia adelante | ADELANTE | ADELANTE |
Robot hacia atrás | ATRÁS | ATRÁS |
Robot curva hacia la derecha | ADELANTE | PARO |
Robot curva hacia la izquierda | PARO | ADELANTE |
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.