Results 1 to 15 of 15

Thread: Stepper acceleration help needed

  1. #1
    Senior Member
    loopyloo's Avatar
    Join Date
    Feb 2008
    Location
    Mid North Coast NSW . Australia
    Age
    67
    Posts
    2,207
    Thanks
    1,431
    Thanked 469 Times in 313 Posts
    Rep Power
    415
    Reputation
    7297

    Default Stepper acceleration help needed

    Just finished building a camera slider that uses 3 steppers. Slide, pan and tilt.
    It works pretty good but I need to add acceleration and deceleration to its movement. I'm not sure how to do that.
    Stepper #1 is the one I need to work on.
    If anyone can help, here is the sketch :

    #include <AccelStepper.h>
    #include <MultiStepper.h>

    #define JoyX A0 // Joystick X pin
    #define JoyY A1 // Joystick Y pin
    #define slider A2 // Slider potentiometer
    #define inOutPot A3 // In and Out speed potentiometer
    #define JoySwitch 10 // Joystick switch connected
    #define InOutSet 12 // Set Button
    #define limitSwitch 11
    #define inLED 8
    #define outLED 9

    // Define the stepper motors and the pins the will use
    AccelStepper stepper1(1, 7, 6); // (Type:driver, STEP, DIR)
    AccelStepper stepper2(1, 5, 4);
    AccelStepper stepper3(1, 3, 2);

    MultiStepper StepperControl; // Create instance of MultiStepper

    long gotoposition[3]; // An array to store the In or Out position for each stepper motor

    int JoyXPos = 0;
    int JoyYPos = 0;
    int sliderPos = 0;
    int currentSpeed = 100;
    int inOutSpeed = 100;

    int XInPoint = 0;
    int YInPoint = 0;
    int ZInPoint = 0;
    int XOutPoint = 0;
    int YOutPoint = 0;
    int ZOutPoint = 0;
    int InandOut = 0;

    void setup() {
    // Set initial seed values for the steppers
    stepper1.setMaxSpeed(3000);
    stepper1.setSpeed(200);
    stepper2.setMaxSpeed(3000);
    stepper2.setSpeed(200);
    stepper3.setMaxSpeed(3000);
    stepper3.setSpeed(200);
    pinMode(JoySwitch, INPUT_PULLUP);
    pinMode(InOutSet, INPUT_PULLUP);
    pinMode(limitSwitch, INPUT_PULLUP);
    pinMode(inLED, OUTPUT);
    pinMode(outLED, OUTPUT);

    // Create instances for MultiStepper - Adding the 3 steppers to the StepperControl instance for multi control
    StepperControl.addStepper(stepper1);
    StepperControl.addStepper(stepper2);
    StepperControl.addStepper(stepper3);

    // Move the slider to the initial position - homing
    while (digitalRead(limitSwitch) != 0) {
    stepper1.setSpeed(1000);
    stepper1.runSpeed();
    stepper1.setCurrentPosition(0); // When limit switch pressed set position to 0 steps
    }
    delay(20);
    // Move 200 steps back from the limit switch
    while (stepper1.currentPosition() != -200) {
    stepper1.setSpeed(-1000);
    stepper1.run();
    }

    }

    void loop() {
    // Limiting the movement - Do nothing if limit switch pressed or distance traveled in other direction greater then 80cm
    while (digitalRead(limitSwitch) == 0 || stepper1.currentPosition() < -64800) {}

    // If Joystick pressed increase the Pan and Tilt speeds
    if (digitalRead(JoySwitch) == 0) {
    currentSpeed = currentSpeed + 200;
    delay(200);
    }
    // If Set button is pressed - toggle between the switch cases
    if (digitalRead(InOutSet) == 0) {
    delay(1000);
    // If we hold set button pressed longer than 1 second, reset the in and out positions
    if (digitalRead(InOutSet) == 0) {
    InandOut = 4;
    }
    switch (InandOut) {
    case 0: // Set IN position
    InandOut = 1;
    XInPoint = stepper1.currentPosition(); // Set the IN position for steppers 1
    YInPoint = stepper2.currentPosition(); // Set the IN position for steppers 2
    ZInPoint = stepper3.currentPosition(); // Set the IN position for steppers 3
    digitalWrite(inLED, HIGH); // Light up inLed
    break;

    case 1: // Set OUT position
    InandOut = 2;
    XOutPoint = stepper1.currentPosition(); // Set the OUT Points for both steppers
    YOutPoint = stepper2.currentPosition();
    ZOutPoint = stepper3.currentPosition();
    digitalWrite(outLED, HIGH);
    break;

    case 2: // Move to IN position / go to case 3
    InandOut = 3;
    inOutSpeed = analogRead(inOutPot)*3; // Auto speed potentiometer
    // Place the IN position into the Array
    gotoposition[0] = XInPoint;
    gotoposition[1] = YInPoint;
    gotoposition[2] = ZInPoint;
    stepper1.setMaxSpeed(inOutSpeed);
    stepper2.setMaxSpeed(inOutSpeed);
    stepper3.setMaxSpeed(inOutSpeed);
    StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
    StepperControl.runSpeedToPosition(); // Blocks until all steppers are in position
    delay(200);
    break;

    case 3: // Move to OUT position / go back to case 2
    InandOut = 2;
    inOutSpeed = analogRead(inOutPot)*3;
    // Place the OUT position into the Array
    gotoposition[0] = XOutPoint;
    gotoposition[1] = YOutPoint;
    gotoposition[2] = ZOutPoint;
    stepper1.setMaxSpeed(inOutSpeed);
    stepper2.setMaxSpeed(inOutSpeed);
    stepper3.setMaxSpeed(inOutSpeed);
    StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
    StepperControl.runSpeedToPosition(); // Blocks until all are in position
    delay(200);
    break;

    case 4: // If Set button is held longer than 1 second go back to case 0
    InandOut = 0;
    digitalWrite(inLED, LOW);
    digitalWrite(outLED, LOW);
    delay(1000);
    break;
    }
    }

    // Joystick X - Pan movement
    JoyXPos = analogRead(JoyX);
    // if Joystick is moved left, move stepper 2 or pan to left
    if (JoyXPos > 600) {
    stepper2.setSpeed(currentSpeed);
    }
    // if Joystick is moved right, move stepper 2 or pan to right
    else if (JoyXPos < 400) {
    stepper2.setSpeed(-currentSpeed);
    }
    // if Joystick stays in middle, no movement
    else {
    stepper2.setSpeed(0);
    }

    //Joystick Y - Tilt movement
    JoyYPos = analogRead(JoyY);
    if (JoyYPos > 600) {
    stepper3.setSpeed(currentSpeed);
    }
    else if (JoyYPos < 400) {
    stepper3.setSpeed(-currentSpeed);
    }
    else {
    stepper3.setSpeed(0);
    }

    // Slider potentiometer
    sliderPos = analogRead(slider);
    // If potentiometer is turned left, move slider left
    if (sliderPos > 600) {
    sliderPos = map(sliderPos, 600, 1024, 0, 3000);
    stepper1.setSpeed(sliderPos); // Increase speed as turning
    }
    // If potentiometer is turned right, move slider right
    else if (sliderPos < 400 ) {
    sliderPos = map(sliderPos, 400, 0, 0, 3000);
    stepper1.setSpeed(-sliderPos); // Increase speed as turning
    }
    // If potentiometer in middle, no movement
    else {
    stepper1.setSpeed(0);
    }
    // Execute the above commands - run the stepper motors
    stepper1.runSpeed();
    stepper2.runSpeed();
    stepper3.runSpeed();
    }



