asyncio help with multiple tasks #16868
-
The following code does not run, I suspect I am not creating tasks or waiting properly. When that problem is sorted I think there would be another problem if I do not cancel all the current tasks before changing direction ... near the bottom of the code. The steppers start to move ... but, why won't they run to completion? Based on this code: # line 53 - in Python, the “//” operator works as a
# floor division for integer and float arguments.
from machine import Pin, Timer
import time
import asyncio
dir_pin_1 = Pin(26, Pin.OUT, value=0)
step_pin_1 = Pin(27, Pin.OUT, value=0)
motor_power_1 = Pin(14, Pin.OUT, value=0)
dir_pin_2 = Pin(32, Pin.OUT, value=0)
step_pin_2 = Pin(33, Pin.OUT, value=0)
motor_power_2 = Pin(25, Pin.OUT, value=0)
dir_pin_3 = Pin(19, Pin.OUT, value=0)
step_pin_3 = Pin(18, Pin.OUT, value=0)
motor_power_3 = Pin(17, Pin.OUT, value=0)
position_1 = 0
position_2 = 0
position_3 = 0
tim_1 = Timer(0)
tim_2 = Timer(1)
tim_3 = Timer(2)
def step_1(t):
global step_pin_1
step_pin_1.value(not step_pin_1.value())
def step_2(t):
global step_pin_2
step_pin_2.value(not step_pin_2.value())
def step_3(t):
global step_pin_3
step_pin_3.value(not step_pin_3.value())
def rotate_motor_1(delay):
# set up timer for stepping
tim_1.init(freq=1000000//delay, mode=Timer.PERIODIC, callback=step_1)
def rotate_motor_2(delay):
# set up timer for stepping
tim_2.init(freq=1000000//delay, mode=Timer.PERIODIC, callback=step_2)
def rotate_motor_3(delay):
# set up timer for stepping
tim_3.init(freq=1000000//delay, mode=Timer.PERIODIC, callback=step_3)
async def motor_1(direction, steps_per_rev, speed):
global position_1
global dir_pin_1
dir_pin_1.value(direction)
motor_power_1.on()
rotate_motor_1(speed)
await asyncio.sleep_ms(steps_per_rev)
tim_1.deinit() # stop the timer
motor_power_1.off()
position_1 = position_1 + steps_per_rev
print(f'position_1 is {position_1}')
async def motor_2(direction, steps_per_rev, speed):
global position_2
global dir_pin_2
dir_pin_2.value(direction)
motor_power_2.on()
rotate_motor_2(speed)
await asyncio.sleep_ms(steps_per_rev)
tim_2.deinit() # stop the timer
motor_power_2.off()
position_2 = position_2 + steps_per_rev
print(f'position_2 is {position_2}')
async def motor_3(direction, steps_per_rev, speed):
global position_3
global dir_pin_3
dir_pin_3.value(direction)
motor_power_3.on()
rotate_motor_3(speed)
await asyncio.sleep_ms(steps_per_rev)
tim_3.deinit() # stop the timer
motor_power_3.off()
position_3 = position_3 + steps_per_rev
print(f'position_3 is {position_3}')
async def main():
# actual test program
direction = 1
speed = 500
steps_per_rev = 50
i = 0
j = 0
while i < 100:
i += 1
asyncio.create_task(motor_1(direction, steps_per_rev, speed))
asyncio.create_task(motor_2(direction, steps_per_rev, speed))
asyncio.create_task(motor_3(direction, steps_per_rev, speed))
# now return the steppers
# direction = 0
# while j < 100:
# j += 1
# asyncio.create_task(motor_1(direction, steps_per_rev, speed))
# asyncio.create_task(motor_2(direction, steps_per_rev, speed))
# asyncio.create_task(motor_3(direction, steps_per_rev, speed))
await asyncio.sleep_ms(1000)
asyncio.run(main()) |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 23 replies
-
What platform? What gets printed? |
Beta Was this translation helpful? Give feedback.
-
Here is my 2nd attempt. The problem I am now facing is ... task1 runs OK by itself and task 2 likewise. However, if I try to run both tasks I find that stepper 2 behaves normally ... but stepper 1 only travels about 1/2 of the distance. Do I need to do something different in the BTW, I am driving A4988 stepper modules. from machine import Pin, Timer
import time
import asyncio
dir_pin_1 = Pin(26, Pin.OUT, value=0)
step_pin_1 = Pin(27, Pin.OUT, value=0)
motor_power_1 = Pin(14, Pin.OUT, value=0)
dir_pin_2 = Pin(32, Pin.OUT, value=0)
step_pin_2 = Pin(33, Pin.OUT, value=0)
motor_power_2 = Pin(25, Pin.OUT, value=0)
position_1 = 0
position_2 = 0
tim_1 = Timer(0)
tim_2 = Timer(1)
def step_1(t):
global step_pin_1
step_pin_1.value(not step_pin_1.value())
print('stepping motor 1')
def step_2(t):
global step_pin_2
step_pin_2.value(not step_pin_2.value())
print('stepping motor 2')
def rotate_motor_1(delay):
# set up timer for stepping
tim_1.init(freq=1000000//delay, mode=Timer.PERIODIC, callback=step_1)
def rotate_motor_2(delay):
# set up timer for stepping
tim_2.init(freq=1000000//delay, mode=Timer.PERIODIC, callback=step_2)
def motor_1(direction, steps_per_rev, speed):
global position_1
global dir_pin_1
i = 0
dir_pin_1.value(direction)
motor_power_1.on()
while i < 5:
i +=1
print('running motor 1 loop')
rotate_motor_1(speed)
await asyncio.sleep_ms(steps_per_rev)
tim_1.deinit() # stop the timer
motor_power_1.off()
position_1 = position_1 + steps_per_rev
print(f'position_1 is {position_1}')
def motor_2(direction, steps_per_rev, speed):
global position_2
global dir_pin_2
j = 0
dir_pin_2.value(direction)
motor_power_2.on()
while j < 5:
j +=1
print('running motor 2 loop')
rotate_motor_2(speed)
await asyncio.sleep_ms(steps_per_rev)
tim_2.deinit() # stop the timer
motor_power_2.off()
position_2 = position_2 + steps_per_rev
print(f'position_2 is {position_2}')
async def main():
# actual test program
direction = 1
speed = 1000
steps_per_rev = 200
task1 = asyncio.create_task(motor_1(direction, steps_per_rev, speed))
task2 = asyncio.create_task(motor_2(direction, steps_per_rev, speed))
await task1
print('motor 1 done')
await task2
print('motor 2 done')
await asyncio.sleep_ms(1000)
asyncio.run(main()) |
Beta Was this translation helpful? Give feedback.
-
I used PWM to control 3 different Stepper Motors, but my solution is different. It is based on one timer, which calls a function and the function calculates the next frequency (ramp) for all 3 stepper motors. Later I could post the code. It's not complete, the calculation of ramp is wrong and the direction is missing. |
Beta Was this translation helpful? Give feedback.
You're rapidly creating 300 tasks. Is that intentional?