bclose

Motores paso a paso: 28BYJ-48

Primer contacto con un motor paso a paso

Objetivos

 

 

    • Insistir con los motores paso a paso.
    • Montar un pequeño motor 28BYJ-48 con su adaptador.
    • Escribir un primer programa de control muy sencillo.

 

 

Material requerido.

 

Imagen de Arduino UNOArduino UNO
BreadboardUna Protoboard
conexiones4 x Cables Dupont Macho Hembra
Incluye adaptadorUn pequeño motor  28BYJ-48   y su breakboard
 

Volviendo con los Motores paso a paso

 

En la sesión anterior dimos un pequeño repaso a la teoría que hay detrás de los motores paso a paso e intentamos sentar las cuatro ideas importantes que debéis conocer para elegir y usar con éxito, uno de esto motores.

En esta sesión, vamos a usar un pequeño motor paso a paso unipolar, muy común en el mundo Arduino por su pequeño tamaño y bajo coste, el 28BYJ-48 y el adaptador  que suele venir con él, basado en el chip ULN2003A.

Incluye adaptador

Veremos en primer lugar las características que presenta y después montaremos un pequeño circuito básico, para mover el motor. Como siempre intentaremos que el ejemplo sea lo más simple posible para que en esta primera ocasión veáis con claridad la forma de manejarlos.

Y poco más que decir en esta pequeña introducción. Vamos pues, a meternos directamente en harina.

 

 

El motor paso a paso 28BYJ-48

 

Este pequeño motor es muy habitual en los proyectos con pequeños robots y posicionadores caseros sencillos, porque aunque no es demasiado potente, ni rápido  tiene varias características más que simpáticas, además de ser muy barato (Unos pocos euros).

Y como no podía ser de otra manera, empezaremos por buscar su manual (Va que sí, que vosotros podéis encontrarlo en Internet).

Caracteristicas

Es un motorcito unipolar con las siguientes características:

 
  • Tensión nominal de entre 5V y 12 V.
  • 4 Fases.
  • Resistencia 50 Ω.
  • Par motor de 34 Newton / metro más o menos 0,34 Kg por cm.
  • Consumo de unos 55 mA.
  • 8 pasos por vuelta.
  • Reductora de 1 / 64.
 

Traduciendo esto a cristiano, quiere decir que como es de 4 pasos (Steps), u 8 medios pasos  (O half Steps) por vuelta y usa una reductora de 1 /64, por lo que necesitamos dar 8 * 64 = 512 impulsos para completar un giro completo a medios pasos.

 
  • Sé que parece confuso. Hay 4 bobinas, si las excitamos de una en una tenemos 4 pasos x 64=256 pasos por vuelta. Pero también podemos excitar la bobina mediante medios pasos, como veíamos en las tablas de la sesión previa (que es el ejemplo que vamos a hacer) y por eso a medios pasos una vuelta son 8 * 64 = 512 impulsos
 

Además si no recuerdo mal de mis lejanos días de universidad, un par de 0,34 Kg por cm, significa que con una polea de un 1cm de diámetro colocado en el eje, este pequeño motor levantaría un peso de 350 gramos contra la gravedad, lo que no está mal.

Guia de colores
detalle

Este es su diagrama de conexión de bobinas, y además marca los colores del cable en función de su conexión interna. El motor presenta un conector al extremo en el que podemos pinchar cables de protoboard si hay que moverlo directamente, o bien para conectarlo a su adaptador.

Fijaros que su consumo es muy bajo, de unos 55 mA, dentro del rango que nuestro USB proporciona a Arduino (Siempre que no intentemos alimentarlo con un pin) y lo alimentaremos mediante la breakboard típica que le acompaña,  que suele usar un integrado del tipo ULN2003A que es un array de transistores Darlington, que soporta hasta 500 mA y que ya dispone de un conector para el motor y de unos pines (IN1 – IN4) para conectar a nuestro Arduino.

Detalle del adaptador
 
  • Sin entrar en muchos detalles, un Darlington suele ser un par de transistores bipolares colocados juntos y que se manejan como uno único.
  • La ventaja de este esquema es que aumenta mucho la ganancia del transistor resultante y además permite la conducción de grandes corrientes y tensiones.
  • Hemos usado uno de estos transistores para alimentar una tira Ed LEDS aquí.
 

 

