Skip to main content

Move a set number of steps

What this example shows​

Moving the motor a precise distance and stopping there, with the library ramping the speed up and back down so the motor does not skip steps at either end. This is what you want for anything that has to end up somewhere: an axis, a feeder, a rotating stage.

The shipped sketch uses BasicStepper stepper;, which the library header defines as AccelStepper::FULL4WIRE on pins 2, 3, 4 and 5. That drives motor coils directly and does not fit this board. Construct it with BasicStepper::DRIVER and your STEP and DIR pins instead, as below.

The example code​

Select Board
Blocking.ino
#include <Basic-Stepper-Driver-SOLDERED.h>

#define dirPin 4
#define stepPin 5

BasicStepper stepper(BasicStepper::DRIVER, stepPin, dirPin);

void setup()
{
stepper.setMaxSpeed(200.0);
stepper.setAcceleration(100.0);
}

void loop()
{
stepper.runToNewPosition(0);
stepper.runToNewPosition(500);
stepper.runToNewPosition(100);
stepper.runToNewPosition(120);
}

Expected result:

The motor steps to position 500, back to 100, forward to 120, then returns to 0 and repeats. Each move accelerates away and decelerates into its target. On a 200-step motor in full step, 500 steps is two and a half turns.

There is no serial output. runToNewPosition() blocks until each move finishes, so nothing else can run while the motor is moving.

Doing it without blocking​

runToNewPosition() is convenient and completely unsuitable for a sketch that also has to read a sensor or answer a button. The non-blocking form sets a target and steps towards it from loop():

Select Board
Blocking.ino
#include <Basic-Stepper-Driver-SOLDERED.h>

#define dirPin 4
#define stepPin 5

BasicStepper stepper(BasicStepper::DRIVER, stepPin, dirPin);

void setup()
{
stepper.setMaxSpeed(1000);
stepper.setAcceleration(50);
}

void loop()
{
stepper.move(100);
while (stepper.run()) {}
delay(2000);
stepper.move(50);
while (stepper.run()) {}
delay(2000);
}

move() is relative, so on a 200-step motor this turns half a rotation, waits two seconds, turns a further quarter rotation, and waits again. Replace the while loops with a plain run() call per pass through loop() and the sketch stops blocking entirely.

If you want a constant speed to a position rather than an accelerated one, moveTo() followed by run() will not do it: the header notes that moveTo() recalculates the speed for the next step, and run() then applies its own acceleration curve on top. Use moveTo(), then setSpeed(), then runSpeedToPosition(), which is documented as running at the selected speed and implementing no accelerations.

Functions used​

BasicStepper(uint8_t interface, uint8_t pin1, uint8_t pin2)returns None

Constructs a stepper on the given interface. Pass BasicStepper::DRIVER for this board, then the STEP pin and the DIR pin, in that order. Inherited from AccelStepper, which also accepts two further pins and an enable flag for the direct-drive interfaces.

ReturnsConstructor; no return value.

Parameters

TypeNameDescription
uint8_tinterfaceMotor interface type. BasicStepper::DRIVER (1) for a step/dir driver. Defaults to FULL4WIRE (4).
uint8_tpin1With DRIVER, the STEP pin. Defaults to 2.
uint8_tpin2With DRIVER, the DIR pin. Defaults to 3.
setMaxSpeed(float speed)returns void

Sets the highest speed the motor is allowed to reach. Acceleration ramps up to this value and no further.

ReturnsNothing.

Parameters

TypeNameDescription
floatspeedMaximum speed in steps per second.
setAcceleration(float acceleration)returns void

Sets how quickly the motor changes speed, used for both accelerating and decelerating. Unlike with runSpeed(), this genuinely applies here: run(), runToPosition() and runToNewPosition() all follow the ramp.

ReturnsNothing.

Parameters

TypeNameDescription
floataccelerationAcceleration in steps per second squared.
runToNewPosition(long position)returns void

Moves to an absolute target with acceleration and deceleration, and blocks until the motor arrives. Simple to use, but nothing else in your sketch runs during the move, so keep it out of event loops.

ReturnsNothing. It returns once the motor is at position.

Parameters

TypeNameDescription
longpositionAbsolute target position in steps.
move(long relative)returns void

Sets a target a given number of steps from where the motor is now. It does not move anything on its own; run() does the stepping. Negative counts as anticlockwise from the current position.

ReturnsNothing.

Parameters

TypeNameDescription
longrelativeTarget offset in steps from the current position.
moveTo(long absolute)returns void

Sets an absolute target position, counted from where the motor started. Also recalculates the speed for the next step, which is why a constant-speed move needs setSpeed() called again afterwards.

ReturnsNothing.

Parameters

TypeNameDescription
longabsoluteAbsolute target position in steps. Negative is anticlockwise from position 0.
run()returns boolean

Steps the motor at most once, following the acceleration curve towards the target. Has to be called repeatedly; anything that blocks in loop() slows the motor down.

ReturnsTrue while the motor is still travelling to its target.

Parameters

This function takes no parameters.

distanceToGo()returns long

How many steps are left before the target is reached. Zero means the motor has arrived, which is the usual way to tell a move has finished without blocking on it.

ReturnsSteps still to go. Negative when the target is behind the current position.

Parameters

This function takes no parameters.

stop()returns void

Sets a new target as close to the current position as the deceleration rate allows, so the motor comes to a controlled halt rather than losing its position. Follow it with runToPosition() to finish the stop.

ReturnsNothing.

Parameters

This function takes no parameters.

Putting it together​

Set speed and acceleration once, then pick the call that matches how much control you need. runToNewPosition() for a quick sketch where blocking is fine. move() or moveTo() plus run() in loop() when other things have to keep working. distanceToGo() == 0 to notice a move has finished, and stop() when you need to abort one without losing track of where the motor is.

Ramping is the point of all of this. A stepper asked to jump straight to speed under load skips steps, and a skipped step means the position the library thinks it is at is no longer the position the shaft is at. There is no feedback to catch that, so it stays wrong until you re-home.

Variations in the library​

Four more shipped sketches do position moves the same way, with the same constructor caveat. They are worth reading for the patterns rather than the outcomes: