Acceleration and deceleration of stepper motor

Thread Starter

Hi.anshul

Joined Jan 9, 2024
5
I am using 3 stepper motors with DM542 driver to build a pick and place robot using Nucleo-F746ZG. For the movement of stepper motor I am using this library :-
Stepper motor library:
#include "stepperMotor.h"

#include "mbed.h"

int motorSpeed; // Steper speed

sMotor::sMotor(PinName A0, PinName A1, PinName A2, PinName A3) : _A0(A0), _A1(A1), _A2(A2), _A3(A3) { // Defenition of motor pins
    _A0=0;
    _A1=0;
    _A2=0;
    _A3=0;
}


void sMotor::anticlockwise() { // rotate the motor 1 step anticlockwise
    
    
     for (int i = 0; i < 8; i++) {

        switch (i) { // activate the ports A0, A2, A3, A3 in a binary sequence for steps
            case 0: {
                _A0=0;
                _A1=0;
                _A2=1;
                _A3=0;
            }
            break;
            case 1: {
           _A0=0;
         _A1=0;
         _A2=0;
       _A3=0;
            }
           break;
            case 2: {
              _A0=0;
             _A1=0;
             _A2=0;
            _A3=1;
            }
     break;
         case 3: {
               _A0=0;
                _A1=1;
                _A2=0;
               _A3=1;
           }
            break;
            case 4: {
                _A0=0;
                _A1=1;
                _A2=1;
               _A3=1;
            }
            break;
        case 5: {
                _A0=1;
                _A1=1;
             _A2=1;
                _A3=1;
            }
            break;
            case 6: {
                _A0=1;
                _A1=0;
                _A2=1;
                _A3=1;
            }
            break;
            case 7: {
                _A0=1;
                _A1=0;
                _A2=1;
               _A3=0;
            }
            break;
        }


        wait_us(motorSpeed); // wait time defines the speed
    }
}

void sMotor::clockwise() { // rotate the motor 1 step clockwise
    for (int i = 7; i >= 0; i--) {
                
        switch (i) {
         case 0: {
                _A0=0;
                _A1=0;
                _A2=0;
                _A3=1;
          }
            break;
          case 1: {
                _A0=0;
             _A1=0;
              _A2=1;
                _A3=1;
            }
            break;
         case 2: {
                _A0=0;
                _A1=0;
                _A2=1;
                _A3=0;
           }
            break;
            case 3: {
                _A0=0;
                _A1=1;
                _A2=1;
                 _A3=0;
         }
           break;
            case 4: {
                _A0=0;
                _A1=1;
                _A2=0;
                _A3=0;
            }
           break;
           case 5: {
                _A0=1;
                _A1=1;
               _A2=0;
               _A3=0;
         }
            break;
            case 6: {
                _A0=1;
                  _A1=0;
                   _A2=0;
                 _A3=0;
            }
            break;
         case 7: {
                _A0=1;
                _A1=0;
                _A2=0;
              _A3=1;
            }
            break;
        }


        wait_us(motorSpeed); // wait time defines the speed
    }
}
void sMotor::step(int num_steps, int direction, int speed) {// steper function: number of steps, direction (0- right, 1- left), speed (default 1200)
    int count=0; // initalize step count
    motorSpeed=speed; //set motor speed
    if (direction==0) // turn clockwise
        do {
            clockwise();
            count++;
        } while (count<num_steps); // turn number of steps applied
        
    else if (direction==1)// turn anticlockwise
    {
        count=0;
        do {
            anticlockwise();
            count++;
 
         } while (count<num_steps);// turn number of steps applied
   }
}
Now the problem is the arm moves with jerks in start and end (inertia) and I want to smooth the movement. For that I want to acceleration while the motor starts and deceleration when the motor stops. Kindly help me with this problem to make stepper motor move smoothly.
I tried different methods to change the speed (delay of stepper motor) but it is not working.
I am trying to get the motion as shown in this video Pick and place robot
 

Jerry-Hat-Trick

Joined Aug 31, 2022
550
I’m not sure what the library is actually doing as your code seems to include all the necessary code to drive the motor without a library is shown?

