En ocasiones, necesitamos controlar motores con Arduino. Proyectos que, de alguna manera, incorporan servomotores, motores DC o motores paso a paso (Stepper motors). La manera más eficaz y óptima de hacerlo es a través de un driver. En este tutorial, de voy a enseñar cómo controlarlos con el Adafruit Motor Shield v2.3.
Veremos el montaje, conexionado y las diferentes formas de programar Arduino para obtener la máxima potencia. Daré un repaso por los conceptos más importantes. Si quieres saber más, te recomiendo que leas la hoja de especificaciones que suministra el fabricante. Precisamente en estas instrucciones me baso para escribir este artículo.
El material que voy a utilizar es el siguiente:
- Un motor DC
- Un motor paso a paso
- Un servomotor
- Arduino UNO
- Motor Shield v2.3 de Adafruit
- Conectores hembra para Arduino UNO
Indice de contenidos
Especificaciones del Adafruit Motor Shield
Antes de comenzar a ver nada vamos a ver un pequeño resumen de lo que nos puede aportar este shield.
- Comunicación I2C con la placa de Arduino. Solo ocuparía dos pines con la posibilidad de conectar más componentes con comunicación I2C.
- Posibilidad de conectar hasta 32 shields en serie.
- 2 conexiones para servos de 5V.
- Puede mover motores desde 4,5V a 13,5V.
- Se pueden conectar 4 motores DC con movimiento adelante y atrás y control de velocidad de 8-bit, más o menos el 0,5% de giro de resolución.
- Hasta 2 motores paso a paso (unipolar o bipolar).
- Posibilidad de separar las fuentes de alimentación de la lógica (Arduino) y los motores (Motor Shield). Muy importante para eliminar el ruido.
- Compatible con Arduino UNO, Leonardo, Mega, Diecimila y Duemilanove.
- Existe una librería muy fácil de usar para Arduino.
- Es compatible con los niveles lógicos de 5V y 3,3V.
Primera toma de contacto
Cuando recibes el paquete y lo abres, lo primero que te encuentras es esto.
Sorprende que venga sin soldar los conectores, pero yo le encuentro una explicación. En este tipo de placas podemos utilizar conectores macho o hembra. ¿Cuál es la diferencia? pues, sobre todo, que los hembra nos van a permitir utilizar el resto de pines de la placa a la que conectemos el shield. En cambio los conectores macho no permiten esto.
Los conectores serían como estos.
En Amazon puedes encontrarlos fácilmente, pero asegúrate que son los recomendados para tu placa. Los de la imagen anterior son para Arduino UNO.
El jumper nos va a permitir configurar la fuente de alimentación de la placa para que funcione con la alimentación de Arduino a través de Vin o con una alimentación separada para el shield y los motores. Todo esto lo veremos más adelante.
Antes de empezar hay que soldar
Pues lo dicho, antes de comenzar a probar el Adafruit Motor Shield, hay que soldar. Si has escuchado alguno de mis capítulos del podcast La Tecnología Para Todos, ya sabrás que yo no soy muy diestro en el tema de soldar. Esto es debido a mi falta de experiencia, pero poco a poco voy adquiriendo más destreza. El truco, practicar, no queda otra así que como una imagen vale más que mil palabras, mira el siguiente vídeo donde te explico cómo debes hacerlo.
Parece sencillo ¿verdad? al final el objetivo está cumplido. Ya podemos conectar el shield encima de nuestro Arduino. La comunicación entre ellos se realiza a través del protocolo I2C. Esto nos da cierta ventaja, solo necesitamos dos pines para controlar 4 motores DC y dos servos por ejemplo.
Instalando el Software necesario para controlar motores con Arduino
Como en casi todos los dispositivos tecnológicos, hay que programar. El Adafruit Motor Shield no va a ser menos y si queremos sacar todo el jugo de esta placa, no nos queda otra que remangarse y picar código. Pero no te preocupes, yo te voy a explicar todo lo necesario para controlar motores con Arduino, motres DC, motores paso a paso y servomotores.
Instalar librería Adafruit Motorshield v2
Para la versiones v2 en adelante, debemos utilizar esta librería. No es compatible con la antigua librería AF_Motor usadas para la v1, así que mucho ojo con la versión de Motor Shield.
La puedes descargar del repositorio de GitHub, es lo más adecuado, así descargarla en tu ordenador. La manera más sencilla es acceder a Programa/Incluir librería/Añadir librería .ZIP…
Esto abrirá una ventana de diálogo para que selecciones el archivo .ZIP que nos hemos descargado de GitHub.
Vete hasta la carpeta donde la has guardado y lo seleccionas. Automáticamente se instalará la librería en tu máquina y tendrás acceso al código y a los ejemplos.
Por último te recomiendo que accedas a la carpeta de la librería y elimines un directorio que se llama .github. No da ningún problema pero saldrá un aviso cada vez que cargues o compiles algún sketc que utilice esta librería.
Fuente de alimentación del Motor Shield
Los motores eléctricos necesitan mucha energía, especialmente los motores baratos debido a su baja eficiencia. Es importante conocer las características de los motores que vayamos a utilizar. Con un poco de suerte, vendrán con unas pequeñas especificaciones escritas en el mismo motor.
Voltaje
Lo normal, es que trabajen entre 6V y 12V. El Adafruit Motor Shield está diseñado para trabajar en el rango de 5V a 12V. Por lo tanto, los típicos motores que trabajan entre 1,5V y 3V no funcionarán con este shield.
Corriente
El Adafruit Motor Shield está preparado para suministrar 1,2 A por cada motor, con picos de hasta 3A. Eso si, si los picos de corriente superan los 2A, la recomendación es utilizar algún sistema de protección ya que puedes quemar la placa.
Alimentar los motores con una pila de 9V no es una buena opción, según las especificaciones. La mejor manera de suministrar energía a los motores es a través de una batería de plomo ácido o MiMH.
Hay dos alternativas a la hora de alimentar el Adafruit Motor Shield
Una de las soluciones que nos permite este shield es utilizar una fuente separada para Arduino y otra para los motores, separando así la lógica de la potencia. Además, así evitaremos los posibles problemas de ruido.
Su voltaje de operación es entre 5V y 12V. Podemos trabajar de dos formas que vendrán definidas si tenemos conectado el jumper en los pines Vin o no. En la siguiente imagen te muestro donde se encuentran.
- Podemos alimentar Arduino a través de un conector Jack DC o a través del puerto USB. Si insertamos el VIN Jumper esto permitirá que Motor Shield tenga potencia. Puedes comprobarlo porque se enciende el LED verde al lado del Jumper.
- La otra forma es quitando el VIN Jumper y alimentando por separado el Arduino y el Motor Shield. En este caso hasta que no conectemos los cables de alimentación externa al Motor Shield, no se encenderá el dispositivo.
Ya tenemos todo preparado para empezar a controlar motores con Arduino a través del Adafruit Motor Shield. Vamos a ver los 3 casos posibles.
Para las pruebas voy a utilizar el segundo método, una fuente de alimentación única para las dos placas, aunque la recomendación es utilizar dos fuentes de alimentación separadas.
Probando el motor paso a paso
Los motores paso a paso o stepper motors, sirven para un control semipreciso, suficiente para muchos robots y máquinas de CNC.
Conectando el motor
El Motor Shield puede controlar motores paso a paso unipolares (5 o 6 cables) y bipolares (4 cables). Utiliza los conectores M1 y M2 o M3 y M4.
Para realizar las pruebas voy a utilizar el motor unipolar 28BYJ-48 de 5 cables. El cableado del motor sería el siguiente.
Recuerda que tienes que tener conectado el shield a la placa para poder probarlo.
Código de ejemplo
Abre el entorno de desarrollo. Vamos a trabajar con el ejemplo que incorpora esta librería Archivos/Ejemplos/Adafruit Motor Shield V2 Library/StepperTest.
Analicemos el código que viene incluido en el ejemplo.
Librerías requeridas
1 2 3 |
#include <Wire.h> #include <Adafruit_MotorShield.h> #include "utility/Adafruit_MS_PWMServoDriver.h" |
En estas tres líneas se añaden las librerías que vamos a utilizar.
- Wire.h: librería para la comunicación I2C con Arduino..
- Adafruit_MotorShield.h: librería de Adafruit Motor Shield.
- «utility/Adafruit_MS_PWMServoDriver.h»: librería de utilidades para la utilización de los pines digitales PWM.
Creando una instancia del objeto Adafruit_MotorShield
1 2 3 4 |
// Create the motor shield object with the default I2C address Adafruit_MotorShield AFMS = Adafruit_MotorShield(); // Or, create it with a different I2C address (say for stacking) // Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61); |
En estas líneas se define la dirección I2C que va a utilizar el shield. Si lo dejamos como está en el ejemplo, utilizará la dirección por defecto. Si queremos modificar la dirección por defecto, podemos hacerlo poniendo una de forma manual.
Controlar motores con Arduino a través del Adafruit Motor Shield requiere de la comunicación I2C. Si tenemos otros dispositivos que utilizan este tipo de comunicación, debemos tener cuidado a la hora de gestionar bien las direcciones para que no se repita la misma en dos dispositivos.
Iniciar el motor paso a paso
1 2 3 |
// Connect a stepper motor with 200 steps per revolution (1.8 degree) // to motor port #2 (M3 and M4) Adafruit_StepperMotor *myMotor = AFMS.getStepper(200, 1); |
En esta parte del código se crea una instancia de la clase Adafruit_StepperMotor. Se especifica para cada motor, el número de pasos por revolución y donde está conectado. Cada paso nos indica un número de grados por ejempo 8 grados por paso. Si dividimos 360/8 nos da el número de pasos que necesita para dar una vuelta, 45 pasos.
También debemos de especificar dónde hemos conectado el motor. Ese es el segundo parámetro que puede coger los valores 1 y 2. Encontrarás una diferencia con respecto al ejemplo de la librería. Si miras el esquema de conexión, yo he conectado el motor en los conectores M1 y M2, por lo tanto hay que poner un 1 a la hora de instanciar la clase. Si se utilizan los conectores M3 y M4 hay que poner un 2. Puedes ver la numeración M1, M2, M3 y M4 en la propia placa.
Función setup()
1 2 3 4 5 6 7 8 9 |
void setup() { Serial.begin(9600);// set up Serial library at 9600 bps Serial.println("Stepper test!"); AFMS.begin(); // create with the default frequency 1.6KHz //AFMS.begin(1000); // OR with a different frequency, say 1KHz myMotor->setSpeed(10); // 10 rpm } |
En la función setup() vamos a configurar los parámetros del monitor serie, las dos primeras líneas y a inicializar el shield con AFMS.begin(). Este método admite 0 parámetros o 1 parámetro e indica la frecuencia de la señal PWM. Si no pasamos ningún parámetro coge la frecuencia por defecto, 1,6KHz. Si pasamos un número entero, le estaremos diciendo que cambie la frecuencia.
La frecuencia dependerá de cada motor. Frecuencias muy altas reducen la eficiencia y frecuencias muy bajas hacen que el movimiento no sea continuo. Mi consejo es utilizar la que viene por defecto y modificar a la alza o a la baja según las características del motor.
Por último, le indicamos la velocidad con el método setSpeed(…). Admite un parámetro entero que indica las revoluciones por minuto (rpm).
Función loop()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
void loop() { Serial.println("Single coil steps"); myMotor->step(100, FORWARD, SINGLE); myMotor->step(100, BACKWARD, SINGLE); Serial.println("Double coil steps"); myMotor->step(100, FORWARD, DOUBLE); myMotor->step(100, BACKWARD, DOUBLE); Serial.println("Interleave coil steps"); myMotor->step(100, FORWARD, INTERLEAVE); myMotor->step(100, BACKWARD, INTERLEAVE); Serial.println("Microstep steps"); myMotor->step(50, FORWARD, MICROSTEP); myMotor->step(50, BACKWARD, MICROSTEP); } |
Para mover el motor necesitamos llamar al método step(pasos, dirección, tipo de paso). Estos son los parámetros que hay que pasar al método.
- pasos: indica el número de pasos que quieres mover el motor. Número entero de 16 bits.
- dirección: si quieres mover hacia adelante FORWARD o hacía atrás BACKWARD.
- tipo de paso: puedes elegir entre los 4 tipos de paso posibles.
- SINGLE: consiste en excitar una bobina cada vez. Este tipo se suele llamar movimiento por ola o par menor. No es el que se usa comúnmente, pero se suele utilizar para ahorrar energía. Por el contrario, se reduce par.
- DOUBLE: este tipo de movimiento consiste en excitar dos bobinas a la vez. También se conoce como par máximo y nos ofrece, el mayor par y el mayor consumo de energía.
- INTERLAVE: este tipo de movimiento reduce a la mitad los pasos. También conocido como medio paso, aumentamos por dos la resolución (los grados que gira cada paso) pero reducimos la velocidad a la mitad. El consumo está entre medias de los otros dos movimientos.
- MICROSTEP: este movimiento se utiliza para garantizar que el motor se mueva de una manera suave entre los pasos. Es ideal para reducir el ruido mecánico y evitar resonancias. No aumenta la resolución pero mantiene el par del motor.
En el siguiente vídeo te enseño cómo funciona el motor paso a paso.
Probando el motor DC
Como ya he comentado, el Adafruit Motor Shield puede controlar hasta cuatro motores DC de forma bidireccional. Esto quiere decir que puede hacerlos ir hacia adelante y hacia atrás. Suele ser muy útiles en proyectos donde se utilizan plataformas o robots motorizados.
Una de las ventajas de utilizar un shield para controlar motores con Arduino, es el control total de la velocidad. De hecho, es capaz de variar en incrementos de 0,5% gracias a alta calidad en la señal PWM.
Conectando el motor
La conexión es muy sencilla, disponemos de 2 conectores en M1, M2, M3 y M4 para el vivo y el neutro del motor. Solo debemos conectarlo al que queramos y listo.
Debemos de llevar cuidado con la polaridad. Si lo conectamos al revés, es decir el vivo en el neutro y viceversa, cuando digamos que vaya hacia adelante irá hacia atrás. Lo mismo sucedería con la colocación del motor.
En el siguiente esquema puedes ver un conexionado básico.
Código de ejemplo
Vamos a cargar el código de ejemplo que viene acompañando a la librería que hemos instalado. Vete a Archivos/Ejemplos/Adafruit Motor Shield V2 Library/DCMotorTest.
Incluir librerías y crear una instancia del objeto Adafruit_MotorShield
1 2 3 4 5 6 7 8 |
#include <Wire.h> #include <Adafruit_MotorShield.h> #include "utility/Adafruit_MS_PWMServoDriver.h" // Create the motor shield object with the default I2C address Adafruit_MotorShield AFMS = Adafruit_MotorShield(); // Or, create it with a different I2C address (say for stacking) // Adafruit_MotorShield AFMS = Adafruit_MotorShield(0x61); |
Estos dos pasos son igual que en el motor paso a paso. Si necesitas más información puedes mirarlo arriba.
Iniciando los motores DC
1 2 3 4 |
// Select which 'port' M1, M2, M3 or M4. In this case, M1 Adafruit_DCMotor *myMotor = AFMS.getMotor(1); // You can also make another motor on port M2 //Adafruit_DCMotor *myOtherMotor = AFMS.getMotor(2); |
En esta ocasión utilizamos motores DC por lo tanto tenemos que hacer uso del método AFMS.getMotor(n), donde n es el número de puerto donde esté conectado el motor. Para M1 será 1, M2 será 2, M3 será 3 y M4 será 4.
Función setup()
1 2 3 4 5 6 7 8 9 10 11 12 13 |
void setup() { Serial.begin(9600); // set up Serial library at 9600 bps Serial.println("Adafruit Motorshield v2 - DC Motor test!"); AFMS.begin(); // create with the default frequency 1.6KHz //AFMS.begin(1000); // OR with a different frequency, say 1KHz // Set the speed to start, from 0 (off) to 255 (max speed) myMotor->setSpeed(150); myMotor->run(FORWARD); // turn on motor myMotor->run(RELEASE); } |
Las tres primeras líneas son para iniciar el monitor serie e iniciar el Adafruit Motor Shield con la frecuencia por defecto. Recuerda que puedes cambiar dicha frecuencia por otra.
Lo siguiente que hace es indicar la velocidad de inicio con el método setSpeed(velocidad). La velocidad debe ser un entero de 8-bit es decir, solo admite valores de 0 a 255.
Con el método run(dirección) le decimos para donde tiene que moverse. Dirección puede tomar tres valores:
- FORWARD: rotación hacia adelante.
- REVERSE: rotación en sentido contrario.
- RELEASE: parar la rotación. No es un freno, simplemente corta la corriente del motor.
Como ya te he dicho, la dirección dependerá de la polaridad y de la situación del motor.
Función loop()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
void loop() { uint8_t i; Serial.print("tick"); myMotor->run(FORWARD); for (i = 0; i < 255; i++) { myMotor->setSpeed(i); delay(10); } for (i = 255; i != 0; i--) { myMotor->setSpeed(i); delay(10); } Serial.print("tock"); myMotor->run(BACKWARD); for (i = 0; i < 255; i++) { myMotor->setSpeed(i); delay(10); } for (i = 255; i != 0; i--) { myMotor->setSpeed(i); delay(10); } Serial.print("tech"); myMotor->run(RELEASE); delay(1000); } |
En la función loop() hace una serie de movimientos utilizando los métodos setSpeed(…) para la velocidad y run(…) para indicar hacia donde se tiene que mover. Los dos primeros bucles for(…) hace un movimiento hacia adelante (FORWARD) con una aceleración progresiva y luego una desaceleración progresiva. Cambia la dirección hacia atrás (BACKWARD) y hace lo mismo, aceleración y desaceleración progresiva. Por último para el motor (RELEASE).
En el siguiente vídeo puedes ver el resultado.
Probando un servomotor
Por último vamos a ver cómo controlar un servomotor con Adafruit Motor Shield. Quizás sea el más sencillo de utilizar. Para controlar motores con Arduino de este tipo, no se requiere la librería de Adafruit.
Podemos controlar hasta dos servos. Para ello la placa dispone de dos grupos de pines macho. En concreto vamos a encontrar 3 pines por grupo. Uno para tierra, otro para aplicar el voltaje y el último la señal de control PWM.
En la propia placa viene la inscripción de cada servo. El Servo 1 corresponde al pin 10 de Arduino y el Servo 2 corresponde al pin 9 de Arduino.
Lo bueno de utilizar el shield para controlar un servomotor, es que dispone de un módulo PWM propio. Este módulo es muy preciso, más que las salidas PWM del propio Arduino. Esto nos permitirá un mejor control sobre los servos.
Para programar en código nativo de Arduino, debemos de utilizar la librería Servo. Ya escribí un tutorial muy completo al respecto que puedes consultar.
Código de ejemplo
Para controlar motores con Arduino de este tipo, vamos a utilizar el siguiente código. No te voy a explicar nada ya que lo puedes ver íntegramente en el tutorial que escribí sobre servomotores.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
// Incluímos la librería para poder controlar el servo #include <Servo.h> // Declaramos la variable para controlar el servo Servo servoMotor; void setup() { // Iniciamos el monitor serie para mostrar el resultado Serial.begin(9600); // Iniciamos el servo para que empiece a trabajar con el pin 9 servoMotor.attach(9); } void loop() { // Desplazamos a la posición 0º servoMotor.write(0); // Esperamos 1 segundo delay(1000); // Desplazamos a la posición 90º servoMotor.write(90); // Esperamos 1 segundo delay(1000); // Desplazamos a la posición 180º servoMotor.write(180); // Esperamos 1 segundo delay(1000); } |
En el siguiente vídeo te muestro su funcionamiento.
Conclusiones
En el mercado podemos encontrar muchos Motor Shield para Arduino. En este artículo te he hablado de uno en concreto pero puedes aplicar los conceptos adquiridos y utilizarlos para controlar motores con Arduino. Como siempre digo, la teoría es un buen punto de partida pero si quieres aprender debes poner en práctica dichos conceptos.
Cualquier duda o sugerencia lo puedes dejar en los comentarios de este artículo. Si te ha gustado, comparte.