How to drive stepper motor with Arduino motor shield

Previously we have driven servo and DC motor using this simple Arduino motor shield. And we saw how it is easy to interface these motors and write code. This time we get to real business – stepper motor control. This is, what usually motor shields are used for. Stepper motors are more complex devices that require some knowledge. You cannot expect to plug some voltage and see it spinning. Their purpose is stepping, that gives precise control of how much motor is turning. You can find 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 won’t get into stepper motor working theory take a peak on types and working principles before try to run one.

Brief info on stepper motors

Stepper motors are mostly 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 on the low-speed precise operation, are reliable as there are no brushes. They are digitally controlled and have full torque when standing still while energized. Rotation speed is determined by the frequency of control pulses, but at very high speed it is hard to control, so it is somewhat limited. There are three types of stepper motors:

  • Permanent magnet;
  • Variable reluctance;
  • Hybrid.

Most common is the variablereluctance motor that has teeth on stator with windings and rotor (without windings).

variable-reluctance-stepper-motor-diagram

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

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

permanent_magnet_stepper

And of course, there are hybrid stepper motors that 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 with more – like three, five. So we focus on 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 is 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 to convert unipolar into the bipolar motor if you look at 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 real case. As an example, I took standard 42mm size stepper motor with a 1.8 deg/step. It’s 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 as 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 motor with step() command using several modes:

Its parameters are simple first number indicates the number of steps to make, 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 Wave Drive). It drives motor by energizing one coil at the time. This is not common 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 of the motor.

  • INTERLEAVE – it is half stepping, when coil pairs are energized simultaneously. So you get double resolution. In our case instead 200 (1.8º) steps per revolution, but 400 (0.9º). Speed is also two times slower.

  • MICROSTEP – this mode is widely used in many applications as it ensures 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 avoid 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 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 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 useful?

accelerated_stepper_motor_rotation

One of the biggest reason would be inertia. If you rotate 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.

Hope you enjoyed my little experiments Arduino motor shield. Have fun while experimenting with motors.

4 Comments:

  1. 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