Archivos de la categoría programación

Motor paso a paso 28BYJ-48

Objetivos

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

Material requerido

 arduino
  • Arduino Uno o similar. Esta sesión acepta cualquier otro modelo de Arduino.
 Img_3_4
  •  Una Protoboard.
 Img_3_6-300x185
  • Algunos cables de Protoboard.
  • Motor paso a paso 28BYJ-48 y adaptador

Motor paso a paso

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.

Veremos en primer lugar las características que presenta y después montaremos un pequeño circuito básico, para mover el motor.

Es un motor 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.

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

  • 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, que es el ejemplo que vamos a hacer y por eso a medios pasos una vuelta son 8 * 64 = 512 impulsos

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.

El módulo cuenta con todos los componentes necesarios para funcionar sin necesidad de elementos adicionales, entre ellos diodos de protección y un regulador LM7805 que suministra 5V a la parte lógica del integrado L298N. Cuenta con jumpers de selección para habilitar cada una de las salidas del módulo (A y B). La salida A esta conformada por OUT1 y OUT2 y la salida B por OUT3 y OUT4. Los pines de habilitación son ENA y ENB respectivamente.

En la parte inferior se encuentran los pines de control del módulo, marcados como IN1, IN2, IN3 e IN4.

Conectando el motor 28BYJ-48

Pues usando la breakboard es muy sencillo. Conectad el motor primero a su conector, 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.

Para conectar vuestro Arduino usad la siguiente tabla:

ARDUINO 12 11 10 9
BREAKOUT IN1 IN2 IN3 IN4

Conectad  GND y Vcc a los pines correspondientes del adaptador.

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)

PASO BOBINA A BOBINA B BOBINA C BOBINA D
1 ON ON OFF OFF
2 OFF ON ON OFF
3 OFF OFF ON ON
4 ON OFF OFF ON

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

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

PASO BOBINA A BOBINA B BOBINA C BOBINA D
1 ON OFF OFF OFF
2 OFF ON OFF OFF
3 OFF OFF ON OFF
4 OFF OFF OFF ON

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í:

PASO BOBINA A BOBINA B BOBINA C BOBINA D
1 ON OFF OFF OFF
2 ON ON OFF OFF
3 OFF ON OFF OFF
4 OFF ON ON OFF
5 OFF OFF ON OFF
6 OFF OFF ON ON
7 OFF OFF OFF ON
8 ON OFF OFF ON

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

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}
   };

Nuestro programa  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

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);
   }

Ahora 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:

void loop()
   { 
   while(steps_left>0)
        { 
           stepper() ;     // Avanza un paso
           steps_left-- ;  // Un paso menos
           delay (1) ;
        }
     delay(300);
     direction =! direction; //Invertimos dir
     steps_left = 4095;
   }

El 28BYJ-48 tiene 64 pasos por vuelta y un reductor interno con una relación de 1/64. En conjunto hacen 4096 pasos por vuelta.

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 el método 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] );
      
     if(direction) 
             steps++; 
       else 
             steps--; 
     steps = (steps+8)%8;
   }

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.

Para controlar la dirección de giro y el valor de steps:

  • si giramos en la dirección digamos positiva, hay que ir incrementando steps para mantener el giro.
  • si el giro es contrario hay que ir decrementando para que lea el array al revés.

A medida que vamos incrementando steps, queremos que cuando pase de 7 vuelva a 0 y esto se consigue haciendo

steps = steps % 8

Es decir tomando el modulo (resto) 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 haciendo:

steps = (steps + 8) % 8 ;
  • También podrías hacerlo así:
    if (steps>7)
        steps=0 ;
    if (steps<0)
        steps=7 ;

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

ARDUMOTO SHIELD

Un chip típico para gobernar dos motores de continua,  con una carga de hasta 2 Amperios por cada uno,  incluyendo todo lo necesario para invertir la dirección de movimiento de estos y para controlar la velocidad de giro es chip L298.

La manera más cómoda de usar este chip es mediante un pequeño shield que nos permita conectarlo desde nuestros Arduinos. Originalmente diseñado por SparkFun.

ardumoto-motor-surucu-shield-600x535

Incluye dos únicos bridge, lo que nos limita a dos motores CC o a un único paso a paso, pero a cambio tenemos todo el control mediante pines directos de Arduino.

También podéis apreciar que dispone de una pequeña área de pruebas y prototipos, donde podréis soldar componentes adicionales, como LEDS, Bluetooth o WIFI o cualquier otra cosa que se os pueda ocurrir.

