Hola controleros y controleras, en esta entrada aprenderemos a programar un motor paso a paso unipolar o bipolar en MicroPython y para eso usaremos la poderosa Raspberry Pi Pico o también el NodeMCU8266.
Antes de comenzar, te hago la invitación que aprendas a programar microcontroladores con nuestro Curso Gratuito de MicroPython.

Y que te suscríbas al canal si te interesa la programación de microcontroladores o la teoría del control.
Motores Paso a Paso
Un stepper motor o motor paso a paso es un dispositivo electrónico que realiza movimientos muy precisos realizando movimientos en pequeños ángulos y por pasos en diferentes direcciones.
Aquí en el sitio web y en el canal de YouTube ya explicamos en detalles el funcionamiento interno de un motor paso a paso, y sus diferentes tipos. Si estás interesado en profundizar en esto, puedes ver nuestro tutorial de Motores Paso a Paso con Arduino, o si te interesa el microchip, puedes ver nuestra entrada de motores paso a paso con Pic.
Tipos de Motores Paso a Paso
Dos tipos de motores paso a paso son vendidos en el mercado: El motor Bipolar (Bi-stepper) y el motor unipolar. Sus configuraciones de bobinas vienen dados por:

A continuación puedes ver el siguiente video para que aprendas a reconocer cada una de las bobinas del motor paso a paso que tienes.
Diferencia en la conexión del Motor PaP Unipolar y Bipolar

Movimiento del Motor Paso a Paso con MicroPython
Para darle movimientos a nuestro motor paso a paso en nuestro microcontrolador basado en el chip RP2040 de la Raspberry Pi Pico o en el NodeMCU ESP8266 usando Micropython, debemos configurar una de las siguientes secuencias:
Secuencia a 1 Fase
Encendemos únicamente una bobina por vez siguiendo la siguiente tabla de verdad.
| Paso | In1 | In2 | In3 | In4 |
| 1 | ON | OFF | OFF | OFF |
| 2 | OFF | ON | OFF | OFF |
| 3 | OFF | OFF | ON | OFF |
| 4 | OFF | OFF | OFF | ON |

Secuencia a 2 pasos
En esta secuencia encendemos de a 2 bobinas para aumentar el Par del motor
| Paso | In1 | In2 | In3 | In4 |
| 1 | ON | ON | OFF | OFF |
| 2 | OFF | ON | ON | OFF |
| 3 | OFF | OFF | ON | ON |
| 4 | ON | OFF | OFF | ON |

Secuencia a Medio Paso
Es una combinación de las dos secuencias anteriores donde se enciende 1 bobina intercalada con la activación de 2 bobinas, por lo tanto puede ser aplicado en aplicaciones que requieran de una mayor precisión.
| Paso | In1 | In2 | In3 | In4 |
| 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 |

Invertir giro motor paso a paso
Si deseas invertir el giro, basta con aplicar las secuencias anteriores de atrás para adelante.
Velocidad Motor Paso a Paso
Para aumentar o disminuir la velocidad del motor paso a paso, debes programar en micropython la velocidad con la cual se envia cada paso al motor.
Entre menos tiempo tomes enviando los pasos, más rápido se moverá el motor.
Ejemplo Raspberry Pi Pico / ESP8266 MicroPython
Crear un programa en arduino usando el driver UNL2003 y el Motor paso a paso 28BYJ-48 que sea capaz de detectar el cambio en 4 pulsadores. Un pulsador servirá para hacer el giro sentido horario, otro pulsador hará el giro anti horario, otro pulsador cambiará la secuencia de pasos para 1, 2 o medio paso y el ultimo pulsador modificará la velocidad del motor.
Recordemos el Pinout de la Raspberry Pi Pico y del NodeMCU8266:




from machine import Pin
import utime
def envia_pasos(paso, tipo, bobinas):
bit = 1;
for i in range(4):
if (tipo[paso] & bit) == 0:
bobinas[i].off()
else:
bobinas[i].on()
bit = bit << 1
def main():
#Define los pines de los 4 botones Raspberry Pi PICO
boton_horario = Pin(19, Pin.IN, Pin.PULL_UP)
boton_antihorario = Pin(18, Pin.IN, Pin.PULL_UP)
boton_velocidad = Pin(17, Pin.IN, Pin.PULL_UP)
boton_pasos = Pin(16, Pin.IN, Pin.PULL_UP)
#Define los pines del Motor PaP
motor_pins = (13, 12, 11, 10)
"""
#Define los pines de los 4 botones NodeMCU8266
boton_horario = Pin(5, Pin.IN, Pin.PULL_UP)
boton_antihorario = Pin(4, Pin.IN, Pin.PULL_UP)
boton_velocidad = Pin(0, Pin.IN, Pin.PULL_UP)
boton_pasos = Pin(2, Pin.IN, Pin.PULL_UP)
#Define los pines del Motor PaP
motor_pins = (14, 12, 13, 15)
"""
#Configura las GPIO como Salidas
bobinas = list()
for i in motor_pins:
bobinas.append( Pin(i, Pin.OUT) )
#Configura las secuencia de los pasos
#Secuencia a 1 paso
un_paso = ( int('1000',2),
int('0100',2),
int('0010',2),
int('0001',2) )
#Secuencia a 2 pasos
dos_pasos = ( int('1100',2),
int('0110',2),
int('0011',2),
int('1001',2) )
#Secuencia a 1/2 paso
medio_paso = ( int('1000',2),
int('1100',2),
int('0100',2),
int('0110',2),
int('0010',2),
int('0011',2),
int('0001',2),
int('1001',2) )
#variables del programa
sentido = True #True -> Horario, False -> Anti-Horario
velocidad = (5, 10, 30, 100, 500) #Velocidades
configuracion = 1 #Selecciona los pasos
contador_pasos = 0 #cuenta del paso actual
contador_velocidad = 0
cantidad_pasos = 3
while True:
#Giro en Sentido Horario
if not boton_horario.value():
utime.sleep_ms(100) #Anti-Rebote
print('Sentido horario')
sentido = True
contador_pasos = -1
#Giro en Sentido AntiHorario
if not boton_antihorario.value():
utime.sleep_ms(100) #Anti-Rebote
print('Sentido antihorario')
sentido = False
contador_pasos = cantidad_pasos
#Cambio de la secuencia de pasos
if not boton_pasos(): #Recordar que los objetos pin son invocables.
utime.sleep_ms(100) #Anti-Rebote
print('Cambio de secuencia de pasos')
#esperar hasta soltar el boton
while boton_pasos.value() == 0:
pass
utime.sleep_ms(100) #Anti-Rebote
configuracion += 1
if configuracion > 3:
configuracion = 1
if configuracion != 3 and contador_pasos > 3:
contador_pasos = contador_pasos - 4
#Cambio de la velocidad del motor
if boton_velocidad.value() == 0:
print('Cambio de velocidad')
utime.sleep_ms(100) #Anti-Rebote
#esperar hasta soltar el boton
while boton_velocidad.value() == 0:
pass
utime.sleep_ms(100) #Anti-Rebote
contador_velocidad += 1
if contador_velocidad > 4:
contador_velocidad = 0
#************************************#
#***** Logica de los Contadores ****#
#************************************#
if sentido:
contador_pasos += 1
if contador_pasos > cantidad_pasos:
contador_pasos = 0
else:
contador_pasos -= 1
if contador_pasos < 0:
contador_pasos = cantidad_pasos
#************************************#
#***** Logica de los Contadores ****#
#************************************#
if configuracion == 1:
envia_pasos(contador_pasos, un_paso, bobinas)
cantidad_pasos = 3
elif configuracion == 2:
envia_pasos(contador_pasos, dos_pasos, bobinas)
cantidad_pasos = 3
else:
envia_pasos(contador_pasos, medio_paso, bobinas)
cantidad_pasos = 7
# Velocidad
utime.sleep_ms(velocidad[contador_velocidad])
#Entry Point
if __name__ == '__main__':
main()
Eso es todo por la entrada del dia de hoy, espero les haya gustado y hayan aprendido algo nuevo. Si te ha servido el contenido de esta entrada, de los videos y los códigos de implementación y deseas apoyar mi trabajo invitandome a un café super barato, puedes hacerlo en el siguiente link:
👉 Invitar a Sergio a un Café ☕️
Que esten muy bien, nos vemos en la siguiente entrada.
Mi nombre es Sergio Andres Castaño Giraldo, y en este sitio web voy a compartir una de las cosas que mas me gusta en la vida y es sobre la Ingeniería de Control y Automatización. El sitio web estará en constante crecimiento, voy a ir publicando material sobre el asunto desde temas básicos hasta temas un poco más complejos. Suscríbete al sitio web, dale me gusta a la página en Facebook y únete al canal de youtube. Espero de corazón que la información que comparto en este sitio, te pueda ser de utilidad. Y nuevamente te doy las gracias y la bienvenida a control automático educación.