Conectando el motor 28BYJ-48

 

Pues usando la breakboard no tiene mucho mérito. Conectad el motor primero a su conector, que tiene una posición para impedir que lo coloques al revés y después vamos a colocar las 4 fases a nuestro Arduino de modo que podamos excitarlas de forma independiente.

Es importante que entendáis la idea de que vamos a ir excitando cada una de las fases (O varias simultáneamente) en secuencia levantando a HIGH el pin de Arduino correspondiente.

No merece la pena montar un esquema de protoboard para esto. Para conectar vuestro Arduino usad la siguiente tabla:

Arduino1211109
BreakoutIN1IN2IN3IN4

Conectad  GND y Vcc a los pines correspondientes del adaptador y eso es todo (Gran ventaja cuando usas módulos a medida) vamos con el programa.

 

El programa de control

 

Mientras que los motores CC normales, están diseñados para que al alimentarlos giren de forma continua, un motor paso a paso está diseñado para girar un pasito cada vez que alimentas una de las fases.

Por eso nuestro programa tendrá que gestionar la secuencia en la que excitamos las bobinas para que el motor vaya avanzando de forma continua.

En un motor de 4 fases como este que vamos a usar hay tres maneras de hacer esta secuencia como veíamos en la sesión anterior.

Excitando dos bobinas cada vez (Suele ser lo que recomienda el fabricante)

PASOBobina ABobina BBobina CBobina D
1ONONOFFOFF normal
2OFFONONOFF
3OFFOFFONON
4ONOFFOFFON

Tendríamos máximo par, buena velocidad y alto consumo.

Excitando solo una bobina cada vez (Se le llama wave drive):

PASOBobina ABobina BBobina CBobina D
1ONOFFOFFOFF wave
2OFFONOFFOFF
3OFFOFFONOFF
4OFFOFFOFFON

Que produciría un par menor (Porque solo se activa una bobina en lugar de dos) y consumo bajo.

O podríamos dar medios pasos así:

PASOBobina ABobina BBobina CBobina D
1ONOFFOFFOFF Animacion del movimineto
2ONONOFFOFF
3OFFONOFFOFF
4OFFONONOFF
5OFFOFFONOFF
6OFFOFFONON
7OFFOFFOFFON
8ONOFFOFFON

El movimiento es más suave y lento que con los métodos anteriores, y el consumo y el par es también intermedio.

Y naturalmente lo habituales, ya os habréis sospechado que vamos a definir unos arrays con estas tablas para secuenciar el movimiento. Por ejemplo en el caso de usar medios pasos el array sería algo así:

int Paso [ 8 ][ 4 ] =
   {  {1, 0, 0, 0},
      {1, 1, 0, 0},
      {0, 1, 0, 0},
      {0, 1, 1, 0},
      {0, 0, 1, 0},
      {0, 0, 1, 1},
      {0, 0, 0, 1},
      {1, 0, 0, 1}
   };

Y seguro que no tendréis problema en definir el array correspondiente a los otros dos tipos de movimiento

Nuestro programa  Prog_98_1 recorrerá el array y alimentara las bobinas de acuerdo a los valores que presenta. Empecemos con algunas definiciones:

#define IN1  12
#define IN2  11
#define IN3  10
#define IN4  9

int steps_left=4095;
boolean Direction = true;
int Steps = 0;                       // Define el paso actual de la secuencia

Los defines indican a que pines de nuestro Arduino vamos a conectar cada una de los terminales de las bobinas del motor. Después algunas variables para control y un array que representa la secuencia. El setup es bastante sencillo

void setup()
   { pinMode(IN1, OUTPUT);
     pinMode(IN2, OUTPUT);
     pinMode(IN3, OUTPUT);
     pinMode(IN4, OUTPUT);
   }

Vamos a definir una función llamada stepper()  que avanza un paso cada vez que la invocamos, en realidad medio paso dada la matriz de excitación y que controle en que punto de la secuencia estamos.

Así, el programa principal quedaría: Prog_98_1

void loop()
   { while(steps_left>0)
        { 
           stepper() ;     // Avanza un paso
           steps_left-- ;  // Un paso menos
           delay (1) ;
        }
     delay(300);
     Direction =! Direction;  // Invertimos la direceccion de giro
     steps_left = 4095;
   }

Usamos Steps_left para definir el número de pasos que queremos girar, y por eso mientras queden pasos pendientes seguimos en el while, que lo que hace es avanzar un paso, disminuir el número de pasos pendientes y hacer un delay que controla la velocidad de giro.

Cuando acaba el while, hacemos un delay para poder apreciar el final e invertimos el valor de direction para cambiar la dirección de giro.Vamos con la funcion Stepper que parece más complicada:

void stepper()            //Avanza un paso
   {  digitalWrite( IN1, Paso[Steps][ 0] );
      digitalWrite( IN2, Paso[Steps][ 1] );
      digitalWrite( IN3, Paso[Steps][ 2] );
      digitalWrite( IN4, Paso[Steps][ 3] );

      SetDirection();
   }

Lo se, da asco. Es tan fácil que aburre. Usamos la variable Steps para saber en cuál de los 8 estados posibles de la matriz estamos y escribimos en las bobinas los valores que corresponden a esa situación.

Es SetDirection() quien va a controlar la dirección de giro y el valor de Steps, vamos a ver como:

void SetDirection()
   {  
      if(Direction)
         Steps++;
      else
         Steps--;

      Steps = ( Steps + 8 ) % 8 ;
   }

Es muy fácil ver que si giramos en la dirección digamos positiva, hay que ir incrementando Steps para mantener el giro. Y tampoco es complicado ver que en el giro contrario hay que irlo decrementando para que lea el array al revés. Pero quizás la última línea merece una explicación aparte.

A medida que vamos incrementando Steps, queremos que cuando pase de 7 vuelva a 0 y esto se consigue muy fácil haciendo

Steps = Steps % 8

Es decir tomando el modulo con respecto a 8, pero si lo vamos decrementando, alcanzaremos valores negativos, y el módulo de algo negativo sigue siendo negativo, lo que no nos vale, porque necesitamos que  el siguiente valor a 0 sea 7 y no -1.

Esto es lo que conseguimos de una tacada haciendo

Steps = ( Steps + 8 ) % 8 ;

Compruébalo si no me crees.

 
  • He visto en Internet que esto lo hacen con un programita así:

    if (Steps>7)
        Steps=0 ;
    if (Steps<0)
        Steps=7 ;
  • Pero mi sentido de la estética y la vagancia me impiden escribir tanto y además son completamente equivalentes (Y además es un código mas compacto y quedón el primero) 

El resultado es un motorcito girando primero en una dirección y después en la contraria tranquilamente.

 

 

 

Resumen de la sesión

 
    • Montamos un primer circuito de control de nuestro motor paso a paso 28BYJ-48.
    • Vimos las varias maneras de controlarlo según como excitemos las fases del motor.
    • Programamos un ejemplo con 8 semipasos para que el motor gire suavemente. 
 

 

 

 

 

 

 

