Stepper synchronisation (with AccelStepper, Robotics)

Hello my friends!
Im trying to build a 6DOF robot as im a automation engineer and work with industrial robots made by ABB.

Im using Nema 17 Stepper Motors and a arduino uno so far i have 3 working axis. Im using the AccelStepper library, even tho the MultiStepper library sounded more promising i only had massive issues with it, like just one motor spinning, them spinning endless or superfast so it would rip off the cable etc.

I did a lot of research on how i could possibly run multiple motors using AccelStepper and came up with the following code:

  while(stepper1.distanceToGo() != 0 ||
  stepper2.distanceToGo() != 0 ||
  stepper3.distanceToGo() != 0 ){

        
    if(stepper1.distanceToGo() != 0){
      stepper1.run();
    }

    if(stepper2.distanceToGo() != 0){
      stepper2.run();
    }

    if(stepper3.distanceToGo() != 0){
      stepper3.run();
    }
    
  }

This code is in a function so i could call it everytime i need to move my motors. It works really well tho my problem was that the motors just go way too fast and would never finish together on the desired position.

After some research i couldnt find anything useful and i even saw someone saying that its not possible with AccelStepper and that MultiStepper exists for that. Because of the strange problems i had with MultiStepper it wasnt a option for me.

After some hours of using a lot of brain juice i discovered a way to calculate the required acceleration for each specific motor and it works quite well, tho im not sure if its the right way.

// distance is the biggest distance one out of all motors has to travel, 
// maxSpeed is the speed the motors should travel at. 
// stepperDis is the travel distance of the current motor im trying to calculate.
// 
// the motor with the biggest distance goes full speed, the others go slower so they all stop at the same time 

float speedOnePerc = (100 / distance);
float usageSpeedPerc = speedOnePerc * stepperDis;
float stepperSpeed = (maxAccel / 100) * usageSpeedPerc;
if(stepperSpeed < 0){ stepperSpeed = (abs(stepperSpeed));  }

This is the basic calculation to get the right acceleration for the motor to end at the same time as the motor that has to travel the most.

At first i tried changing the motor speed using.setMaxSpeed with the stepperSpeed variable, tho that didnt work at all, and out of curiousity i tried changing the stepper acceleration instead to see what would happen, and all of the sudden it worked.

Because i couldnt find any actual solution to the problems i described i thought i'd share my experience and code.

Im telling the steppers how many degrees they have to turn because i couldnt figure out a way to do the IK yet

1 Like

thanks for sharing

note that you can simplify your while loop

while( stepper1.distanceToGo() != 0 ||
       stepper2.distanceToGo() != 0 ||
       stepper3.distanceToGo() != 0 )   {

  stepper1.run();
  stepper2.run();
  stepper3.run();   
}

as once one of the stepper has arrived (distance to go is null) calling run won't do anything


to your issue, you could also not use acceleration / deceleration and move at constant speed

oh thank you a lot i didnt know that but now that i think of it it kinda makes sense.

About the acceleration things i tried a lot even the plain example codes but it just never worked properly.

Since i also wanna build my robot as close to the once we have at work acceleration is an actual setting there too if you have to handle fragile stuff or if you use a vacuum gripper like we do.

Still many thanks tho!

I edited the following line to use maxAccel / 100 as maxSpeed / 100 was a mistake and wouldnt sync the motors properly. now its fixed

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.