Stepper Motor - AccelStepper.h

[Mar. 26, 2019]

Introduction

This web page is a "companion piece" to my Electronic Indexing Head page. In building that project, I ended up writing Arduino code to drive the indexer. As I began revising that code, I eventually became interested in using the AccelStepper.h code library to drive the stepper motor in a more sophisticated manner (using acceleration and deceleration).

Important note: At the time I am writing this, I am relatively new to Arduino programming (although not to computer programming generally), and I am very much in the process of learning how to use the AccelStepper library. Bear this in mind if you are using any of the programs listed on this page - they are intended to be useful examples, but not necessarily examples of great programming.

With the above in mind, why do I have the effrontery to be writing this web page at all? There are two reasons: First, I have found that when I try to explain something to someone else, it helps me to better understand what I am talking about. Second, as new as I am to this effort, I think there are people out there who are newer still and may benefit from some code examples and observations.

Finally, nobody should try to use the information on this page without first going to primary sources listed in the references below. Once you have tried out some of the code on this page, you will probably find it useful to once again review the primary sources, which I think you will then do with a deeper understanding.

Caveat emptor!

Sample Programs

These programs were written to experiment with various aspects the AccelStepper library, and for the most part are simple and rough early trials to help me learn how the library works. While they do work, they are likely to contain a few bugs. They may also implement a feature or approach which is not done in the most efficient way, or which works for a specific case but fails in a more general application. However, I believe they are useful as a learning tool, and toward that end I have tried to comment them liberally to explain what is going on with the program.

Comments, suggestions, and "hey, I found a bug" messages can be sent to:

mailto:kaje567@gmail.com

AccelStep-accelerate-to-constant-run.ino : https://drive.google.com/file/d/1dwDmqIN2cmtOUjwSI9GfFMGO6y0CmmZG/view?usp=sharing

Waits for a keypad key press, then accelerates to a set speed and continues to run constantly. A second key press at any time will stop the motor and wait for another key press to start over again.

AccelStep-accelerate--run-reverse.ino : https://drive.google.com/file/d/1fz47_2XKcEuMmZy8ixKdNibUU9lFS5Db/view?usp=sharing

This program includes a subroutine to accelerate to a constant run speed, in either clockwise or counter-clockwise direction. This program does NOT implement deceleration when stopping; all stops are immediate.

The program to operates as follows:

first key press: accelerate stepper motor to a designated speed and then run continuously

second key press: stop, wait one second, accelerate in reverse and then run continuously

third key press: return to the initial wait state

AccelStep-accelerate-run-decelerate.ino : https://drive.google.com/file/d/1-AKiK38Ii2Sflb4qTaTlonKRB1jypboP/view?usp=sharing

This program stops in either of two ways: A single button press decelerates the motor slowly to a stop; a double button press stops immediately.

The program to operates as follows:

  • first key press: accelerate stepper motor to a designated speed and then run continuously

  • key press while running starts deceleration until stopped, a double key press while running causes immediate stop

  • after full top stop, wait two seconds, accelerate in reverse and then run continuously

  • key press while running in reverse starts deceleration until stopped, a double key press while running causes immediate stop

  • after second full stop, return to wait state

beep-test.ino : https://drive.google.com/file/d/1vvBbbmfBYGx-T46nV1J529GEnCWiicWo/view?usp=sharing

This program has nothing to do with stepper motors, except that I used it to test the beeper on my indexer set-up. I am including it here because the program is useful in verifying that the beeper is working, and in setting the best beep frequency for a particular beeper.

Final release code:

The program below is the final version in that there will be no additional features. However, if bugs or other problems are reported to me, I will post bug fixes or alerts to know issues.

[June 15, 2022]

Arduino_Rotary_Table_Control_2019_V2-Rev4.72d.ino : https://drive.google.com/file/d/1jsLIyIk0W9Tbn1SN9G3Unr60CLXTFa5K/view?usp=sharing

Note that while this latest release has 2019 in the file name (because it is based on code originally written in 2019), this is a new modification for 2022. The following capabilities have been added (see notes in the code for additional details):

  • Ability to operate a relay

  • Ability to change the "clock-wise" designation to match the physical rotation of your indexer

  • When choosing "arc rotation" (indexer moves back and forth in a designated arc), the indexer does not move immediately after degree designation, but only when the "Go" key is pressed

[April 25, 2019 ]

Arduino_Rotary_Table_Control_2019_V2-Rev4.69.ino : https://drive.google.com/file/d/1eq4wtb9i2-4oegIn-TEW0zOMaXgbcMo7/view?usp=sharing

Note: If you are using this program version for the first time, you must use the Settings mode first enter your stepper and rotary table parameters.

