Stepper motors with PIO
Posted: Sat Apr 03, 2021 6:24 am
Hi!
I'm trying to write my first PIO program to control stepper motors.
I'd like to be able to tell it how many steps to make and what would be a delay between steps.
After hours and hour of reading docs and watching Youtube videos I'm still not able to write a working program.
Here is what I have so far:
Here is the intention of this code:
1. Read delay between pulses and put it in x
2. Read a number of steps and put it in y
3. Have a loop "step" and iterate until y is zero with "jump(y_dec, "step")"
4. For each step set pin to HIGH and then have a waiting loop for the duration specified in x
I'm invoking an interrupt for debugging and I'm confused by the results.
If I put it inside of the "delay" loop it would just execute continuously until the state machine is stopped. I would expect it to finish after x has become 0.
If I put it inside of the "step" loop it's only executed once. I expected it to be executed 4 times because of sm.put(3)
What am I doing wrong here?
Also, is there a way to keep a copy of x so I can reset it in each "step" back to its original value after it reaches 0?
Cheers,
Leonti
I'm trying to write my first PIO program to control stepper motors.
I'd like to be able to tell it how many steps to make and what would be a delay between steps.
After hours and hour of reading docs and watching Youtube videos I'm still not able to write a working program.
Here is what I have so far:
Code: Select all
import time
import rp2
from machine import Pin
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def stepper():
pull()
mov(x, osr) # delay
pull()
mov(y, osr) # steps
label("step")
set(pins, 1)
label("delay")
set(pins, 0)
# irq(rel(0)) # <- runs continously
jmp(x_dec, "delay")
# irq(rel(0)) # <- only a single invocation
jmp(y_dec, "step")
def turn(sm):
print("irq")
# at 10_000Hz, 1 tick is 100us
sm = rp2.StateMachine(0, stepper, freq=10000, set_base=Pin(25))
sm.irq(turn)
sm.active(1)
sm.put(2)
sm.put(3)
time.sleep(1)
sm.active(0)
1. Read delay between pulses and put it in x
2. Read a number of steps and put it in y
3. Have a loop "step" and iterate until y is zero with "jump(y_dec, "step")"
4. For each step set pin to HIGH and then have a waiting loop for the duration specified in x
I'm invoking an interrupt for debugging and I'm confused by the results.
If I put it inside of the "delay" loop it would just execute continuously until the state machine is stopped. I would expect it to finish after x has become 0.
If I put it inside of the "step" loop it's only executed once. I expected it to be executed 4 times because of sm.put(3)
What am I doing wrong here?
Also, is there a way to keep a copy of x so I can reset it in each "step" back to its original value after it reaches 0?
Cheers,
Leonti