Help - PIO - Handshaking - Simultaneous activation #9363
Replies: 2 comments 4 replies
-
I have tested another method. Using the onboard LED-pin to trigger both intial SMs and then setting my main program in a while True loop until both SMs raises an interrupt that is cleared each time the statemachines run. This almost works. Motor turns one step, both statemachines calls the irq handler and a print is made in repl but the program does not continues from here. If anyone has a better method that is quicker than using the onboard LED i am all ears. Maybe use a transistor and wait for a high on a pin? import time
from machine import Pin#, WDT
import rp2
activation_pin = Pin(25, Pin.OUT)
activation_pin.value(1)
time.sleep(1)
#SM0/SM4 - keeps track on total steps, activates pin and informs main program
@rp2.asm_pio(set_init=rp2.PIO.OUT_LOW)
def counter():
pull(block) # or maybe noblock?
mov(x, osr)
wait(1, gpio, 25) # Wait for activation from main function runner()
irq(clear, rel(0))
label("step")
jmp(not_x, "end") # If all steps are made, jump to "end"
set(pins, 1) [1]
set(pins, 0)
irq(6) # Send signal to SM_1/5
wait(0, irq, 7) # Wait for SM_1/5 to signal back
jmp(x_dec, "step")
label("end")
irq(block, rel(0))
#irq(rel(0))# Signal main program that PIO-block 0/1 is complete.
#SM1/SM5 - adds a delay of around 50 us plus the time surround instructions will take.
@rp2.asm_pio()
def pacer():
wait(1, irq, 6) # Wait for SM_0/4 from irq1
set(x, 31)
label("loop")
set(y, 31)
label("loopinloop")
jmp(y_dec, "loop")
jmp(x_dec, "loop") # x not zero, make jump.
irq(7) # Signal SM_0/4 to proceed
def handler(sm):
# Print a (wrapping) timestamp, and the state machine object.
#print(time.ticks_ms(), sm)
#motor = ("motor" ,sm)
print(sm)
## Global State machine settings
sm_freq = 1_000_000 # 1_000_000 Hz = 1 MHz means each instruction in PIO is 1us long which is optimal.
## Motor 1 - Pio Block 0
step_pin_1 = Pin(17, Pin.IN, Pin.PULL_UP)
dir_pin_1 = Pin(16, Pin.IN, Pin.PULL_UP)
sm_0 = rp2.StateMachine(0, counter, freq=sm_freq, set_base=step_pin_1)
sm_0.irq(handler)
sm_1 = rp2.StateMachine(1, pacer, freq=sm_freq)
sm_0.active(1)
sm_1.active(1)
## Motor 2 - Pio Block 1
step_pin_2 = Pin(18, Pin.IN, Pin.PULL_UP)
dir_pin_2 = Pin(19, Pin.IN, Pin.PULL_UP)
sm_4 = rp2.StateMachine(4, counter, freq=sm_freq, set_base=step_pin_2)
sm_4.irq(handler)
sm_5 = rp2.StateMachine(5, pacer, freq=sm_freq)
sm_4.active(1)
sm_5.active(1)
instruction_tuple = ((100, 50), (150, 100), (60, 120), (24, 48))
def runner(x, y): # Feeds the PIO programs and activates them.
sm_0.put(x)
sm_4.put(y)
activation_pin.value(1)
time.sleep(0.1)
activation_pin.value(0)
while True:
if sm_0.irq(counter) and sm_4.irq(counter) == True:
return
# Signal sm_0 and sm_4 to activate simultaneously
# Wait for irq from both PIO blocks before exiting function.
activation_pin.value(0)
#rp2.PIO(0).irq(lambda pio: print(pio.irq().flags()))
#rp2.PIO(1).irq(lambda pio: print(pio.irq().flags()))
while True:
for i in range(len(instruction_tuple)): # loads each item within the instruction tuple and assign to each motor.
i = i# - 1
x = instruction_tuple[i][0]
y = instruction_tuple[i][1]
print("stepping to: " + "x:" + str(x) + ", " + "y:" + str(y))
runner(x, y)
time.sleep(1)
print("Done!") |
Beta Was this translation helpful? Give feedback.
-
Yes you can have different frequencies for each state machine. As for the error: You forgot to indent the lines in the A few other observations/remarks: With your successtion of
in the control functions you introduce asynchrony because this is executed by the rather slow mPy interpreter. On the state machine side you have the blocking |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Edit
I have created a repository that does what I am asking in this thread.
Once i have been able to test with hardware that everything works i will post a solution here in this thread.
RP2040_PIO_Steppermotors
Hello. I need a huge favour from you guys and i hope someone can help me with this.
I need some help with PIO in Micropython because even if i find PIO code that i kind of understand and can manipulate to do what i want, i have big problems realizing how to make handshakes from state machine to state machine and also how to handshake to and from a PIO block. This means i am unable to make my own PIO projects.
What i need:
Some mock-up code with comments where i think the correct code is needed
Beta Was this translation helpful? Give feedback.
All reactions