Read the introductory program comments for extensive advice and instructions.

This is a complete and tested Rotary Table Controller program but it is not guaranteed to be bug free. Note the release date above to get an

idea of how long it has been in use.

Reported issues:

  1. [Apr.16, 2019] Reported: In Arc Mode, if degree setting is entered and then exited with 0 value, then the motor will make a small random move. I have not been able to reproduce this behavior, but I will investigate further.

  2. Rev.4.69 - fixed display bug in index move when number of degrees per move > 360

    1. - revised code to prevent arc move when number of degrees entered = 0.0

[April 27, 2019 ]

Arduino_Rotary_Table_Control_2019_V2-Rev4.69B.ino : https://drive.google.com/file/d/13R_rxw831M2mKFzQj5tR3caBJbluyLz7/view?usp=sharing

Note: This version of the program includes code for operating a relay before and after stepper motor movement (intended use: unlock the table before moving, lock the table when not moving). This code variation was kindly provided to me by VK. I have not tested it myself as I do not have a relay set up, but I see no reason why it should not work from a programming viewpoint.

The program code includes extensive instructions on how to use the program, how to determine optimal speed and acceleration

settings, how to determine required backlash corrections, etc.

The program implements the following functions:

  • All user settings are stored in permanent memory

  • All user settings can be entered via keypad

  • All stepper motor moves use acceleration/deceleration

    • Maximum motor speed and acceleration are set by the user

  • Backlash compensation is implemented (can be switched on or off)

      • (can be switched on or off)

      • (can be switched on or off)

  • Beep (audio) function is implemented (can be switched on or off)*

  • Move in indexed steps by setting degrees per move

  • Move in indexed steps by setting number of sides or (gear) teeth

  • Move in jog mode (small steps clockwise or counterclockwise)

  • Move in arc mode: Move back and forth in a defined arc

  • Move in continuous rotation (clockwise or counterclockwise)

    • speed and acceleration for this can be set

    • in particular, speed can be reduced for machining purposes

* See the Electronic Indexing Head page for information on connecting a beeper.

Observations and Comments

AccelStepper terms:

  • acceleration : steps per second per second

  • position : starting from zero, the number of motor steps taken, either positive (CW = clockwise) or negative (CCW = counterclockwise)

  • speed : steps per second

General approach:

AccelStepper works generally as follows:

  • First, set some basic parameters such as maximum speed, acceleration, and (in some cases) position to move to

  • Second, use a run type command in a loop to execute the set parameters

  • Additional commands are available to get information on current motor speed, position, etc.

Note I am using the word command here as synonymous with an AccelStepper instruction/class.

Important warning from the official documentation: "This is an open loop controller: If the motor stalls or is oversped, AccelStepper will not have a correct idea of where the motor really is (since there is no feedback of the motor's real position. We only know where we think it is, relative to the initial starting point)."

Stop mode:

Some issues I have discovered with the AccelStepper.h functions:

First, there is no built in function to accelerate to a set speed and then run continuously. However, I have found a workable method of approximating this (implemented in the program code linked to on this page).

Second, a problem arises with stopping the motor when it is in continuous run mode. The ideal method of doing this from a programming standpoint is to use a while loop which checks for a keypad key-press on each loop. The practical problem with this approach is that the keypad scan required to check for key-press introduces a long enough delay in the loop that stepper motor operation is impacted. The practical effect is that the maximum possible motor run speed is greatly reduced. In theory, using an interrupt to detect a stop signal should resolve this issue, but as of this writing [4-13-2019] I have not yet developed a working solution using an interrupt. This is partly due to the hardware limitations of the Arduino Uno which has a limited number of pins with respect to its use as a Rotary Table Controller with keypad and display.

The program I have written (download link above) offers three options for stopping:

  1. A stop-key on the keypad. This works well, but requires the maximum motor speed to be reduced to prevent stalling or skipping.

  2. Key-press detect: This method uses simply detects keypad press by looking for the state change on a designated pin; this is faster than a keypad scan but does not reliably detect the pin state change and may require multiple key presses before detection.

  3. Reset: This works by simply resetting the Arduino. This is highly reliable, but results in an immediate stop with no deceleration.

Motor Interface Type

AccelStepper defines motor interface types like DRIVER, FULL2WIRE, FULL3WIRE, FULL4WIRE, etc. My hardware uses a stepper motor with 4 wires connected to the stepper controller, which is connected to 2 driver pins on an Arduino. So with 4 wires but two driver pins, which interface type to use? At this point I believe the answer is DRIVER. In my programs, I am using the following assignment statement:

AccelStepper stepper(1, 2, 3);