El shield utiliza 2 pines de Arduino para controlar cada  motor. Uno regula la dirección de giro y el otro la velocidad mediante una señal PWM, lo que hacen un total de 4 pines dejando libres el resto.

ardumoto-control

El Ardumoto Shield se reserva los pines 12 y 13 para controlar la velocidad, y los pines 3 y 11, para controlar el sentido de giro de los motores A y B respectivamente.

PIN ARDUINO USO NOTAS
3 PWM Motor A Valores de 0 a 255
11 PWM Motor B Valores de 0 a 255
12 Sentido Motor A Es un Bool True / False
13 Sentido Motor B Es un Bool True / False

En el lado izquierdo de Ardumoto se pueden ver las conexiones para los motores A y B, así como un conector para alimentar los motores independientemente de la alimentación de Arduino.

Ardumoto_Shield_Hookup_Guide1

No tiene demasiada importancia en qué orden conectáis los cables de los motores, siempre y cuando lo tengáis claro. Os recomiendo que os fijéis en los colores de los cables y conectéis ambos pares de igual modo para evitar sorpresas.

Fijaros también, que a los laterales de donde conectamos los motores hay un par de LEDs de colores que indican el estado del motor y su sentido de giro.

El programa

El shield Ardumoto usa simplemente los pines de control que se muestra en la tabla de más arriba, por lo que no requiere ninguna librería especial para mover los motores sino que usamos Arduino y sus pines para controlar el L298N y por tanto la velocidad y sentido de los motores conectados.

El programa que nos presenta SparkFun es de lo más sencillo y lo vamos a usar como ejemplo de control. Empezamos con algunas definiciones:

#define CW  0     //Sentido 1
#define CCW 1     //Sentido 2

#define MOTOR_A 0
#define MOTOR_B 1

const byte PWMA = 3; //control velocidad motor A
const byte PWMB =11; //control velocidad motor B
const byte DIRA =12; //Dirección motor A
const byte DIRB =13; //Direction motor B

Y ahora vamos a definir un par de funciones sencillas. La primera la usaremos para arrancar uno de los motores con un sentido y velocidad dados:

void accionMotor(byte motor, byte dir, byte spd){        if (motor == MOTOR_A){
   digitalWrite(DIRA, dir);
   analogWrite(PWMA, spd);
  }
  else if (motor == MOTOR_B){
            digitalWrite(DIRB, dir);
            analogWrite(PWMB, spd);
       }
}

Y la segunda es aún más sencilla, para parar un motor:

void stopMotor(byte motor){
  accionMotor(motor, 0, 0); }

Y como tenemos que programar los pines, porque no tenemos una librería que nos haga el trabajo sucio, podemos definir una función que lo haga:

void setupArdumoto()
   {    pinMode(PWMA, OUTPUT);
        pinMode(PWMB, OUTPUT);
        pinMode(DIRA, OUTPUT);
        pinMode(DIRB, OUTPUT);

        digitalWrite(PWMA, LOW);
        digitalWrite(PWMB, LOW);
        digitalWrite(DIRA, LOW);
        digitalWrite(DIRB, LOW);
   }

EL resto del programa tiene poco mérito. Básicamente vamos llamando a accionMotor() para hacer girar los motores en diferente sentido y con distinta velocidad.

No pretende ser más que un pequeño ejemplo de como se puede realizar el control de los motores conectados al Ardumoto Shield.

void loop()
   {  
     // Mueve Motor A, a diferentes velocidades
      accionMotor(MOTOR_A, CCW, 255); 
      delay(1000);  
      accionMotor(MOTOR_A, CW, 127);
      delay(1000);   
      stopMotor(MOTOR_A);  // Parar Motor A

     // Mueve Motor B a varias velocidades
     accionMotor(MOTOR_B, CCW, 255); 
     delay(1000);  
     accionMotor(MOTOR_B, CW, 127); 
     delay(1000);  
     stopMotor(MOTOR_B);  // Para Motor B

     // Ahora girar ambos motores
     accionMotor(MOTOR_A, CW, 255);  
     accionMotor(MOTOR_B, CW, 255);  
     delay(1000);  

     // Ahora retroceso a media maquina
     accionMotor(MOTOR_A, CCW, 127);  
     accionMotor(MOTOR_B, CCW, 127);  
   }

Podemos conectar un módulo de bluetooth, y poder controlar nuestro robot (coche) con una aplicación de móvil.

Conectando el módulo en los pines 2 y 4 el programa quedaría así: Ardumoto_v1.0