I am working with two NEMA 42 stepper motors. These motors generate high torque and they are under high load. I am using Accelstepper library to control these motors. When I use .stop(), the motors stop immediately, which is good, but the stop is not smooth and I can hear a loud bump sound. When I want to start them again (after the .stop() command), the same bump sound is heard.
I tried using .runToPosition() after the .stop() command. That made the stops smoother but the problem is that the .runToPosition() is a blocking code and creates other issues in the other parts of the code.
I also used the following code after .stop():
.run();
if (.distanceToGo() == 0)
{
.stop();
}
this trick also makes the stop smooth and it is not blocking, however it is not reliable and sometimes the motors do not stop.
I also lowered the acceleration. The problem is that if the motor is rotating CW and I use .stop(), then if I want to start the motor to run in CCW, because of low acceleration and the high load torque on the motor, it can't rotate in CCW and it rotates in CW. So I need to use high acceleration to fix this issue, which again creates non-smooth start-stops.
Anyone has an idea how to fix this start-stop problem?
You would have to set a new target position a certain distance ahead of the current position to give enough time to decelerate the motor (and load) without missing steps. That distance would vary with the current running speed, NOT easy, but COULD be done (not by ME ). Maybe you could address your problem to one Mr. Mike McCauley, the program writer.
I believe you should keep calling run() after the call to stop() so the motor can continue through the deceleration period. The stop() function just sets a new target.
Robin2:
I believe you should keep calling run() after the call to stop() so the motor can continue through the deceleration period. The stop() function just sets a new target.
...R
I did this but sometimes it does not stop the motor. This approach was effective but not reliable.
JCA34F:
You would have to set a new target position a certain distance ahead of the current position to give enough time to decelerate the motor (and load) without missing steps.
That is exactly what .stop() does.
To make the stop smooth, after calling .stop(), keep calling .run() until .distanceToGo() == 0
On the 8bit Uno/Nano I found that in order to have responsive steppers
you have to keep the code that is running while the steppers are running to a bare minimum.
So this is how my loop() was set up:
void loop()
{
if (myStepper.run()) // Returns true if it hasn't yet reached the target position.
{
if ((digitalRead(stopButton)) == PUSHED) // no need to debounce
{
myStepper.stop(); // Slows to a stop according to acceleration
}
// Absolute minimum amount of code necessary while steppers are running goes here
}
else // The stepper is not running
{
// All other code goes here
}
} // End Loop()
If you try to do to much while the steppers are running you will have these kinds of issues.
I thought about trying to put .run inside a timer interrupt but then I got a 32 bit MKR board and Ooh butter!