where Arduino pin 2 is the step pin and Arduino pin 3 is the driver pin.

A discussion on the support forum has some useful clarification on this topic.

Commands Overview:

Here I list some (not all) of the AccelStepper commands organized by "type", together with some key relevant information. See the primary references below for a complete list of classes and much more detailed information.

Classes to Set Parameters

Classes to Get Information

Classes to Run Motor

Classes indicated as "blocking" cannot be used in event loops.

Classes with no Type listed are implemented with no value entered.

Index Control Program Test Protocol

This is a testing protocol for the Arduino Rotary Control program listed on this web page. It is basically a checklist of functions to test and verify.

Part 1 - Start-up

  1. Press the key for CW; verify full clockwise rotation

  2. Press the key for CCW, verify full counter-clockwise rotation back to (approximate*) starting position.

  3. Reset the Arduino

  4. Press the key for CCW; verify full clockwise rotation

  5. Press the key for CW, verify full counter-clockwise rotation back to (approximate*) starting position.

  6. Press the key for EXIT, verify exit to Main menu

*Note: Backlash compensation is implemented in the start-up movement but will not work if backlash

compensation has not yet been set.

Part 2 - Settings

  1. Power on controller

  2. Enter Settings mode

  3. Change every setting to a new value and Exit

  4. Reset or power cycle controller

  5. Enter Settings mode

  6. Verify that every setting was changed and . . .

  7. change each setting back to the proper setting and Exit

  8. Reset or power cycle controller

  9. Enter Settings mode

  10. Verify that each setting is now correct

Part 3 - Indexing Mode

Test the following with backlash compensation turned on;

repeat with backlash compensation off.

  1. Reset or power cycle controller

  2. Make an initial CW rotation and EXIT to Main Menu

  3. Select Degrees mode

  4. Enter 90° and EXIT back to the move menu

  5. Rotate CW 5 times; verify that display resets to position=90°

  6. Rotate CCW 5 times, verify that display shows position=0°

  • Repeat the above test in Sides (4 sides) mode

Part 4 - Jog Mode

Test the following with backlash compensation turned on;

repeat with backlash compensation off.

  1. Reset or power cycle controller

  2. Make an initial CW rotation and EXIT to Main Menu

  3. Select Jog mode

  4. Rotate CW 1, 10, and 100 steps - verify display shows 111 steps and corresponding degrees

  5. Rotate CCW 1, 10, and 100 steps - verify display shows 0 steps and 0 degrees

Part 5 - Arc Mode

Test the following with backlash compensation turned on;

repeat with backlash compensation off.

  1. Reset or power cycle controller

  2. Make an initial CW rotation and EXIT to Main Menu

  3. Select Arc mode, verify display shows 0.0° degrees start and 0.00° end

  4. Select Degrees setting, set to 90° - motor should move immediately to position

  5. Verify display shows next move: 0.0° <CCW 90.00°

  6. Move once, verify display now shows: 0.0° CW>> 90.00°

  7. Move once, verify display shows next move: 0.0° <CCW 90.00°

  8. Move once, verify display now shows: 0.0° CW>> 90.00°

  9. Exit to Main Menu and re-enter Arc mode (to re-initialize arc mode)

  10. Select Degrees setting, set to 90° - motor should move immediately to position

  11. Select Jog setting, enter 111 CW steps - note the [number of degrees]

    • Note: Display should show current total steps + additional steps as added, and changing degree total

  12. EXIT back to Arc mode

  13. Verify display shows next move: 0.0° <CCW [number of degrees]

  14. Move once, verify display now shows: 0.0° CW>> [number of degrees]

  15. Move once, verify display now shows: 0.0° <CCW [number of degrees]

Part 6 - Continuous Mode

  1. Using Settings, set the continuous stop mode to [stopkey]

  2. Select Continuous mode

  3. Verify display shows correct settings

  4. Start rotation in CW direction, verify motor accelerates and runs smoothly

  5. Stop rotation with stop key, verify motor decelerates to a stop

  6. Repeat steps 4 - 5 in CCW direction

  7. Select acc change option and change acceleration value

  8. EXIT back to continuous menu and verify display shows modified setting

  9. Repeat steps 4 - 6

  10. Select %sp change option and change percent of max speed value

  11. EXIT back to continuous menu and verify display shows modified setting

  12. Repeat steps 4 - 6

  • Using Settings, set the continuous stop mode to [keypress]

    • Repeat the above tests

  • Using Settings, set the continuous stop mode to [reset]

    • Verify that the display no longer shows a stop key option

    • Repeat the above tests with these changes:

      • Verify that stop key no longer stops rotation

      • Stop rotation using the reset button, verify immediate stop

References