Your motor speed variable is actually the inverse of speed as it specifies the delay time between steps. How about setting the value to a high number every time the direction changes and, knowing the number of planned steps in that direction, reduce the motor speed variable by one each step for half those steps and increase it again for the second half? To set a maximum speed make the delay time a maximum speed chosen value if the delay variable is below that value.

Not an optimal curve but it works
 

Thread Starter

Hi.anshul

Joined Jan 9, 2024
5
I’m not sure what the library is actually doing as your code seems to include all the necessary code to drive the motor without a library is shown?

Your motor speed variable is actually the inverse of speed as it specifies the delay time between steps. How about setting the value to a high number every time the direction changes and, knowing the number of planned steps in that direction, reduce the motor speed variable by one each step for half those steps and increase it again for the second half? To set a maximum speed make the delay time a maximum speed chosen value if the delay variable is below that value.

Not an optimal curve but it works
I already tried this logic but the motion doesn't feel smooth, still jerks are there.
 

BobTPH

Joined Jun 5, 2013
8,922
If course it can. As already stated it uses an acceleration curve rather than constant acceleration. It is still done by controlling the acceleration. Simple constant acceleration is the first order approximation to this. The slower you accelerate, the smoother it will look.

What do you think it uses, magic?
 

Papabravo

Joined Feb 24, 2006
21,220
Smooth acceleration and deceleration also avoids the mechanical and electrical resonances that are prevalent in stepper motor systems. On an engraving machine I designed and built in the mid 1980's I used a velocity profile with 25 discreet steps to ramp up and down from maximum speed on two axes. Mistakes on a silver anniversary tray can be quite expensive.
 

Jerry-Hat-Trick

Joined Aug 31, 2022
550
I'm wondering if your step sequence is causing issues?

It looks like:
0 0010
1 0000
2 0001
3 0101
4 0111
5 1111
6 1011
7 1010
which doesn't seem right - maybe the motor is confused too!

A typical sequence would be:
1704811685514.jpeg
Also, whilst the loop from 0 to 7 with choices made according to "case" is okay, how about storing the states in a table array and use a loop which steps in increments of 4 and drives the coils according to the array numbers? Or a 2 dimensional array?
 

Sensacell

Joined Jun 19, 2012
3,441
Generating the signals to run a stepper motor in a super smooth, optimized manner is beyond the idea of just a "code library" running on a microcontroller.

Why are there chipsets designed do do this?

https://www.novaelec.co.jp/eng/MCX514_e.html
https://www.analog.com/en/products/tmc5160.html

Because it requires a complex integration of hardware and software to perform this task.
The simple code libraries people use to control stepper motors with an Arduino are very crude approximations, and will never perform to the level you see in that video.
 

Thread Starter

Hi.anshul

Joined Jan 9, 2024
5
I'm wondering if your step sequence is causing issues?

It looks like:
0 0010
1 0000
2 0001
3 0101
4 0111
5 1111
6 1011
7 1010
which doesn't seem right - maybe the motor is confused too!

A typical sequence would be:
View attachment 312220
Also, whilst the loop from 0 to 7 with choices made according to "case" is okay, how about storing the states in a table array and use a loop which steps in increments of 4 and drives the coils according to the array numbers? Or a 2 dimensional array?
Can you tell me sequence for counter-clockwise?
 
Can you tell me sequence for counter-clockwise?
I think you just have to step backwards - instead of 1 to 8 go from 8 to 1 - so you don't need to save another array, just have the loop step down.

One further thought. You'll be aware that stepper motors can slip if you try to turn them too quickly which is why you put a delay between steps, but if you accelerate and decelerate smoothly you can go faster without losing steps. In your three axis system, the rate at which you can accelerate and decelerate each axis without losing steps depends on the position of the other axes - for example, in the video clip you showed, when the arm is at full stretch you would not be able to accelerate and decelerate the vertical axis so quickly as when the arm is pulled inwards. Fine tuning, but if you are looking for optimisation of speed this makes a difference.
 
Top