Controlar motores – Shield L293D con Arduino

El Shield de driver de motor que presento hoy está basado en el original de Adafruit version 1.0 (ya que hoy existe una version 2.0 mejorada) y que permite manejar varios motores de distintos tipos mediante 2 L293D con Arduino en una conveniente placa Shield que podemos conectar a nuestro Arduino UNO, Mega y otros compatibles.

El Shield L293D compatible 1.0

Shield L293D con Arduino 1.0

Mi Shield L293D no es el original de Adafruit (que ya no lo comercializa) sino una versión compatible de DK Electronics (que se vende aun hoy en día). Si quiere conseguir uno y tienen opción, traten de buscar uno que posea conectores superiores para continuar conectando otros Shields. Mi verión no lo posee.

El Shield posee varias características que detallamos a continuación:

  • Posee 2 conectores para servo motores los que poseen una limitación (que no posee la version 2.0) y es que se alimentan de la alimentación de su Arduino, por lo que manejar 2 servos con actividad contínua puede hacer que el controlador de voltaje de su Arduino caliente un poco.
  • Integra 2 L293D donde cada uno brinda un doble puente H con capacidad de manejar 2 motores de corriente continua cada uno bidireccional, o 4 motores de corriente continua en una sola dirección.
  • Posee una entrada de alimentación externa para alimentar los motores conectados a los puentes H de los L293D
  • La alimentación de los motores con los L293D también puede hacerse mediante Vin del Arduino (si usted lo alimenta con una fuente externa) mediante un jumper a tal fin.

Además, los L293D poseen las siguientes características a tener en cuenta para elegir motores apropiados (o para evaluar si puede manejar motores que ya tenga):

  • Alimentación para motores de 4,5V a 36V
  • Alimentación separada para lógica (5V)
  • Corriente máxima de trabajo: 600mA por cada canal (soporta picos de hasta 1,2A)

Les dejo un enlace a la hoja de datos del chip L293/D: https://www.ti.com/lit/ds/symlink/l293.pdf

Pines a considerar usando el Shield L293D con Arduino

La información mas relevante para mi, fue entender que pines de nuestro Arduino se usan para cada caso. En general usted no usará todos los drivers del Shield, y saber que pines estan vinculados a cada salida es importante para luego saber que pines le quedan disponibles. En mi caso los pines analógicos son accesibles (no se usan en el Shield) ya que el mismo Shield posee unos agujeros que puedo aprovechar para soldar pines o un conector para usarlos (recuerde que los pines A0 a A5 tambien pueden usarse para salidas digitales). Pero los pines digitales no lo son, por lo que si tiene un Shield como el mío, deberá ingeniárselas para acceder a los pines digitales que no use en el Shield, o usar un Arduino Mega 2560.

El uso de pines es el siguiente:

  • Servo 1: pin 10
  • Servo 2: pin 9
  • Motor 1: pin 11
  • Motor 2: pin 3
  • Motor 3: pin 6
  • Motor 4: pin 5
  • Shield (shift register): pines 4, 7, 8, 12

Los pines 2 y 13 no se usan. El pin 2 posee un agujero para soldar que facilita su uso. En base a la lista suministrada, usted verá que los pines 4, 7, 8 y 12 son fijos para manejar el Shield y no puede usarlos para otra cosa. El uso del resto de los pines es opcional dependiendo de que desee manejar y lo que no use podrá usarlo para otra función. Los pines A0 a A5 como dije también estan disponibles para uso genérico.

Manejo de Servos en el Shield L293D con Arduino

Las pruebas que realicé las hice con un clásico SG90.

Servo motor SG90 - L293D con Arduino

Este servo motor es muy común y viene con muchos kits de aprendizaje y kits de robots para Arduino. El motor consume unos 6-10mA en reposo. El consumo mientras rota es de 220mA ±20%. El pico de consumo (por ejemplo cuando se le ofrece resistencia), es de unos asombrosos 650mA ±15% lo cual es a tener en cuenta en nuestras aplicaciones, en especial porque los servos son alimentados desde el mismo Arduino.

El Shield no ofrece funcionalidad extra al manejo de servos y el mismo es equivalente a conectar los servos directamente a 5V, GND y el pin que el Shield dice: 10 para el Servo 1 y 9 para el Servo 2. Yo opté por alimentar mi Arduino con una fuente externa de 12V y 1,5A para que sea suficiente para alimentar el servo también. La alimentación básica por USB no será suficiente para que el servo funcione correctamente.

El código para probar los servos conectados al Shield L293D con Arduino sería el siguiente:

// Codigo de prueba para el manejo de servos con Shield
// L293D con Arduino (para la version 1.0 del Shield)
#include <Servo.h>

// Cambie el pin a 9 si conectará su servo al conector Servo2
#define SERVO_PIN 10

// Creamos un objeto del tipo servo para manejar 1 servo.
// Si desea manejar 2 servos al mismo tiempo deberá crear 2 objetos independientes
Servo servo1;

void setup() {
  // Conectamos el objeto con el pin que controlará al servo
  servo1.attach(SERVO_PIN);
  
  // Iniciamos pidiendo al servo que vaya a posición 0, que es todo a la derecha
  servo1.write(0);
}

void loop() {
  // Haremos 5 secuencias de movimientos
  for (int x=0; x<5; x++) {
    // Primero a posición media o 90 grados
    servo1.write(90);
    // Nos quedamos ahi 2 segundos
    delay(2000);
    // Repetimos pero a 180 grados
    servo1.write(180);
    delay(2000);
    // Volvemos a 90 grados
    servo1.write(90);
    delay(2000);
    // Y volvemos a 0 grados para terminar
    servo1.write(0);
    delay(2000);
  }
  
  // Cuando terminamos no hacemos nada. Para iniciar la secuencia de
  // nuevo solo presiones el boton reset en su Arduino o Shield.
  while(1);
}

Manejo de motores de corriente continua mediante el Shield L293D con Arduino

Para la prueba con motor de corriente continua bidireccional, yo usé la librería que Adafruit desarrolló para este Shield la que puede descargar desde aquí: https://github.com/adafruit/Adafruit-Motor-Shield-library/archive/master.zip

Yo conecté un motor con reducción típico de kits de robots para Arduino como el siguiente:

que funciona de 3V a 6V (yo usé los 5V del Arduino pero con fuente externa) y lo conecté al Shield a los 2 pines que corresponden al motor 1 (M1) ubicado cerca de los conectores para servos. Para las pruebas no importa que cable va a que conector, pero para una aplicación práctica será deseable que haga coincidir el FORWARD (hacia adelante) con el movimiento del motor que represente ese movimiento. El código es el siguiente y en mi motor produce ruido (no movimiento) para velocidades demasiado bajas ya que el motor no las soporta, pero esto no implica ningun problema para la prueba:

// Programa de ejemplo para el uso de Shield L293D con Arduino para el manejo 
// de motores de corriente continua bidireccional

// Usamos la librería AFMotor de Adafruit que nos resuelve casi todo
#include <AFMotor.h>

// Creamos un objeto para manejar nuestro motor. Necesitará un objeto 
// por cada motor que desee manejar. Use los números del 1 al 4 
// dependiendo del conector de motor que use de su Shield.
AF_DCMotor motor(1);

void setup() {
  // Encendemos el motor ajustando la velocidad a 200 (255 es el máximo)
  motor.setSpeed(200);
 
  // RELEASE es el estado de parada
  motor.run(RELEASE);
}

void loop() {
  uint8_t i;
  
  // FORWARD es el sentido "hacia adelante" del motor
  motor.run(FORWARD);
  
  // Variamos la velocidad desde 0 (parado) hasta 255 (maximo) 
  for (i=0; i<255; i++) {
    motor.setSpeed(i);  
    delay(10);
  }
 
  // Variamos la velocidad desde 255 hasta 0
  for (i=255; i>0; i--) {
    motor.setSpeed(i);  
    delay(10);
  }
  
  // BACKWARD es el sentido "hacia atras" del motor
  motor.run(BACKWARD);
  
  // Repetimos lo hecho antes con la velocidad
  for (i=0; i<255; i++) {
    motor.setSpeed(i);  
    delay(10);
  }
 
  for (i=255; i>0; i--) {
    motor.setSpeed(i);  
    delay(10);
  }
 
  // Paramos el motor y hacemos 1 segundo de pausa 
  motor.run(RELEASE);
  delay(1000);
} 

Luego de cargar el Sketch en su Arduino IDE, verá el motor girar para un lado y luego para el otro, primero acelerando y luego desacelerando, todo esto en forma continua. Para una mejor experiencia siempre recuerde considerar el uso de una fuente de alimentación externa en su L293D con Arduino.

