Control con Arduino.
PRÓLOGO.
Esta documentación, pretende ser una aproximación práctica a las formas de control de motores paso a paso, también conocidos en la terminología inglesa como, stepper’s.
En este sitio, puede encontrar un artículo que trata extensamente sobre los motores paso a paso, donde puede disipar cualquier duda sobre los mismos. En dicho documento, se hace un análisis de los tipos de motores paso a paso, su constitución, su lógica y además se presentan algunos ejemplo de uso con el puerto paralelo del PC. La característica principal de los motores paso a paso, es el hecho de poder moverlos un paso con cada impulso aplicado. Los pasos necesarios para dar un giro de 360º, depende de la constitución de cada motor, pueden variar desde 90º cada paso a 1’8 grados por pulso.
No basta con decir motor paso a paso o si me apuran motor stepper. Hay que distinguir entre dos tipos de motores paso a paso, motor bipolar y motor unipolar. En esta ocasión, vamos a abordar el tema desde la perspectiva práctica, en la que se propone, la puesta en servicio de un control para un motor paso a paso bipolar, en otro artículo abordaremos la descripción de los motores del tipo unipolar. En adelante, especificaré al tipo de motor en uso, como motor bipolar o en su caso motor unipolar.
MOTOR BIPOLAR.
Para hacer girar un motor paso a paso bipolar, se aplican impulsos en secuencia los devanados, la secuencia de estos impulsos, se aplican externamente con un controlador electrónico. Dichos controladores, se diseñan de manera que el motor se pueda mantener en una posición fija y también para que se le pueda hacer girar en ambos sentidos. Los motores bipolares, se pueden hacer avanzar a frecuencias de audio, lo que les permite girar muy velozmente. Este es el motivo por que se suele decir que un motor «canta», debido a la frecuencia a la que se produce la conmutación. Con un controlador apropiado, se les puede hacer arrancar y detenerse en cualquier instante y en una posición determinada. Este es en teoría, el esquema de un motor bipolar.
Estos motores, tienen varios bobinados que, para producir el avance de un paso, deben ser alimentados en una secuencia adecuada. Al invertir el orden de esta secuencia, se logra que el motor gire en sentido opuesto. El torque de detención, hace que un motor paso a paso (esto vale para los bipolares y unipolares) se mantenga firmemente en su posición, estando alimentado aun cuando no esté girando.
Hay tres características que, son comunes a los motores paso a paso:
- Voltaje. Los motores paso a paso tienen una tensión eléctrica de trabajo. Este valor viene impreso en su carcasa o por lo menos se especifica en su hoja de datos.
- Resistencia eléctrica. La resistencia de los bobinados, esta resistencia determinará la corriente que consumirá el motor y su valor afecta la curva de torque del motor y su velocidad máxima de operación.
- Grados por paso. Generalmente, este es el factor más importante al elegir un motor paso a paso para un uso determinado. Este factor define la cantidad de grados que rotará el eje para cada paso completo. Una operación de medio-paso o semi-paso (half step) del motor duplicará la cantidad de pasos por revolución al reducir la cantidad de grados por paso.
Si adquirimos un motor paso a paso, es bastante sencillo conocer las características del motor, sin embargo, lo más común es que nos encontremos ante un motor de desguace. Cómo distinguir ante qué tipo de motor nos encontramos, el procedimiento es bastante sencillo, el primer paso es mirar en el cuerpo del motor si permanece alguna leyenda que nos pueda servir de orientación como, el fabricante, modelo, la tensión o alguna otra pista que nos indique las características más inmediatas.
Si no dispusiera de dichas indicaciones, nos centraremos en los cables de alimentación (descartamos los de dos cables que, corresponden a motores de corriente continua), generalmente presentan cuatro, cinco o seis cables de salida. Nos referiremos a los de cuatro cables, estos, para controlarlos necesitan de ciertos trucos, debido a que requieren del cambio de dirección del flujo de corriente a través de las bobinas en la secuencia apropiada para lograr avanzar un paso en su movimiento.
Estos motores, podemos obtenerlos al desguazar una vieja impresora, los podemos encontrar en la vieja unidad de disquete y son relativamente fáciles de controlar, son de imán permanente. Existen dos tipos de motores paso a paso: unipolares y bipolares. En los unipolares la corriente circula siempre en el mismo sentido en cada bobina, en los bipolares, la corriente sigue una secuencia alterna que cambia el sentido de la intensidad.
Los cuatro cables se corresponden a los cuatro terminales, dos de cada devanado, aunque internamente pueden contener varios pares de bobinas, como se aprecia en la imagen anterior. Los motores paso a paso, difieren de los motores de CC, en la relación entre velocidad y torque o «par motor». Su mayor capacidad de torque se produce a baja velocidad.
Los motores bipolares requieren circuitos de control y de potencia más complejos que los unipolares. Estos circuitos de control, se suelen implementar con un circuito integrado que, soluciona dicha complejidad con un solo componente. Cuando se requieren mayores potencias, se deben agregar algunos componentes, como transistores y diodos para las contracorrientes, aunque esto no es del todo necesario en los pequeños motores.
La configuración de los motores bipolares requiere que las bobinas reciban corriente en ambos sentidos y no solamente un encendido-apagado como en los unipolares. Esto hace necesario el uso de un Puente H con una secuencia sobre cada uno de los devanados.
Al avanzar un paso de la secuencia al paso siguiente, hace mover el estator del motor un paso. Si vamos hacia adelante en la secuencia, el motor se mueve hacia adelante un paso y si lo hacemos al revés, el motor se mueve un paso atrás. El código que sigue, muestra la secuencia de activación de las bobinas 1a-1b y 2a-2b.
Motor Bipolar.
Utilizaremos un motor de cuatro hilos. Dos para la bobina A y dos para el B. Código sin librería.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
/* Motor paso a paso bipolar * --------------------------- * * (cleft) 2005 DojoDave for K3 * http://www.0j0.org | http://arduino.berlios.de * * @author: David Cuartielles * @date: 20 Oct. 2005 * * Es un motor paso a paso bipolar con cuatro cables: * - azul3 y naranja5 : bobina 1 * - rojo4 y amarillo6: bobina 2 * Sin usar la librería de Arduino. * * Adaptado a mis necesidades. * */ int motorPin1 = 3; // pines del Motor int motorPin2 = 5; int motorPin3 = 4; int motorPin4 = 6; int delayTime = 1; // Delay que determina la velocidad de giro void setup() { pinMode(motorPin1, OUTPUT); // Configuración de los PINes como salida digital pinMode(motorPin2, OUTPUT); pinMode(motorPin3, OUTPUT); pinMode(motorPin4, OUTPUT); } void loop() { digitalWrite(motorPin1, HIGH); // Los pines se activan en secuencia digitalWrite(motorPin2, HIGH); digitalWrite(motorPin3, LOW); digitalWrite(motorPin4, LOW); delay(delayTime); digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, HIGH); digitalWrite(motorPin3, HIGH); digitalWrite(motorPin4, LOW); delay(delayTime); digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, LOW); digitalWrite(motorPin3, HIGH); digitalWrite(motorPin4, HIGH); delay(delayTime); digitalWrite(motorPin1, HIGH); digitalWrite(motorPin2, LOW); digitalWrite(motorPin3, LOW); digitalWrite(motorPin4, HIGH); delay(delayTime); } |
RECONOCIENDO EL MOTOR.
Los motores paso a paso, también tienen un número determinado de pasos, necesarios para girar una vuelta completa. Por ejemplo, el motor que estoy usando tiene 96 pasos por revolución. En su etiqueta dice: STP-42H100 3’75 grados/paso, 4’6V y 0’55A. No obstante, si prueba a girar su motor y observa que se salta algún paso o se mueve con dificultad, deberá probar de poner un múltiplo de 4, piense que tiene 360 grados y un mínimo de 4 polos (esto serían 90º por paso, claramente muy poco), si quiere un movimiento limpio de 3º aproximadamente, serían 360/3 = 120 pasos, ahora, guardamos los 120 pasos y ya usaremos este valor en la variable adecuada del programa.
Aprovechando el Escudo que realicé en otra práctica, ahora más acabado, como puede verse en la imagen de abajo. Se pueden ver detallados los cuatro pines dispuestos para el uso de un motor bipolar, la entrada de tensión exterior con un jack adecuado junto al selector de tensión, dispuesto por un puente en amarillo y naturalmente dos conexiones independientes para aplicar a dos motores de corriente continua o en su caso a un motor bipolar con cables separados.
Uso de la librería Stepper.h
El software Arduino viene con la biblioteca <Stepper.h> que hace que sea fácil de controlar un el motor paso a paso bipolar. Un problema con esta configuración básica es que requiere cuatro cables para su control. Un Arduino sólo tiene doce pines digitales disponibles, así que, pronto nos quedaremos sin salidas. Sería agradable poder utilizar sólo dos cables para manejar un motor.
Ahora, se muestra un código que utiliza dicha librería de Arduino. Con esta librería, se generaliza el uso de los motores bipolares.
Motor Stepper DC con librería <Stepper.h>
Cuatro hilos para las bobinas y un potenciómetro para cambiar la velocidad.
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 32 33 34 35 36 37 38 39 40 41 42 43 |
/* * motor_dc_stepper.pde * */ #include <Stepper.h> int pot[10]; // nada que ver con el potenciometro // cambiar este numero por los pasos de su motor #define STEPS 196 // los pasos del motor // crea una instancia de clase stepper, especificando // el numero de steps del motor y los pines usados Stepper stepper(STEPS, 3, 4, 5, 6); // poner pines entre (2-12) // the previous reading from the analog input int previous = 0; void setup() { // set the speed of the motor stepper.setSpeed(200); Serial.begin(9600); } void loop() { // promedio de los últimos valores para suprimir el desorden long sum = 0; for (int i= 0; i<9; i ++) { pot[i]= pot[i+1]; sum = sum + pot[i]; } // get the sensor value pot[9] = (long)analogRead(2)/4; // el potenciometro en pin 2 sum = sum+(pot[9]/.64); // long diff = sum/10+pot[9] ; // sum / 100; long val = previous - diff; stepper.step(val); // remember the previous value of the sensor previous = diff; } |
En este ejemplo, se puede apreciar que, las variables responsables de valores que dependen del PWM, se declaran como long, esto tiene sentido por el valor que puede alcanzar este parámetro. En Internet se pueden encontrar muchos códigos para controlar los motores bipolares y es bueno conocer los distintos tipos de controlarlos, de modo que, en cada caso, el técnico debe aplicar el código que mejor se adapte a sus necesidades, modificando los parámetros que necesite.
EL MÉTODO DE DOS CABLES.
Sabemos que el comportamiento de un transistor en configuración de colecto abierto se puede considerar como un inversor. Este tipo de circuito es muy útil para manejar cosas, como luces o motores, en el que simplemente se convierte algo encendido a apagado, con la necesidad de proporcionar más corriente que puede dar el micro controlador. Cuando está en «on», se conecta la salida a tierra y puede pasar una corriente relativamente grande a través del transistor. Cuando se trata de «off «, la resistencia de puesta a alto (pullup) pone a alto la salida.
He mencionado que el transistor NPN es también un inversor, lo que significa que la salida es la inversa a la entrada. Si usted le da un 1, le entregará un 0 y si le da un 0, se obtendrá un 1, siempre la inversa. Pueden utilizarse transistores universales NPN como, por ejemplo BC549/C (BD139, TIP31, etc.).
Volviendo a la secuencia, si nos fijamos en la secuencia de pasos, se puede notar algo interesante. Entre los pines 1a y 1b de la tabla anterior, nunca son iguales, siempre están en contraposición.
Lo mismo ocurre con el par 2a y 2b. Por lo tanto, si utilizamos a la salida del inversor un transistor, podemos eliminar los pasos innecesarios de una entrada a cada lado.
De modo que, si utilizamos las dos salidas de Arduino como entradas del L293 y los dos transistores inversores, con sus salidas, dispondremos de las cuatro entradas necesarias para el L293, podemos eliminar pasos innecesarios de la secuencia, una entrada a cada lado. El circuito que se muestra en el siguiente esquema, presenta la aplicación de dos inversores que atacan las entradas del L293, reduciendo de esta forma las cuatro señales necesarios a sólo dos salidas de Arduino.
El esquema puede parecer muy complejo, sin embargo, si se toma un momento y sigue cada conexión, pronto comprenderá que resulta lógico y sencillo. Los dos transistores NPN están conectados como el circuito propuesto en el sitio web de Arduino. Además, utiliza los pines activados. Así que el circuito necesita cuatro pines, no hay manera de usar menos.
Por lo tanto en un boceto de Arduino, la línea para configurar de forma normal el motor bipolar se vería así:
Stepper stepper(STEPS, 3, 5, 4, 6);
Pero con el sistema descrito de dos hilos, hay que cambiar la línea de configuración de la forma siguiente:
Stepper stepper(STEPS, 3, 5);
Como se ve, el código utiliza el comando de puerto directo para reducir el tiempo de procesador. Y crear una función que se llama en el bucle principal para cada uno los pasos. De esta manera el código puede hacer otra cosa cuando el motor está en marcha.
Y eso es todo lo que tiene que cambiar, el código funciona de la misma forma. Sin embargo hemos ahorrado dos salidas del Arduino. Concretando, utilizaremos dos línea PWM (2, 7), más dos de control (3, 5), en lugar de cuatro más dos de control, esto nos permitirá disponer de más pines E/S, esto es muy importante.
El código que sigue, se ha probado y adaptado a las prestaciones que se describen en este documento. Dicho código, permite utilizar un menor número de pines del Arduino, así como, puede controlar dos motores de corriente continua, sin embargo, si no se dispone de los transistores que tienen el cometido de inversores, se deberá utilizar otro código, como el que se describe más adelante.
Motor bipolar con 2 hilos.
Este código al utilizar el inversor nos facilita la conexión mediante sólo dos hilos para las bobinas.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 |
/* bipolar2hilos.pde Stepper Motor Bipolar Controller con L293 by Kevin Filteau 2010-05-29 */ // Motor controller pins. #define pinMotorCtrlA 3 #define pinMotorCtrlB 5 #define pinMotorEnA 2 #define pinMotorEnB 7 // Direction constants. #define GOLEFT 0 #define GORIGHT 1 // Estado Motor y posición. boolean motorRunning = false; int motorMax = 700; int motorPos = 0; // Configuración del motor. void motorSetup() { pinMode(pinMotorCtrlA, OUTPUT); pinMode(pinMotorCtrlB, OUTPUT); pinMode(pinMotorEnA, OUTPUT); pinMode(pinMotorEnB, OUTPUT); // Todo a LOW. digitalWrite(pinMotorCtrlA, LOW); digitalWrite(pinMotorCtrlB, LOW); digitalWrite(pinMotorEnA, LOW); digitalWrite(pinMotorEnB, LOW); } // Libera el motor. void motorFree() { digitalWrite(pinMotorEnA, LOW); digitalWrite(pinMotorEnB, LOW); } // Hace girar el motor un paso en la dirección especificada. // Pines 7532 ---- // Binary 0000 0000 void motorSpin(boolean dir) { static int pos = 0; // Starting step pos. int stepsSeq[] = {0xC0,0x30,0x40,0x20}; // Registry value. int st; // Timing static unsigned long previousMillis; long interval = 3; if(millis() - previousMillis > interval) { previousMillis = millis(); st = stepsSeq[pos]; if( dir == GOLEFT ) { pos++; if(pos>3) pos=0; motorPos++; } else { pos--; if(pos<0) pos=3; motorPos--; } PORTD &= 0xF; PORTD |= st; } } void setup() { // main functions. motorSetup(); } void loop() { motorSpin(GOLEFT); // motorSpin(GORIGHT); } |
Este código básicamente es como el del caso anterior, la diferencia radica en que, utiliza dos salidas de Arduino y mediante dos transistores invierte dichas señales a las entradas del L293, como se ha descrito.
OTRO EJEMPLO.
En este caso, se presenta un código, que no utiliza la librería Stepper.h. En este ejemplo, he incorporado un potenciómetro mediante el cual se puede variar la velocidad, consigo una velocidad continua sin saltarme ningún paso, cosa frecuente hasta lograr las condiciones adecuadas.
Bipolar Stepper.
En este ejemplo nos servimos de dos pulsadores para cambiar la dirección de giro.
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 |
/* bipolar4.pde Control de motor bipolar, con cuatro salidas, dispone de un pulsador para cambiar la direccion de giro. Con un pot se varía la velocidad de giro. Un LED nos indica el cambio de dirección. Autor: V. Garca 15.05.2011 compilado con Arduino v.13: 2992 bytes */ int motorPin1 = 3; //Digital pin 4 int motorPin2 = 5; //Digital pin 5 int motorPin3 = 4; //Digital pin 6 int motorPin4 = 6; //Digital pin 7 int pinE1 = 2; int pinE2 = 7; int switchPin = 12; // pin del switch int switchState = 0; // estado del switch int analogPin0=0; // pin del pot int val=0; int delayTime = 0; int outPin = 13; // indicador estado. int estado = 0; // estado actual del pin de salida int previo = 0; // lectura anterior del pinX de entrada int reading; // lectura actual del pin de entrada long time = 0; // la ultima vez que el pin de salida fue basculado long debounce = 500; // el tiempo de rebote, aumenta si la salida parpadea void setup() { pinMode(motorPin1, OUTPUT); pinMode(motorPin2, OUTPUT); pinMode(motorPin3, OUTPUT); pinMode(motorPin4, OUTPUT); digitalWrite(pinE1, HIGH); digitalWrite(pinE2, HIGH); pinMode(analogPin0, INPUT); // get input from variable Resister. pinMode(outPin, OUTPUT); pinMode(switchPin, INPUT); // set the switch pin to be an input digitalWrite(switchPin, HIGH); // activa RPA Serial.begin(9600); // activa comunicaciones serie, para depurar } void loop() { int val=analogRead(analogPin0)/16; // El pot se conecta al pin0 analog. val=map(val,0,1023,0,500); // set delayTime value between 0-500 delayTime=val; switchState = digitalRead(switchPin); // si la entrada va de BAJO a ALTO y esperamos bastante tiempo ningún // ruido afectará al circuito, el pin de salida bascula y recuerda desde cuando if (switchState == HIGH && previo == LOW && millis()+100 - time > debounce) { if (estado == HIGH) { estado = LOW; time = millis(); } else { estado = HIGH; time = millis(); } } digitalWrite(outPin, estado); previo = switchState; if (estado == LOW) avanza(); else retrocede(); } void avanza(){ digitalWrite(motorPin1, HIGH); digitalWrite(motorPin2, HIGH); digitalWrite(motorPin3, LOW); digitalWrite(motorPin4, LOW); delay(delayTime); digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, HIGH); digitalWrite(motorPin3, HIGH); digitalWrite(motorPin4, LOW); delay(delayTime); digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, LOW); digitalWrite(motorPin3, HIGH); digitalWrite(motorPin4, HIGH); delay(delayTime); digitalWrite(motorPin1, HIGH); digitalWrite(motorPin2, LOW); digitalWrite(motorPin3, LOW); digitalWrite(motorPin4, HIGH); delay(delayTime); } void retrocede(){ digitalWrite(motorPin1, HIGH); digitalWrite(motorPin2, LOW); digitalWrite(motorPin3, LOW); digitalWrite(motorPin4, HIGH); delay(delayTime); digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, LOW); digitalWrite(motorPin3, HIGH); digitalWrite(motorPin4, HIGH); delay(delayTime); digitalWrite(motorPin1, LOW); digitalWrite(motorPin2, HIGH); digitalWrite(motorPin3, HIGH); digitalWrite(motorPin4, LOW); delay(delayTime); digitalWrite(motorPin1, HIGH); digitalWrite(motorPin2, HIGH); digitalWrite(motorPin3, LOW); digitalWrite(motorPin4, LOW); delay(delayTime); } |
Nótese que dentro del bucle (loop), se lee el estado del potenciómetro y se utiliza el mapa tipo, para modificar los PWM y suavizar el cambio de velocidad. Así mismo, he intercalado la lectura del estado del pulsador que, nos permite cambiar la dirección de giro, incluso respetando la velocidad anterior sin necesidad de poner a cero, naturalmente esto tiene mucho que ver con la inercia del motor que se utilice. El código empleado, recomendado por los fabricantes, es decir, paso completo que activa dos bobinas al tiempo, esto infiere un alto par motor o torque.
Eso es todo por este tutorial.