Hello,
I've been using CoreS3 from very recently, and I really enjoy the easyness :-).
I am currently trying to develop a 3 step motor module that is capable of accelerating / decelerating each step motor (independantly). And I am facing an issue that I cannot solve with provided modules under UIFlow2.
Let me paste my code :
import gc, time
import M5
from M5 import *
from module import StepMotorDriverModule
stepmotor = None
current_speed = 500
max_speed = 900
min_speed = 400
b_increase = True
b_direction = True
def setup():
global stepmotor
M5.begin()
gc.collect()
print("free RAM after boot:", gc.mem_free())
# ONE object only — it internally manages X, Y, Z
stepmotor = StepMotorDriverModule(
address=0x27,
step_pin=(18, 6, 13), # STEP: X, Y, Z
dir_pin=(17, 7, 0), # DIR : X, Y, Z
)
gc.collect()
print("free RAM after driver init:", gc.mem_free())
stepmotor.set_motor_state(StepMotorDriverModule.MOTOR_STATE_ENABLE) # global enable
stepmotor.set_microstep(StepMotorDriverModule.STEP_FULL) # global microstep
# Per-axis config (every call needs a motor_id)
stepmotor.set_motor_direction(StepMotorDriverModule.MOTOR_X, 1)
stepmotor.set_motor_pwm_freq(StepMotorDriverModule.MOTOR_X, 700)
stepmotor.set_motor_direction(StepMotorDriverModule.MOTOR_Y, 0)
stepmotor.set_motor_pwm_freq(StepMotorDriverModule.MOTOR_Y, 700)
stepmotor.set_motor_direction(StepMotorDriverModule.MOTOR_Z, 1)
stepmotor.set_motor_pwm_freq(StepMotorDriverModule.MOTOR_Z, 700)
# Start all three together — do this once here, NOT repeatedly in loop()
stepmotor.motor_control(StepMotorDriverModule.MOTOR_X, 0)
stepmotor.motor_control(StepMotorDriverModule.MOTOR_Y, 0)
stepmotor.motor_control(StepMotorDriverModule.MOTOR_Z, 1)
def vary_motor_speed () :
global current_speed
global max_speed
global min_speed
global b_increase
if current_speed <= max_speed and b_increase == True:
current_speed += 10
else :
b_increase = False
current_speed -= 10
if current_speed < min_speed:
b_increase = True
current_speed = min_speed
print(current_speed)
stepmotor.set_motor_pwm_freq(StepMotorDriverModule.MOTOR_Z, current_speed)
#stepmotor.set_motor_pwm_freq(StepMotorDriverModule.MOTOR_X, current_speed)
def vary_motor_direction () :
global b_direction
if b_direction == True:
b_direction = False
stepmotor.set_motor_direction(StepMotorDriverModule.MOTOR_X, 1)
stepmotor.set_motor_direction(StepMotorDriverModule.MOTOR_Y, 0)
stepmotor.set_motor_direction(StepMotorDriverModule.MOTOR_Z, 1)
else :
b_direction = True
stepmotor.set_motor_direction(StepMotorDriverModule.MOTOR_X, 0)
stepmotor.set_motor_direction(StepMotorDriverModule.MOTOR_Y, 1)
stepmotor.set_motor_direction(StepMotorDriverModule.MOTOR_Z, 0)
def loop():
global stepmotor
M5.update()
vary_motor_speed ()
#vary_motor_direction ()
time.sleep_ms(200)
if __name__ == "__main__":
try:
setup()
while True:
loop()
except (Exception, KeyboardInterrupt) as e:
from utility import print_error_msg
print_error_msg(e)
It is highly based on what can be found on the different forums and code samples. But I would like to add the acceleration phase and deceleration phase.
When I run the code as is, I have 2 motors running constant speed and one runing accelerating and decelerating. And it works :-).
But as soon as I uncomment the second stepmotor.set_motor_pwm_freq in function vary_motor_speed function, the CoreS3 hangs with an error that is :
File "module/step_motor_driver.py", line 196, in set_motor_pwm_freq
RuntimeError: out of PWM timers:4
Rebooting / Hard reset leads to same behavior.
Would anybody encountered this ?
What is a solution ?
I can elaborate if needed, but for now, I cannot see a solution.
Thanks for your time, reading and help.
Regards.
EDIT : I have found a working solution that is uninitialize the PWM each time the frequency is updated. It works. But in the Blockly approach of UIFlow2, the deinit function does not exists. Would be amazing to have unitary blocks to deinit the PWM and initialize them uniquely :-).