31 comentarios en “Controlar motores – Shield L293D con Arduino”

  1. Gracias por el artículo, me está ayudando para el proyecto CNC DVD`s.
    Voy a comprar el servo SG90 que recomiendas, aconsejas alimentar la placa de Arduino una fuente externa.
    Los 2 motores paso a paso de la placa shield los tengo alimentados por una fuente externa, para su correcto funcionamiento.
    ¿Existe alguna forma de usar una sola fuente externa?
    Si estoy alimentando la placa arduino con fuente externa, ¿me puede valer para manejar los 2 motores paso a paso y el servo?
    Un saludo

    • Todo depende del diseño que estes implementando. En cuanto a fuentes externa, siempre se puede usar una unica fuente externa si es suficientemente potente para la corriente necesaria. Cuando se trabaja con motores, no se recomienda usar la misma fuente para los motores que la que usamos para la electronica, en especial cuando hay microprocesadores involucrados que son susceptibles a los ruidos (comunes en los motores). Supongo que para una prueba de concepto está bien si eres precabido. Las fuentes de computadora son excelente fuentes para propositos multiples y pueden entregar gran potencia. Hay que asegurarse que la corriente necesaria es del voltaje correcto y esta dentro de los parametros de la fuente que en esos casos varian por voltaje (entregan varios voltajes y distintos amperajes maximos por voltaje). Suerte con ese proyecto. Vamos a ver si podemos publicar una CNC basada en DVDs que hicimos hace un tiempito.

  2. Buenas tardes, tengo problemas con un motor shield de sainsmart, y no logro hacerlo funcionar, alguien sabe si es compatible con la libreria de adafruit version 1

  3. Hola tengo un problema al compilar
    Arduino:1.8.9 (Windows 10), Tarjeta:”Arduino/Genuino Uno”

    Opciones de compilación cambiadas, reconstruyendo todo
    Programaci_n_del_robot__carro__final:1:21: error: AFMotor.h: No such file or directory

    compilation terminated.

    exit status 1
    AFMotor.h: No such file or directory

    Este informe podría contener más información con
    “Mostrar salida detallada durante la compilación”
    opción habilitada en Archivo -> Preferencias.

    Me sale esto, hace que no existe una librería para el AFMotor.h
    Qué puedo hacer

  4. Hola ,estoy intentando hacer el pequeño proyecto este de los dvds y me pasa lo siguiente ,después de cargar todo al arduino y cargar el codigo g solo se mueve el servo los motores no ,el shield lo alimento con una fuente externa .He comprobado con el osciloscopio la salida y parece que las ondas las genera pero a muy poco voltaje ,también mencionar que la lie un poco al empezar ,para alimentar se me ocurrió la idea de alimentar mediante un puerto usb de portátil ,se me apago todo y casi me cargo el portátil.Pensando luego ,lógico el arduino esta a 9 y el usb del portátil a 5 por eso me paso ,portátil areglado pero no se si no me cargado el shield ?,son muy delicados ?.He probado con varios códigos y nada los motores no se mueven ,lo que si que pasa ,es lo siguiente ,si quito un cable de una bobina y lo toco con la conexión del medio el motor si hace ruido .No se algo se me escapa o simplemente me la he cargado .Gracias de antemano ,por tu trabajo y un saludo .

  5. Buenas tardes

    Soy un novato en esto del arduino, vaya por delante

    Mi idea era controlar 2 motores tal que asi

    https://www.amazon.es/gp/product/B07882FYB7

    Tipo de producto: motor DC de cepillo
    Modelo: XD-3420
    Potencia nominal: 30 W
    Tensión nominal (opcional): 12V, 24V
    Velocidad nominal: 3000 RPM (12 V), 6000 RPM (24 V)
    Actual: 0.5 A
    Longitud del eje de salida: 43 mm / 1.7 pulgadas
    Par de apriete: 1kgf.cm (12V), 2kgf.cm (24v)

    Tengo los dos motores, el arduino y el shield, pero no soy capaz de hacerlo funcionar

    Es posible hacerlo o necesito otro shield o alguna cosa mas??

    Gracias de antemano

  6. ¿Como puedo programo los motores, o más bien declarar los motores para que no pierdan potencia? . Uso botones para que manden la señal y prendieran el motor, pero… Ahora los motores no tienen fuerza, O sea, si pongo un ciclo automático los motores funcionan correctamente pero si hago que funcionen con los botones los motores con trabajo se mueven. Así que la energía no es el problema. ¿Sabes que puedo hacer?

    le dejo mi programa para ver si puede corregir algún error que este cometiendo.

    #include
    #include

    //SERVOS
    Servo Bloqueo;

    //MOTORES
    AF_DCMotor motor_x (1);//izquierda
    AF_DCMotor motor_y (2);//derecha
    AF_DCMotor motor_z (3);//central

    //BOTONES

    //SUBIR,BAJAR,DERECHA,IZIQUIERDA
    int Boton_S = 22;
    int Boton_B = 24;
    int Boton_D = 26;
    int Boton_I = 28;

    //ABRIR, CERRAR
    int Boton_A = 30;
    int Boton_C = 32;

    //PARAR
    int Boton_P = 34;

    //Variables dinamicas
    int estado_S = 0;
    int estado_B = 0;
    int estado_D = 0;
    int estado_I = 0;
    int estado_A = 0;
    int estado_C = 0;
    int estado_P = 0;

    int pulsador=0;
    int pulsadorAnt=0;

    void setup() {
    Serial.begin(9600);

    //inicializamos el pin del servo
    Bloqueo.attach (10);

    //inicializamos el pin del boton como entrada:
    pinMode(Boton_S,INPUT_PULLUP);
    pinMode(Boton_B,INPUT_PULLUP);
    pinMode(Boton_D,INPUT_PULLUP);
    pinMode(Boton_I,INPUT_PULLUP);
    pinMode(Boton_A,INPUT_PULLUP);
    pinMode(Boton_C,INPUT_PULLUP);
    pinMode(Boton_P,INPUT_PULLUP);

    //inicializamos los motores:
    motor_x.setSpeed(255);
    motor_y.setSpeed(255);
    motor_z.setSpeed(255);

    }

    void loop() {

    //Lee el valor del pin del boton y lo alamacena
    estado_S = digitalRead(Boton_S);
    estado_B = digitalRead(Boton_B);
    estado_D = digitalRead(Boton_D);
    estado_I = digitalRead(Boton_I);
    estado_A = digitalRead(Boton_A);
    estado_C = digitalRead(Boton_C);
    pulsador = digitalRead(Boton_P);

    if (estado_S == HIGH)
    {
    Subir();
    Serial.println(Boton_S);
    }
    else
    {
    Detener();
    Serial.println(Boton_S);
    }

    if (estado_B == HIGH)
    {
    Bajar();
    Serial.println(Boton_B);
    }
    else
    {
    Detener();
    Serial.println(Boton_B);
    }

    if (estado_D == HIGH)
    {
    Derecha();
    Serial.println(Boton_D);
    }
    else
    {
    Detener();
    Serial.println(Boton_D);
    }

    if (estado_I == HIGH)
    {
    Izquierda();
    Serial.println(Boton_I);
    }
    else
    {
    Detener();
    Serial.println(Boton_I);
    }

    if(pulsador == HIGH && pulsadorAnt == LOW)
    {
    estado_P = 1 – estado_P;
    delay(40);
    }
    pulsadorAnt = pulsador;

    if(estado_P == 1)
    {
    Parar();
    }
    else
    {
    Soltar();
    }

    }

    void Detener()
    {
    motor_x.run(RELEASE);
    motor_y.run(RELEASE);
    motor_z.run(RELEASE);
    }

    void Subir()
    {
    motor_x.run(RELEASE);
    motor_y.run(RELEASE);
    motor_z.run(FORWARD);
    }

    void Bajar()
    {
    motor_x.run(RELEASE);
    motor_y.run(RELEASE);
    motor_z.run(BACKWARD);
    }

    void Derecha()
    {
    motor_x.run(BACKWARD);
    motor_y.run(FORWARD);
    motor_z.run(RELEASE);
    }

    void Izquierda()
    {
    motor_x.run(FORWARD);
    motor_y.run(BACKWARD);
    motor_z.run(RELEASE);
    }

    void Abrir()
    {
    //no hay nada.
    }

    void Cerrar()
    {
    //No hay nada.
    }

    void Parar()
    {
    Bloqueo.write (180);
    motor_z.run(RELEASE);
    }
    void Soltar()
    {
    Bloqueo.write (90);
    motor_z.run(RELEASE);
    }

    • ¿Es posible que los 3 motores trabajen al mismo tiempo? ¿Has probado antes de comenzar si los 3 motores al mismo tiempo andan rapido? pregunto porque es comun tener suficiente potencia para un motor pero no para 2 o 3 simultaneos…

  7. Buenos dias- El siguiente programa me da error ” error compilando para la tarjeta arduino / genuini UNO” . Es copiado de un ejemplo de internet, No he podido usar motor shield 293. Me podrian ayudar? Gracias

    // Set Motor 1 conectado al puerto 1
    AF_DCMotor motor1 ( 1 );
    // Establecer la conexión 4 unido a Motor2
    AF_DCMotor Motor2 ( 4 );

    void setup ()
    {
    // Establecer la velocidad máxima para los motores 1 y 2
    motor1.setSpeed ( 255 );
    motor2.setSpeed ( 255 );

    }

    void loop ()
    {
    // Acciona el motor 1 en sentido horario
    motor1.run (hacia adelante);
    // Acciona el motor 2 en sentido antihorario
    motor2.run (hacia atrás);

    // espera de 5 segundos
    de retardo ( 5000 );

    // Apaga los 2 motores
    motor1.run (RELEASE);
    motor2.run (RELEASE);

    // Acciona el motor 1 en sentido antihorario
    motor1.run (hacia atrás);
    // Acciona el motor 2 en el sentido horario
    motor2.run (hacia adelante);

    // espera de 5 segundos
    de retardo ( 5000 );

    // Apaga los 2 motores
    motor1.run (RELEASE);
    motor2.run (RELEASE);
    }

    • Hola Alvaro. Veo casi todo lo que esta en loop() mal. Cosas como “de retardo ( 5000 );” no funcionará. Esa linea es probable que sea “delay(5000);”
      Además veo lineas como “motor2.run (hacia atrás);”, eso tampoco funcionará. No sé como vaya esa linea. Te aconsejo que revises el lugar de donde copiaste ese codigo porque no tiene mucho sentido…

  8. Hola buenas tardes.

    Estoy llevando a cabo un proyecto con arduino, y todavía no sé mucho sobre este mundillo. Me preguntaba si existirían motores de corriente bidireccionales cómo los de la foto, pero que trabajarán a más de 6V, ya que la me parece entender que la shield puede trabajar a bastante más.

    Un saludo.

    • Hola Mario, entiendo que si hay opciones que trabajan a más de 6v. Si buscas en Amazon verás que hay muchisimas alternativas. Solo debes tener cuidado con el consumo ya que los shields tienen un límite de amperaje que pueden entregar. Suerte con ese proyecto!

    • Su aumentas el consumo en amperes, podrías quemar la placa o al menos el integrado (driver) al que le pedís más de su límite. Para eso hay otros drivers más potentes que soportan mayor consumo como el l298N

  9. Muy bueno el artículo Quería consultarte que tipo de batería , voltaje y amperaje conviene utilizar para hacere funcionar dos motores iguales a los del articulo conectados a SHIELD DRIVER MOTOR, L293D?

    • En lo personal no creo que sea efectivo usar baterias para 2 servos. Esos motores tienen picos de más de 650mA. Aun asi, si fueras a intentarlo deberias conseguir una bateria de al menos 5V (6V mejor) y de unos asombrosos 1200mA aunque si deseas alimentar el Arduino y el Shield tambien necesitarás un poco más. No he medido el consumo total conjunto pero podrias hacerlo facilmente con un amperímetro.

    • La librería es “AFMotor.h” y no “AF_Motor”, pero si aun así no te funciona por favor comparte el código que estás probando y trataremos de ayudarte!

  10. hola muy buen dia
    acabo de empesar con arduino, y quiero controlar 4 motores dc con el shiend L293D
    pero me marca error en libreria
    me podrian ayudar como solusiono el problema
    me dise Error copilando para la targeta Arduino/Genuino Uno

    • Hola Ruben, para poder ayudarte con un código, necesitaríamos que compartas el código que estás tratando de compilar y te da error. De otra manera no sabremos que ocurre…

  11. Que tal!
    La página es excelente!
    Tengo una duda, soy nuevo en el mundo arduino y estoy en el proceso de aprendizaje para poder construir algo que tengo en mente. Una de las cosas que quiero hacer es por medio de arduino poder cortar el paso de un líquido. Que debería tener en cuenta a grandes rasgos?
    Muchisimas gracias.

    • Hola Sebastian,

      Gracias por leernos. Lo primero es que para cortar el paso de un liquido necesitas una valvula solenoide como la del enlace este: httpss://www.amazon.com/Adafruit-Industries-997-Water-Solenoid/dp/B00K0TKJCU/ref=sr_1_1?ie=UTF8&qid=1522339264&sr=8-1&keywords=arduino+solenoid+water que vienen de distintos tamaños (diametros) y caudal.

      Lo segundo es que para accionar la valvula solenoide es posible que necesites un relay, o al menos un transistor de potencia. Yo recomiendo no complicarse la vida y usar un rele, hay módulos Arduino con relays que se integran muy facilmente.

      Espero te sirva la información! Saludos y suerte con ese proyecto!

  12. MUCHAS GRACIAS ME AYUDO MUCHO TU PAGINA TENIA CASI MAS DE 5 HORAS TRATANDO DE SOLUCIONARLO Y BUSCABA Y BUSCABA Y NO ENCONTRABA ALGO PARA MI AYUDA GRACIAS POR LA LIBRERIA..

    • Me alegro mucho. La idea es ir fundando las bases para proyectos intermedios y avanzados donde trabajamos con motores y otros sensores o módulos. Gracias por visitarnos!

Deja un comentario