Controlando motores de paso a paso con la Raspberry Pi

Publicado .

Los motores de paso a paso nos permiten controlar con precisión el giro y posición de un motor. Para este tutorial se utilizará el motor 28BYJ-48 junto al módulo controlador ULN2003, estos serán controlados por una Raspberry Pi. El motor 28BYJ-48 es un motor de 4 fases en el que se requieren de 512 pasos para que éste de una vuelta. El chip ULN2003 nos permite controlar fácilmente el motor ya que sólo se necesita de 4 pines activados en un orden específico, suele venir incorporado en un módulo que facilita su conexión. Existen 3 tipos de secuencia válidas para este

Paso simple: Consiste en activar uno a uno los pines del módulo y por cada repetición se dará un paso en el motor. No se recomienda del todo ya que el motor tiene menos fuerza que con el paso doble.

Paso doble: Activa los pines en pares consecutivos, es el recomendado para los motores de 4 fases ya que genera buen torque y permite un movimiento rápido del motor.

Medio paso: Activa los pines en medios pasos, recomendado para tener mayor precisión en el movimiento, aunque es un poco más lento tiene todavía mejor torque que el modo anterior.

Conecta el motor al módulo controlador, también las entradas 1-4 del módulo a los puertos GPIO deseados de la Raspberry Pi, en este caso se utilizan los puertos 12, 16, 20, y 21 conectados a las entradas 1, 2, 3 y 4 correspondientemente del módulo controlador. Alimenta al módulo con la salida de 5V de la RPi, este motor consume poco poder pero si lo deseas puedes conectarle una fuente externa. Se puede cambiar el motor a uno más potente siempre y cuando sea de 4 fases (5 cables) también y se alimente con el voltaje adecuado.

Vamos a crear una clase en Python que nos facilite el control del motor, esta clase recibe como argumentos el número de los 4 puertos GPIO a los que conectamos el módulo. La clase hace uso del método de paso doble, el movimiento será fluido y con fuerza.

import time
import RPi.GPIO as GPIO
GPIO.setmode(GPIO.BCM)

class StepperMotor:
	def __init__(self, in1, in2, in3, in4):
		self.p1 = in1
		self.p2 = in2
		self.p3 = in3
		self.p4 = in4
		self.delay = 0.004
		GPIO.setup(in1, GPIO.OUT)
		GPIO.setup(in2, GPIO.OUT)
		GPIO.setup(in3, GPIO.OUT)
		GPIO.setup(in4, GPIO.OUT)
	def stepForward(self):
		GPIO.output(self.p1, True)
		GPIO.output(self.p2, True)
		GPIO.output(self.p3, False)
		GPIO.output(self.p4, False)
		time.sleep(self.delay)
		GPIO.output(self.p1, False)
		GPIO.output(self.p2, True)
		GPIO.output(self.p3, True)
		GPIO.output(self.p4, False)
		time.sleep(self.delay)
		GPIO.output(self.p1, False)
		GPIO.output(self.p2, False)
		GPIO.output(self.p3, True)
		GPIO.output(self.p4, True)
		time.sleep(self.delay)
		GPIO.output(self.p1, True)
		GPIO.output(self.p2, False)
		GPIO.output(self.p3, False)
		GPIO.output(self.p4, True)
		time.sleep(self.delay)
	def stepBackward(self):
		GPIO.output(self.p1, True)
		GPIO.output(self.p2, False)
		GPIO.output(self.p3, False)
		GPIO.output(self.p4, True)
		time.sleep(self.delay)
		GPIO.output(self.p1, False)
		GPIO.output(self.p2, False)
		GPIO.output(self.p3, True)
		GPIO.output(self.p4, True)
		time.sleep(self.delay)
		GPIO.output(self.p1, False)
		GPIO.output(self.p2, True)
		GPIO.output(self.p3, True)
		GPIO.output(self.p4, False)
		time.sleep(self.delay)
		GPIO.output(self.p1, True)
		GPIO.output(self.p2, True)
		GPIO.output(self.p3, False)
		GPIO.output(self.p4, False)
		time.sleep(self.delay)
	def goForward(self, steps=1):
		for i in range(steps):
			self.stepForward()
		self.off()
	def goBackwards(self, steps=1):
		for i in range(steps):
			self.stepBackward()
		self.off()
	def off(self):
		GPIO.output(self.p1, False)
		GPIO.output(self.p2, False)
		GPIO.output(self.p3, False)
		GPIO.output(self.p4, False)

Para utilizar la clase la instanciamos y hacemos uso de los métodos goForward(pasos) y goBackwards(pasos) para controlarlo.

motor = StepperMotor(12,16,20,21)
# Avanza 100 pasos a la derecha
motor.goForward(100)
# Retrocede 150 pasos
motor.goBackwards(150)
# Limpiamos puertos
GPIO.cleanup()

Es posible instanciar más de un motor y controlar los dos motores fácilmente:

motor1 = StepperMotor(12,16,20,21)
motor2 = StepperMotor(6,13,19,26)
motor1.goForward(350)
motor2.goBackwards(230)

Puedes visitar este repositorio en GitHub para acceder a una versión más completa de la clase, en el que se soportan los tres modos de control, además se puede ajustar la velocidad. Ejecuta los siguientes comandos en tu Raspberry Pi para descargar los archivos del repositorio automáticamente:

cd ~
git init pruebas_python
cd pruebas_python
git remote add -f origin https://github.com/intelidomo/rpi_snippets
git config core.sparseCheckout true
echo "stepper_motor" >> .git/info/sparse-checkout
git pull origin master
rm -R -f .git #opcional, elimina archivos de git

Esto creará un directorio llamado pruebas_python en tu directorio home del usuario pi, dentro se descargarán los archivos correspondientes a la clase que controla el motor. Así como está conectado el motor en el ejercicio anterior así se utiliza en los archivos de ejemplo que acompañan a la clase. Ejecuta:

cd ~/pruebas_python/stepper_motor
sudo python example1.py
sudo python example2.py
sudo python example3.py

Nota el movimiento del motor y el código fuente de los archivos, así de cómo varía su movimiento y velocidad según se cambia el modo de movimiento y retraso.

Más tutoriales