Librería AccelStepper
Es momento de dar un salto de nivel en el control de motores paso a paso con nuestro driver L298N que ya hemos utilizado en el tutorial anterior.
Si sabemos como controlar un motor de pasos, con la librería Stepper, nos habremos fijado que es demasiado simplificado para toda la teoría contenida en el control de motores. Es bastante posible que encontremos muchas otras librerías publicadas (oficiales y no oficiales ) que pueden extender el control de nuestros modelos robóticos.
Repaso de conexión de motores paso a paso
Para poder conectar correctamente los motores paso a paso, vamos a seguir el siguiente esquema. Si queremos saber más en profundidad podéis acceder a los tutoriales anteriores. Por ahora es suficiente con seguir este esquema.
Ecuaciones de movimiento
Si ya hemos realizado algún programa con la librería Stepper, podemos realizar facilmente un control de posición y si utilizamos el método setSpeed() definiremos un parámetro al cual fijamos la velocidad para que permanezca constante.
De esta manera tendremos un movimiento rectilineo uniforme, gobernada por la ecuación:
x = vt
Pero si podemos controlar la posición en todo momento, podemos crear otros comportamientos más complejos.
En la primera imagen, tendriamos un comportamiento a velocidad constante, mientras que en la segunda imagen tendríamos un movimiento con aceleración constante sin perder ese control de posición. Esta opción nos permite realizar movimientos más suaves y fluidos para ejecutar en nuestro sistema y que es mucho más conveniente.
x = v*t + (a*t^2)/2
v = a*t
Para cualquier proyecto de robótica, en el control de motores es preciso profundizar en las ecuaciones que gobiernan el movimiento de nuestro sistema.
Librería AccelStepper
La librería AccelStepper es una librería que nos permitirá realizar este segundo modelo en el que añadimos una componente de control de velocidad y aceleración.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #include <AccelStepper.h> AccelStepper stepper_motor(4,5,6,9,10); void setup() { stepper_motor.setSpeed(300); stepper_motor.setAcceleration(100); stepper_motor.setMaxSpeed(600); stepper_motor.moveTo(1000); } void loop() { stepper_motor.run(); } |
Métodos librería AccelStepper
Para ejecutar los movimientos, estos métodos serán suficientes para hacer funcionar nuestros motores paso a paso.
- moveTo ( position ) – Definir el movimiento del motor hasta una posición en una referencia absoluta.
- move( steps ) – Definir el movimiento del motor hasta una posición en una referencia relativa.
- run() – Actualización y ejecución del movimiento en cada iteración del bucle.
- stop() – Parada del motor.
Mientras se ejecuta el movimiento podemos obtener información del sistema durante su transcurso con los siguientes métodos.
- currentPosition() – posición absoluta en la que se encuentra el sistema actualmente.
- targetPosition() – posición objetivo.
- speed() – Velocidad actual del sistema.
- distanceToGo() – Distancia o diferencia entre la posición objetivo y la posición actual
Antes de definir el movimiento o si quisieramos modificarlo, podemos establecer otros parámetros como:
- setMaxSpeed( vel ) – Velocidad máxima. El sistema no superará este valor de velocidad en ningún momento. Velocidades mayores de 1000 son impredecibles. [ steps/s ]
- setAcceleration( acc ) – Aceleración del sistema en [ steps/s^2 ]
- setSpeed( vel ) – Velocidad del sistema [ steps/s ]
Constructor AccelStepper
El constructor de nuestro motor paso a paso, debe estar definido de la siguiente manera.
AccelStepper( pins = 4, pin1 , pin2 , pin3 , pin4 );
El primer parámetro pins soporta varios tipos de motor, aunque en principio usaremos el modelo de motor bipolar con control con 4 cables.
En algunos casos es importante definir el orden de los pines con el siguiente formato. IN1-IN3-IN2-IN4
Control Serial
En el programa anterior tenemos un control que solamente se inicia en el setup al inicio del programa, pero nuestro interés es el de ejecutar el movimiento durante el bucle atendiendo a los eventos que pudieran ocurrir.
Referencia absoluta o referencia relativa
Podemos definir con el método moveTo() como un valor absoluto, en el que evolucionaremos desde un valor 0 al iniciar la placa y que ejecutará la posición desde dicha referencia.
Con el método move(), podemos elegir un movimiento relativo con un número de pasos respecto a la referencia de posición anterior.
El método run() es el método que calcula el siguiente valor de pasos a una velocidad determinada con la aceleración definida al comienzo del programa. Por lo que tenemos que cambiar el modo de ejecutar un movimiento que se define en un momento puntual, como un movimiento que evoluciona con el tiempo en cada iteración del bucle.
En el siguiente programa vamos a controlar el movimiento a través del puerto serie enviando un carácter para mover el motor seguido del número de pasos que queremos desarrollar.
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 | #include <AccelStepper.h> char serialData; AccelStepper stepper_motor(4,5,6,9,10); void setup() { Serial.begin(9600); serialData = ( char )(( '0' )); stepper_motor.setSpeed(300); stepper_motor.setAcceleration(100); stepper_motor.setMaxSpeed(600); } void loop() { if (Serial.available()) { serialData = (Serial.read()); if (serialData == ( 'A' )) { stepper_motor.moveTo(((Serial.readString()).toInt())); Serial.println((stepper_motor.targetPosition())); } if (serialData == ( 'R' )) { stepper_motor.move(((Serial.readString()).toInt())); Serial.println((stepper_motor.targetPosition())); } } stepper_motor.run(); } |
Una vez que hayamos cargado el programa, accedemos al monitor serie y podemos escribir A200 para alcanzar la posición absoluta de 200 pasos. Si queremos definir una posición relativa, podemos escribir R200 para dar una vuelta y visualizar en qué posición nos encontramos.
Gráficas de posición, velocidad y aceleración
Para entender cómo se calculan los movimientos de esta librería establecemos un modelo con aceleración al inicio y al final del movimiento. Este factor es importante a la hora de realizar movimientos suaves desde el estado parado hasta su estado en el que alcanza la velocidad constante.
Para ello, realizaremos un programa en el que visualizaremos en una gráfica esta información de posición, velocidad y aceleración.
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 | #include <AccelStepper.h> char serialData; unsigned long auxtimer; AccelStepper stepper_motor(4,5,6,9,10); void setup() { Serial.begin(9600); serialData = ( char )(( '0' )); delay(2000); stepper_motor.setSpeed(300); stepper_motor.setAcceleration(100); stepper_motor.setMaxSpeed(600); stepper_motor.moveTo(5000); } void loop() { if ( millis() - auxtimer > 100){ auxtimer = millis(); Serial.println((String(stepper_motor.currentPosition()) + String( "," ) + String(stepper_motor.speed()))); }; stepper_motor.run(); } |
Si abrimos el serial Plotter podremos observar la evolución del sistema que será muy similar a la gráfica de la imagen.
De esta manera podemos observar el comportamiento de la posición en azul y la velocidad que va aumentando hasta alcanzar una velocidad constante para disminuir al final del movimiento.
Los ejercicios de código, proyectos y recursos que desarrollaremos durante el curso se pueden consultar a través de nuestro Github.