(61) Comments

  • Admin tenga buenas noches, disculpe si es algo molesto pero en mi universidad tenemos que realizar un proyecto en el cual mi grupo tomo por tal construir una casa “domotica” (encender luces, ventiladores, alarma y ABRIR GARAJE) todo lo anterior esta bien a excepción del garaje el cual no he dado con el movimiento del motor (abrir y cerrar -_- ) le pido por favor mire este video y me diga que esta mal alli a principio puede ver mi codigo que es muy sencillo pero el cual no se que error lleva, el motor lo estoy manejando solo con dos pines IN1 = pin 8 arduino IN2 = pin 9 arduino, cuando quiere mueve todo en un sentido, aveces avanza y retrocede y asi, al presionar 1 deberia avanzar y el dos retroceder (abrir garaje cerrar garaje) … tengo algo mal o el problema sera el motor o que me recomienda usted? le agradezco su respuesta …
    ACA EL VIDEO
    https://youtu.be/2xde2faJRrk

    • No se que decirte Juan Luis, ponme aqui el codigo y le chamos un oje, pero describeme lo mas exactamente posible el problema ¿Vale?

    • Jose

    hola disculpa ese driver me podría funcionar con tipo de motor de 4 hilos como este “ miniature stepper motor “ si me pudieses ayudar seria de muy gran ayuda

    • En principio deberia funcionar

  • HOLA ME PODRIAS MANDAR EL CODIGO CORRECTO PARA EL PRIMER EJEMPLO DEL MOTOR PASO A PASO, EL QUE RECOMIENDA EL FABRICANTE. NO CONSIGO QUE GIRE EL MOTOR. HE HECHO EL ARRAY DE 4X4 SEGUN EL GRAFICO Y NADA.
    GRACIAS . UN SALUDO.

    • Antonio, tienes los ejemplos en la propia sesion con vinculos para descargar

  • hola llevo ya siguiendo esta pagina casi 1 año y todo lo que vais subiendo y estoy diseñando una cnc e impresora 3d y voy a montarle un arduino mega para poder tener mas peso ya que lo que he leido por internet todos van un poco justo y yo la quiero mas versatil pero tengo la duda de si los controladores de los motores me piden unas puertas del arduino especificas como son las pwm ya que todos ante la duda montan una shield y yo estoy diseñandola tambien para poder tener todo montado y sea cuestion de pocos pasos el cambiar de cnc a impresora 3d

    • Hombre, yo te recomendaria un shield porque por regla general te descargas de las complicaciones del PWM, que son que interfieren con los timers, mientras que si usas un shield los independizas

  • A LA PLACA SE PODRÍA CONECTAR UN MOTOR DE CC ?

    • Hola antonio,

      Se podria usar solo una de las fases para manejar un mootor de continua, pero no podrias invertir su direccion de giro, lo que ya es un tanto molesto.

      Seria mas practico que usaras un chip L293d o bien un shield de motores V1

  • Hola, estoy investigando un poquito con el kit, y al llegar al motor paso a paso y compilarle este programa, me he fijado que para valores de 512 impulsos solo se mueve 45º, en cambio si le meto los 4096 pulsos, si realiza la vuelta completa… ¿sabría decirme por qué?
    Muchas gracias de antemano!

    • Hola ANabel, mirando la hoja de datos este motor tiene un ángulo de paso de 5.625°. Esto quiere decir que para que el engrane gire 1 revolución requiere 360°/5.625° = 64 pasos. Como además tiene una relación de transmisión de 1:64 (1 vuelta el eje = 64 vueltas el engrane); entonces para que el eje del motor gire 1 revolución son necesarios 64×64 pasos, es decir 4096 pasos. Un saludote!

  • Hola, tengo un problema y me parece buena idea ponerlo a su consideración ya que la pagina es muy buena, y pues podria encontrar alguna solucion con su ayuda…
    necesito controlar un motor paso a paso con grados de 9oº, 180º y 360º y pues a lo que voy investigando no encuentro una ayuda que me diga como podria codificar estos grados, conociendo que 1/4 de paso en el motor es 90º y todo lo que es teorico del motor, pero no logro codificarlo…. estoy usando el pic16f877a un motor de 5 hilos, si podrian ayudarme estaria muy agradecido…

    • Hola Franz, Parece sencillo que si quieres girar 90 bastaria mandar girar 90 x 4 pasos = 360 pasos. Pero si la cosa se lia siempre puedes usar un shield con su libreria que te ahorrara todo el problema de contrtol

  • Hola de nuevo Ivan, perdona por lo pesado que me estoy poniendo, pero es que no consigo hacer que el motor me gire mas de ocho vueltas. He cambiado los numeros de int steps_left y steps_left en el void loop y cuando el numero es mayor de
    98300 ya no me funciona el motor y en el adaptador no se encienden los cuatro leds rojos. Sera problema del adaptador?
    Perdona de nuevo por lo pesado que me estoy poniendo y la lata que te estoy dando.
    Un saludo
    Pedro.

    • Pedro

    Pedro
    Hola de nuevo Ivan, el codigo qie utilizo es el del ejemplo:
    #define IN1 11
    #define IN2 10
    #define IN3 9
    #define IN4 8

    int steps_left=20095;
    boolean Direction = true;
    int Steps = 0;

    int Paso [ 8 ][ 4 ] =
    { {1, 0, 0, 0},
    {1, 1, 0, 0},
    {0, 1, 0, 0},
    {0, 1, 1, 0},
    {0, 0, 1, 0},
    {0, 0, 1, 1},
    {0, 0, 0, 1},
    {1, 0, 0, 1}
    };

    void setup()
    {
    Serial.begin(115200);
    pinMode(IN1, OUTPUT);
    pinMode(IN2, OUTPUT);
    pinMode(IN3, OUTPUT);
    pinMode(IN4, OUTPUT);
    }

    void loop()
    { while(steps_left>0)
    {
    stepper() ; // Avanza un paso
    steps_left– ; // Un paso menos
    delay (1) ;
    }
    delay(3000);
    Direction=!Direction;
    steps_left=20095;
    }

    void stepper() //Avanza un paso
    {
    digitalWrite( IN1, Paso[Steps][ 0] );
    digitalWrite( IN2, Paso[Steps][ 1] );
    digitalWrite( IN3, Paso[Steps][ 2] );
    digitalWrite( IN4, Paso[Steps][ 3] );

    SetDirection();
    }

    void SetDirection()
    {
    if(Direction)
    Steps++;
    else
    Steps–;

    Steps = ( Steps + 8 ) % 8 ;
    }
    Con este codigo solo consigo que me de cinco vueltas para la derecha, se para y otras cinco para la izquierda, y asi sucesivamente. Lo que yo quiero es que de mas vueltas para los dos lados.
    Muchas gracias por atender tan pronto mi problema.
    Un saludo
    Pedro

    • Hola Pedro, el número de vueltas que da para cada lado lo controlas con la variable steps_left. Si quieres cambiar el número de vueltas tienes que cambiar ese valor tanto en el setup como en el loop. Un saludote!

    • Pedro

    Hola:
    Mi problema es que no consigo que gire el motor mas de cinco vueltas a la derecha y despues otras cinco a la izquierda.
    ¿ Como conseguir que de muchas mas vueltas tanto para un lado como para otro?
    Soy nuevo en esto de los motores PaP y arduino, vienen muy bien los tutoriales que nos pones y nos dan animo para no estancarnos a los nuevos en este mundo de arduino.
    Muchas gracias
    Un saludo Pedro

    • Hola Pedro, no deberías tener problema en en hacer que giren indefinidamente para uno u otro lado, sólo con el hecho de que en cada loop se mueva un cierto número de pasos ya debería hacerlo, o puedes hacer que se mueva todos de una tacada con la función del ejemplo. Si no lo consigues pon si quieres la función que utilizas para moverlo e intentamos ayudarle.

      Un saludo.

  • Hola Lalo,

    Aunque ppuedes usar varios pines de arduino para controlar simultaneamente mas de uno de estos motores, es mas comodo que uses una controladora especificamente diseñada para controlar mas de un motor paso a paso como esta : http://www.prometec.net/producto/servo-shield-x16/

  • Hola Lalo, con la librería que estamos usando puedes controlar hasta 12 servos.

  • Creo que encontré la solución a ambos problemas, lo comparto por si a alguien le sirve:

    Se calienta, porque – aunque no esté en movimiento – siempre quedan dos bobinas activas. Para solucionarlo se deben desactivar todas las bobinas después de realizar el desplazamiento. Para esto, al final de la función spinMotor() se deben escribir las siguientes líneas:

    digitalWrite(IN1, 0);
    digitalWrite(IN2, 0);
    digitalWrite(IN3, 0);
    digitalWrite(IN4, 0);

    En relación a la falta de fuerza, parece que el tiempo de polarización es bajo y comienza con un cierto desfaze entre la instrucción de polarización y la posición del eje, lo que naturalmente le quita fuerza. La solución fue aumentar el tiempo de polarizado dentro de la función spinMotor(), es decir, en lugar de delay(1) escribí delay(2). Con esto se soluciona el problema del torque, aunque se castiga la velocidad de rotación. Para mi proyecto la velocidad sigue siendo útil. Si no lo fuera, creo que la única opción sería cambiar de motor.

    Saludos

Give a Reply

WordPress Anti-Spam by WP-SpamShield