Skip to content

Instantly share code, notes, and snippets.

@cmouse
Created December 10, 2022 19:23
Show Gist options
  • Save cmouse/9aee30e57a2b8587c8660111ecab8da4 to your computer and use it in GitHub Desktop.
Save cmouse/9aee30e57a2b8587c8660111ecab8da4 to your computer and use it in GitHub Desktop.
Simple 4 Phase UNL 2003 Stepper Motor Driver PCB controller script for Raspberry PI
#!/usr/bin/env python
## Written by Aki Tuomi 2022
# Released into public domain with NO WARRANTY
# Written for 4 Phase UNL 2003 Stepper Motor Driver PCB
##
# To use, update INx to match your setup
# Then choose steps_4 or steps_8 as steps (4 or 8 steps)
# You can use UP and DOWN arrow to adjust speed
# LEFT and RIGHT arrow to change direction
# q to quit
from RPi import GPIO
import time
import random
from time import sleep
import curses
# Where the stepper has been connected
# Please see RPi.GPIO documentation
IN1 = 31
IN2 = 33
IN3 = 35
IN4 = 37
# channels and steps. These must match
channels = [IN1, IN2, IN3, IN4]
# If you want 8 steps, update this array
# to match the steps you want.
steps_4 = [
[1, 1, 0, 0], # AB
[0, 1, 1, 0], # BC
[0, 0, 1, 1], # CD
[1, 0, 0, 1], # DA
]
steps_8 = [
[1, 0, 0, 0], # A
[1, 1, 0, 0], # AB
[0, 1, 0, 0], # B
[0, 1, 1, 0], # BC
[0, 0, 1, 0], # C
[0, 0, 1, 1], # CD
[0, 0, 0, 1], # D
[1, 0, 0, 1], # DA
]
steps = steps_8
# Gives us 8 different speeds.
# 0.002 seems to be shortest period that works
# faster than that causes the motor to not move.
speeds = [0.1, 0.07, 0.05, 0.02, 0.01, 0.007, 0.005, 0.002]
# Initialize GPIO
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
# Setup & clear channels
GPIO.setup(channels, GPIO.OUT)
GPIO.output(channels, 0)
def do_step(state):
"""Perform single step by setting the channels
to the current step's coding"""
step = steps[state.get("step",0)]
GPIO.output(channels, step)
# Wait a bit
sleep(speeds[state["speed"]])
def go_faster(state):
"""Go faster (moves to faster speed, wraps around)"""
state["speed"] = (state["speed"] + 1) % len(speeds)
def go_slower(state):
"""Go slower, (moves tos lower speed, wraps around)"""
state["speed"] = (state["speed"] - 1) % len(speeds)
def go_cw(state):
"""Go clockwise"""
state["direction"] = "CW"
def go_ccw(state):
"""Go counter-clockwise"""
state["direction"] = "CCW"
def update_step(state):
"""Update next stepper step"""
step = state.get("step", 0)
if state["direction"] == "CW":
step = (step + 1) % len(steps)
elif state["direction"] == "CCW":
step = (step - 1) % len(steps)
state["step"] = step
def main(stdscr):
stdscr.nodelay(1)
try:
# Start going slowly clockwise
state = {
"speed": 0,
"direction": "CW"
}
while True:
c = stdscr.getch()
if c != -1:
if c == curses.KEY_UP:
go_faster(state)
elif c == curses.KEY_DOWN:
go_slower(state)
elif c == curses.KEY_LEFT:
go_ccw(state)
elif c == curses.KEY_RIGHT:
go_cw(state)
elif c == ord("q"):
break
print(f"Going {state['direction']} at {state['speed']}\r")
do_step(state)
update_step(state)
except KeyboardInterrupt:
# catch CTRL+C
pass
finally:
# Clear channels when we are leaving
GPIO.output(channels, 0)
if __name__ == "__main__":
curses.wrapper(main)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment