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 a code. This time we get to real business – stepper motor control. Actually 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 spinning. You can find stepper motor in any printer which feeds paper incrementally – and this is where you can get one. Disk drives is another great source to scavenge.

driwing stepper motor with arduino motor shield

We won’t get in to stepper motor working theory just 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 current position of shaft. So you only keep track of steps and rely on stepper motor rotation precision. They are great on low speed precise operation, are reliable as there is no brushes. They are digitally controlled and have full torque when stand still while energized. Rotation speed is determined by 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 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 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 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 number of connection wires. Bipolar has only four wires. Unipolar can have 6 or 8 depending on model. And there is no problem to convert unipolar in to bipolar motor if you look ad diagram bellow:

unipolar_and_bipolar_steppers

(source: motionking.com)

 Working example of stepper motor

OK enough of theories. Lets get to real example. As example I took standard 42mm size stepper motor with 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 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 following command:

motor.setSpeed(50);

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

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

  • SINGLE – is a single coil stepping (sometimes referred as 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 – this is when two coils are energized (Full Stepping). This gives full torque of 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º). Obviously 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 ensures smooth transition between steps. Micro-stepping is great for reducing mechanical noise, smooth rotation and avoid resonances. But not to increase resolution more as micro-steps wont ensure enough holding torque and you loose accuracy due to motor friction.

This is practically it with motors. But there is one more thing to try – stepping with acceleration and deceleration. To try this lets download another library called AccelStepper. It still requires Afmotor library. So be sure to have them both.

Here is a simplified example for 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 preparation before 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 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 rough movements.

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

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

Leave a Reply

Your email address will not be published. Required fields are marked *