Look Here ->
  • #2
    Senior Member
    trash's Avatar
    Join Date
    Jan 2008
    Location
    Tamworth
    Posts
    4,088
    Thanks
    148
    Thanked 3,229 Times in 1,451 Posts
    Rep Power
    1287
    Reputation
    47674

    Default

    acceleration = (final velocity - initial velocity) / time

    The simple example is gravity. lets say your camera is following a falling object. For simplicity we can say 10ms-<sup>2</sup>.
    Starting at rest 0ms-<sup>1</sup>, in 1 second the camera should be moving at 10ms-<sup>2</sup>.

    You also have the issue of angular acceleration which is a factor of pi*r. To keep that simple, convert it to linear velocity.

    Again, we can simplify velocity so you can build upon it. If we say the motor takes 1cm per step.
    1ms-<sup>1</sup> = 100cms-<sup>1</sup> = 1mm ms-<sup>2</sup>

    So to accelerate at 10ms-<sup>2</sup> you would need to 1 step in 10ms, two more steps in the next 10ms then 3 steps in the next 10ms after that.
    To accelerate at 5ms-<sup>2</sup> you would take the first step in 20ms, two more in the next 20ms.
    But that thinks of it from a step perspective which can be a little bit jerky because you can see the velocity changes in steps rather than smoothly especially if you're stepping slowly.

    You can think of it from a time perspective so that the velocity changes smoothly
    10ms-<sup>2</sup> first step at 10ms, the second step at 16ms, the third step at 20mS the fourth step at 23ms fifth at 25ms and so on.......
    Deceleration is the opposite.

    Remember how your high school maths teacher said Calculus was important and useful and then demonstrated to you how dull and boring and irrelevant it was.
    Well this is where it is useful.

    Velocity is an integral of position.
    Acceleration is an integral of velocity.
    Impulse is an integral of acceleration.

    If the position changes with time, this is a velocity
    If the velocity changes with time, this is acceleration
    If the acceleration changes with time, this is a impulse.

    The first two are easy to program onto a joystick.
    A pulse on the joystick just steps the motor in that direction.
    Holding the joystick means you want to accelerate, so increasing the stepping rate or decreasing the increment timing.

    Impulse... this is the tricky one.
    Lets assume you hold the joystick to move.....
    The motor steps once and checks the joystick position.
    If the joystick is still in position, then increase the stepping rate. (linear acceleration) This is normally what you want. But the longer you hold the joystick, the faster the velocity and you might choose to increase the acceleration (impulse).

    To decelerate.....
    You release the joystick .... but if you stop instantly, the acceleration is very high and so is the impulse because the instant change.
    Instead when you release the joystick, the velocity stays the same (no acceleration) so the motor keeps running. This might be what you want or you might want to linear decelerate the motor back to zero when the joystick is idle.

    If you want a constant velocity, then reverse joystick decelerates by reducing the stepping rate or increasing the interval.
    If you're already decelerating on idle joystick, then reverse joystick decreases the acceleration (impulse).

    start:
    if forward then (dv=dv+da)
    if reverse then (dv=dv-da)
    if idle then (dv=dv+0) goto start

    if forward or reverse then da=da+1
    if idle then da=da-1 goto start


    OR

    if forward and (forward-previous) then da=da+1
    if idle then da=0
    if reverse and (forward-previous) then da=da-1



    Sorry for my simple pseudo code... but I'm hoping that you can use it to build up the mods to your code.
    Yes I am an agent of Satan, but my duties are largely ceremonial.

  • The Following 2 Users Say Thank You to trash For This Useful Post:

    hinekadon (15-03-19),loopyloo (16-03-19)

  • #3
    Senior Member
    loopyloo's Avatar
    Join Date
    Feb 2008
    Location
    Mid North Coast NSW . Australia
    Age
    67
    Posts
    2,207
    Thanks
    1,431
    Thanked 469 Times in 313 Posts
    Rep Power
    415
    Reputation
    7297

    Default

    Ha ha Another great read from trash.
    I love it but I'd have to learn how to program arduino first. I can look at an arduino sketch and make some minor changes and see what results come from it but that's about it at the moment.
    See, this is the vid I copied from, but his runs too slow for what I want so I modded the sketch to speed up the stepper to about twice the speed. Now at high speed it misses steps, thus it needs acceleration to dampen the start.


  • The Following User Says Thank You to loopyloo For This Useful Post:

    hinekadon (16-03-19)

  • #4
    Senior Member
    trash's Avatar
    Join Date
    Jan 2008
    Location
    Tamworth
    Posts
    4,088
    Thanks
    148
    Thanked 3,229 Times in 1,451 Posts
    Rep Power
    1287
    Reputation
    47674

    Default

    Yeah, I'm not an arduino programmer, but the source code looks like C to me. It appears to be all functions which aren't visible in that code. (libraries)
    So looking closer at it.... errr.... this is the problem. You can't

    So normally I'd write code from the ground up. That's just me as an assembler programmer.
    But this code uses some libraries which do that job for you.

    #include <AccelStepper.h>
    #include <MultiStepper.h>

    You have to look at those files and reverse engineer the code that does the maths.
    I'd look for the code that actually changes the poles of the stator coils.
    Then look at how the rate of change is achieved. It'll be closely related to the "inOutSpeed" variable.

    stepper1.setSpeed(1000);
    stepper1.runSpeed();
    stepper1.setMaxSpeed(inOutSpeed)


    I've got code which I've written for PIC chips to drive stepper motors. In particular poker machine reels.
    Generally they don't have an acceleration problem because the reels are so light and I don't want to move them at any particularly fast rate.
    The issue I have is that I have to know the position of the reel so I cannot afford a slip. Any slip means the reel is not where it is supposed to be.

    But if your problem is start up torque, then that is not that hard to fix. (provided you know the code).
    Normally you might run the coils 1234123412341234. But for a slower start up, all you really need to do is 11223344123412341234.
    If I had a large inertia to get moving, I haven't ever written code for that, but I think I might consider doing something like 122223334412341234 or some larger variation of that.

    I'd say try and dig down into the code and find the bit that moves the motor just 1 step and build up from there.
    Each one of the functions appears to change the values, so if you create a value that changes how fast a function changes a value, you should be able to control the start up acceleration/speed.
    Yes I am an agent of Satan, but my duties are largely ceremonial.

  • The Following 2 Users Say Thank You to trash For This Useful Post:

    hinekadon (23-03-19),loopyloo (24-03-19)

  • #5
    Senior Member
    Uncle Fester's Avatar
    Join Date
    Jan 2008
    Location
    Commonly found in a pantry or the bottom of a fridge, searching for grains, fermented or distilled
    Posts
    6,405
    Thanks
    2,289
    Thanked 4,414 Times in 2,517 Posts
    Rep Power
    2046
    Reputation
    81778

    Default

    Quote Originally Posted by loopyloo View Post
    Ha ha Another great read from trash.
    I love it but I'd have to learn how to program arduino first. I can look at an arduino sketch and make some minor changes and see what results come from it but that's about it at the moment.
    See, this is the vid I copied from, but his runs too slow for what I want so I modded the sketch to speed up the stepper to about twice the speed. Now at high speed it misses steps, thus it needs acceleration to dampen the start.


    Can't you leave it first at the fixed slow speed and then after a short delay change to a second set speed to a higher fixed value.
    I assume this is where it happens:
    stepper1.setSpeed(1000)

    and reverse:
    stepper1.setSpeed(-1000);

    so something like:
    stepper1.setSpeed(1000);
    stepper1.run();
    delay(50);
    stepper1.setSpeed(2000);
    stepper1.run();

    Just a random stab in the dark. I have no clue how the library works and if it accepts setSpeed changes while the motor is running.
    A Delay of 50ms is just a guess as starting point.

    I am no Arduino programmer either.



    Update: A deletion of features that work well and ain't broke but are deemed outdated in order to add things that are up to date and broken.
    Compatibility: A word soon to be deleted from our dictionaries as it is outdated.
    Humans: Entities that are not only outdated but broken... AI-self-learning-update-error...terminate...terminate...

  • The Following 2 Users Say Thank You to Uncle Fester For This Useful Post:

    hinekadon (23-03-19),loopyloo (24-03-19)

  • #6
    Premium Member
    Skepticist's Avatar
    Join Date
    Apr 2009
    Posts
    1,139
    Thanks
    714
    Thanked 670 Times in 525 Posts
    Rep Power
    475
    Reputation
    12780

    Default

    I had this problem some years ago when driving a largeish stepper motor from a PIC based circuit IE hit the motor with too high a stepping rate from standstill and it just quivered going nowhere.
    What I did was use a 'target' rate and a variable extra delay between steps based on a counter that was decremented each loop so the motor could accelerate up to the target rate which worked a treat.
    Didn't use any commercial stepper circuits (all homebrew) and the software was in assembly language - not even sure where the file might be just now.
    Last edited by Skepticist; 23-03-19 at 07:47 PM. Reason: fat fingers

  • The Following User Says Thank You to Skepticist For This Useful Post:

    loopyloo (24-03-19)

  • #7
    Senior Member
    loopyloo's Avatar
    Join Date
    Feb 2008
    Location
    Mid North Coast NSW . Australia
    Age
    67
    Posts
    2,207
    Thanks
    1,431
    Thanked 469 Times in 313 Posts
    Rep Power
    415
    Reputation
    7297

    Default

    I joined up and put the same question on Arduino.cc .... It was a lot of fun and games trying to get answers out of those guys, and with little results. I did however find a few interesting things about acceleration etc in other places and put them on the forum.
    Here's the link : I dunno if you can see it without joining.

    You might as well have a look at the slider while you're here
    The harness might look messy but it's actually plaited for max flexibility. The blue and grey plastic parts and the control box were cad drawn and 3D printed by myself.







    Last edited by loopyloo; 24-03-19 at 06:44 PM.

  • The Following 2 Users Say Thank You to loopyloo For This Useful Post:

    Skepticist (24-03-19),tristen (24-03-19)

  • #8
    Premium Member
    Skepticist's Avatar
    Join Date
    Apr 2009
    Posts
    1,139
    Thanks
    714
    Thanked 670 Times in 525 Posts
    Rep Power
    475
    Reputation
    12780

    Default

    Compared to some my gadgets, that's a work of art

  • The Following User Says Thank You to Skepticist For This Useful Post:

    loopyloo (24-03-19)

  • #9
    Senior Member
    trash's Avatar
    Join Date
    Jan 2008
    Location
    Tamworth
    Posts
    4,088
    Thanks
    148
    Thanked 3,229 Times in 1,451 Posts
    Rep Power
    1287
    Reputation
    47674

    Default

    Quote Originally Posted by nomeat View Post
    so something like:
    stepper1.setSpeed(1000);
    stepper1.run();
    delay(50);

    stepper1.setSpeed(2000);
    stepper1.run();
    Yep, you've either got to manipulate those functions.
    .....setSpeed(500); or .setSpeed(2000); wonder if that is faster or slower? Normally I'd guess larger numbers are slower (milliseconds)

    delay(50); is clearly milliseconds, so starting with a 250mS delay and reducing that to 200, 150, 100, 50 after a number of steps should be all that you really
    need to do.


    I'm thinking you probably don't want to play with the library files, but it they might give you some clues as to the best way to manipulate them for a smooth acceleration.

    Like ....
    speed(100);
    delay(100);
    speed(250);
    delay(100);
    speed(500);
    delay(100);
    speed(1000);

    So that would take 300mS to come up to speed.
    Yes I am an agent of Satan, but my duties are largely ceremonial.

  • The Following User Says Thank You to trash For This Useful Post:

    loopyloo (24-03-19)

  • #10
    Senior Member
    loopyloo's Avatar
    Join Date
    Feb 2008
    Location
    Mid North Coast NSW . Australia
    Age
    67
    Posts
    2,207
    Thanks
    1,431
    Thanked 469 Times in 313 Posts
    Rep Power
    415
    Reputation
    7297

    Default

    Problem :
    Notice the line in case2 and case3 ..... StepperControl.runSpeedToPosition(); // Blocks until all steppers are in position

    Case 0 is where you move the 3 steppers to the position for the beginning of the video run. The set button is then pressed to store those positions.
    Case 1 is where you move the 3 steppers to the position for the end of the video run. Press the set button again to store those positions.

    Case2 ... When the set button is now pressed, the steppers will move the camera to its stored beginning positions ready for videoing.
    Case3 ... Start the camera and press the set button to calculate the distance all steppers will move and mathematically synchronize their movements so they arrive at the same time, then move the camera to the end positions at the speed set by the speed pot. Stop camera.

    During case2 and case3, the line ( StepperControl.runSpeedToPosition(); ) blocks anything else from happening. Buttons don't work. It can't do other calcs.
    Funny thing about accelstepper is it can do acceleration and it can do sync of stepper movements but it can't do both at the same time right ? .... Well I'm not so sure now.
    I've seen other youtube vids where the guy has got accelstepper to do both, but it's a bit different and a bit beyond my at the moment. One of them is linked in my posts on Arduino.cc
    Last edited by loopyloo; 24-03-19 at 09:36 PM.

  • #11
    Premium Member

    Join Date
    Jan 2008
    Posts
    4,311
    Thanks
    5,982
    Thanked 4,171 Times in 1,771 Posts
    Rep Power
    1348
    Reputation
    50392

    Default

    Quote Originally Posted by loopyloo View Post
    I joined up and put the same question on Arduino.cc .... It was a lot of fun and games trying to get answers out of those guys, and with little results. I did however find a few interesting things about acceleration etc in other places and put them on the forum.
    Here's the link : I dunno if you can see it without joining.

    You might as well have a look at the slider while you're here
    The harness might look messy but it's actually plaited for max flexibility. The blue and grey plastic parts and the control box were cad drawn and 3D printed by myself.







    That's VERY impressive, Loopy!

    Well done indeed.

  • The Following User Says Thank You to tristen For This Useful Post:

    loopyloo (24-03-19)

  • #12
    Senior Member
    loopyloo's Avatar
    Join Date
    Feb 2008
    Location
    Mid North Coast NSW . Australia
    Age
    67
    Posts
    2,207
    Thanks
    1,431
    Thanked 469 Times in 313 Posts
    Rep Power
    415
    Reputation
    7297

    Default

    Here we go .... out of my league at the moment.


  • #13
    Senior Member
    trash's Avatar
    Join Date
    Jan 2008
    Location
    Tamworth
    Posts
    4,088
    Thanks
    148
    Thanked 3,229 Times in 1,451 Posts
    Rep Power
    1287
    Reputation
    47674

    Default

    There's lots of useful functions. I'm resisting the temptation to look too closely at it.
    So it looks like the speed numbers are microseconds or steps per second.

    The run(); command looks simple, but there is a bit of code behind it.
    I look for the code that sits under it (again, that's just me)... the move(); command appears to be the lowest level of moving the motor.

    move(+1); and move(-1)

    run(); looks at a couple of registers, the direction register than the timing register. If the timing is right, it runs the move(); command, else it continues to wait.

    Speed is how long you wait.
    Acceleration is how much you change how long you wait.

    There's nothing stopping you writing that code yourself, or trying to learn how the acceleration(); function does it.
    If the issue is just your ability to write code, I will say just jump in the deep in. Either write some really simple code from scratch, like move(+1); move(-1)
    and then just build on that making your own code mode complex.
    Or, use the code you have and either make some random changes and watch what effect they have or add new lines of code with the same aim.

    One thing that really helps is having a friend who programs the same things as you and you can bounce code off them.
    Quite often a friend will have a different perspective on the same thing which is useful.
    Yes I am an agent of Satan, but my duties are largely ceremonial.

  • The Following User Says Thank You to trash For This Useful Post:

    loopyloo (25-03-19)

  • #14
    Junior Member
    Join Date
    Jul 2010
    Posts
    72
    Thanks
    567
    Thanked 46 Times in 32 Posts
    Rep Power
    185
    Reputation
    840

    Default

    Hi Loopyloo,
    Not sure if you watched this one, but I think he is doing what you want to do with 6 motors (easy to delete 3)

    Keep going, it is looking really nice mate

  • The Following User Says Thank You to ammlione For This Useful Post:

    loopyloo (25-03-19)

  • #15
    Senior Member
    loopyloo's Avatar
    Join Date
    Feb 2008
    Location
    Mid North Coast NSW . Australia
    Age
    67
    Posts
    2,207
    Thanks
    1,431
    Thanked 469 Times in 313 Posts
    Rep Power
    415
    Reputation
    7297

    Default

    Quote Originally Posted by ammlione View Post
    Hi Loopyloo,
    Not sure if you watched this one, but I think he is doing what you want to do with 6 motors (easy to delete 3)

    Keep going, it is looking really nice mate
    Yep I saw that vid. He's a pretty clever bloke. The thing is running from his own sketch, so no good to me though since accelstepper isn't used at all.
    Last edited by loopyloo; 26-03-19 at 10:33 AM.

  • Bookmarks

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •