How to drive stepper motor with Arduino motor shield

Previously we have driven servo and DC motor using an Arduino motor shield. It is easy to interface with these motors and write the code. This time we get to the stepper motor control and discover the full potential of the motor shield. Stepper motors are more complex devices than servos or DC and require some knowledge before running them. You cannot expect to plug some voltage and see it spinning. Their primary purpose is precise stepping that gives control of how much the motor is turning. You can find a stepper motor in any printer which feeds paper incrementally – and this is where you can get one. Disk drives are another great source to scavenge.

driwing stepper motor with arduino motor shield

We will not get into stepper motor working theory. Do your research before trying to run one.

Brief info on stepper motors

Stepper motors are primarily used in open-loop systems. This means that there is no feedback on the current position of the shaft. So you only keep track of steps and rely on stepper motor rotation precision. They are great for precise low-speed operation, and are reliable as there are no brushes. They are digitally controlled and have full torque when standing still while energized. The frequency of control pulses determines rotation speed, but it is hard to control at very high speed, so it is somewhat limited. There are three types of stepper motors:

  • Permanent magnet;
  • Variable reluctance;
  • Hybrid.

Most common is the variable-reluctance motor with teeth on the stator with windings and rotor (without windings).

variable-reluctance-stepper-motor-diagram

It rotates is when an energized stator attracts poles that are displaced at specific angles.

Permanent magnet steppers are less precise but are low cost. It has no teeth on the rotor – just magnetic lines on a drum.

permanent_magnet_stepper

Moreover, of course, hybrid stepper motors combine the best features of both previous motors. It has high torque and precision but is more expensive.

Stepper motors are also characterized by phase number. Usually, there are two phases, but you can find more – like three or five. So we focus on the two-phase now. One phase is one winding of the motor. It can be unipolar, where one winding has a center tap, and bipolar, where only two ends of one winding are accessible. You can tell the type by the number of connection wires. Bipolar has only four wires. Unipolar can have 6 or 8, depending on the model. And there is no problem converting unipolar into the bipolar motor if you look at the diagram below:

unipolar_and_bipolar_steppers
(source: motionking.com)

 A working example of a stepper motor

OK, enough of theories. Let’s get to the actual case. As an example, I took a standard 42mm size stepper motor with a 1.8 deg/step. Its model number is 103-546-5342. It requires 0.6A in unipolar mode and 0.42 in bipolar – perfect for our Arduino motor shield.

103-546-5342 steper motor

As we can see connect motor is bipolar, connecting Orange and Blue wires to M1 and Red with Yellow to M2 connector. White and Black, we can leave unconnected.

wiring_stepper_motor_to_arduino_motor_shield

Now load Arduino program from Examples->AFmotor->StepperTest:

#include <AFMotor.h>
// Motor with 200 steps per rev (1.8 degree)
// to motor port #1 (M1 and M2)
AF_Stepper motor(200, 1);
void setup() {
  // set up Serial library at 9600 bps
  Serial.begin(9600);
  Serial.println("Stepper test!");
  motor.setSpeed(50); // 50 rpm  
}
void loop() {
  Serial.println("Single coil steps");
  motor.step(200, FORWARD, SINGLE);
  motor.step(100, BACKWARD, SINGLE);
delay(100);
  Serial.println("Double coil steps");
  motor.step(200, FORWARD, DOUBLE);
  motor.step(100, BACKWARD, DOUBLE);
delay(100);
  Serial.println("Interleave coil steps");
  motor.step(200, FORWARD, INTERLEAVE);
  motor.step(100, BACKWARD, INTERLEAVE);
delay(100);
  Serial.println("Micrsostep steps");
  motor.step(200, FORWARD, MICROSTEP);
  motor.step(100, BACKWARD, MICROSTEP);
delay(100);
}

As we can see, we have created a stepper motor object with 200 steps per revolution motor attached to 1 connector:

AF_Stepper motor(200, 1);

Then in setup, we set motor speed to 50rpm with the following command:

motor.setSpeed(50);

And the fun begins by driving the motor with step() command using several modes:

Its parameters are simple first number indicates the number of steps to make, the second rotation direction (FORWARD, BACKWARD), and finally, stepping mode (SINGLE, DOUBLE, INTERLEAVE, and MICROSTEP). Let’s go briefly what each stepping mode means.

  • SINGLE – is a single-coil stepping (sometimes referred to as Wave Drive). It drives the motor by energizing one coil at a time. This is not standard usage, but handy where power saving is required. You have less torque in this mode.
  • DOUBLE – is when two coils are energized (Full Stepping). This gives full torque to the motor.
  • INTERLEAVE – it is half-stepping when coil pairs are energized simultaneously. So you get double resolution. In our case, instead of 200 (1.8º) steps per revolution, 400 (0.9º). Speed is also two times slower.
  • MICROSTEP – this mode is widely used in many applications as it ensures a smooth motor drive. Instead of driving coils with DC signals, they are driven with PWM. It provides a smooth transition between steps. Micro-stepping is excellent for reducing mechanical noise, smooth rotation, and avoiding resonances. But not to increase resolution more, as micro-steps won’t ensure enough holding torque, and you lose accuracy due to motor friction.

There is one more thing to try – stepping with acceleration and deceleration. To try these, let’s download another library called AccelStepper. It still requires the Afmotor library. So be sure to have them both.

Here is a simplified example of one motor we use:

#include <AccelStepper.h>
#include <AFMotor.h>
// two stepper motors one on each port
AF_Stepper motor1(200, 1);
// you can change these to DOUBLE or INTERLEAVE or MICROSTEP!
// wrappers for the first motor!
void forwardstep1() { 
  motor1.onestep(FORWARD, DOUBLE);
}
void backwardstep1() { 
  motor1.onestep(BACKWARD, INTERLEAVE);
}
// Motor shield has two motor ports, now we'll wrap them in an AccelStepper object
AccelStepper stepper1(forwardstep1, backwardstep1);
void setup()
{ 
    stepper1.setMaxSpeed(300.0);
    stepper1.setAcceleration(100.0);
    stepper1.moveTo(500);
}
void loop()
{
    // Change direction at the limits
    if (stepper1.distanceToGo() == 0)
    stepper1.moveTo(-stepper1.currentPosition());
    stepper1.run();
}

Using this library, we can drive a stepper motor by accelerating its rotation to maximum speed for zero. It requires a little bit of preparation before the run as we need to set max speed, acceleration, and final position (steps to make). Where is this feature helpful?

accelerated_stepper_motor_rotation

One of the biggest reasons would be inertia. If you rotate the stepper at high speed with some load, it can overshoot when stopped. Acceleration ensures that no steps will be missing and no overshooting will occur. And this is healthy for any mechanical system not to have sharp movements.

I hope you enjoyed my little experiment, Arduino motor shield. Have fun while experimenting with motors.

4 Comments:

  1. rogério oliveira

    tenho um motor de passo ele tem 4 fios é da mitisumi (m42sp-6nka Lf ) (6,3 ohms) quero ligar no motor shield L 293 D mas não sei como ligar os fios no shield , consegui ligar motores dc e outros dispositivos menos o motor de passo se alguém puder me ajudar fico muito agradecido.
    Faz parte do meu projeto de mecatrônica que será apresentado no fim de dezembro obrigado desde já um abraço a todos.

  2. Thank you for your nice page and your tutorial!
    I tried your tutorial:
    how can stop the Stepper in example two where you use AF Motor library and Accel Stepper?

    Could you please help me?
    Best, Martin

  3. The idea of using AccelStepper library is to include acceleration and deceleration. when starting and ending rotation. The other remains same – you give it some steps to rotate if you want it stop, don’t use stepper1.moveTo() command.
    If you want to make emergency stop inside loop, then probably you should use other tricks like commanding motor to move to its current position. stepper1.moveTo(stepper1.currentPosition())
    I haven’t tried this – please post a comment if this trick works.

  4. Can I use this class with the L298N shield?

    BR / Albino

Leave a Reply