


                    CONTROL OF STEPPING MOTORS
                                By
                         Douglas W. Jones
                        University of Iowa
                        jones@cs.uiowa.edu

                          COPYRIGHT 1990
                originally posted on rec.railroad

                           REVISED 1995

                   All rights reserved.  Permision
                   is hereby given to make copies
                   for personal use and to archive
                   or distribute copies of this
                   material on the Internet and
                   connected networks.  All other
                   copying of this material is
                   prohibited.


                           Introduction

Stepping motors can be viewed as electric motors without commutators.
Typically, all windings in the motor are part of the stator, and the
rotor is either a permanent magnet or, in the case of variable reluctance
motors, a toothed block of some magnetically soft material.  All of the
commutation must be handled externally by the motor controller, and
typically, the motors and controllers are designed so that the motor may
be held in any fixed position as well as being rotated one way or the
other.  Most stepping motors can be stepped at audio frequencies,
allowing them to spin quite quickly, and with an appropriate controller,
they may be started and stopped "on a dime" at controlled orientations.

Stepping motors come in two varieties, permanent magnet and variable
reluctance (there are also hybrid motors, which are permanent magnet
motors from the controller's point of view).  Lacking a label on the
motor, you can generally tell the two apart by feel when no power is
applied.  Permanent magnet motors tend to "cog" as you twist the rotor
with your fingers, while variable reluctance motors almost spin freely
(although they may cog slightly because of residual magnetization in
the rotor).  You can also distinguish between the two varieties with
an ohm meter.  Variable reluctance motors usually have three (sometimes
four) windings, with a common return, while permanent magnet motors
usually have two independent windings, without center taps in bipolar
motors, with center taps in unipolar motors.

   Variable Reluctance         Bipolar             Unipolar

                                                       |
      ---/\/\/\-                                       |
                |           ---/\/\/\---         ---/\/ \/\---
      ---/\/\/\-|--
                |           ---/\/\/\---         ---\/\_/\/---
      ---/\/\/\-                                       |
                                                       |

Stepping motors come in a wide range of angular resoluation.  The
coarsest motors typically run around 90 degrees per step, while high
resolution permanent magnet motors are commonly able to handle 1.8
degrees per step.  With an appropriate controller, a permanent magnet
motor can be run in half-steps, and some controllers can handle
"microsteps", smaller fractional steps.


                      Basic Control Circuits

I see no advantage to using commercial stepping motor controllers.  I've
had an easy time with the direct software control of the 3 or 4 windings
in the typical stepping motor, using an 8 bit parallel output port to run
two motors.

What follows is a simple plan for computer control of a stepping motor.
First, we'll assume that the DC resistance of the windings is all you need
to limit the current through the motor.  Some motors have very low
resistance windings and need external current limiters, for example, series
resistors or (better yet) current limiting power transistors.

The following circuit, duplicated once per winding, will generally suffice
to control even a fairly large unipolar stepping motor.

                                                      + motor power
                                                      | ( 5 to 24 volts )
                                                ------|  poorly regulated
                                       diode   |      |
                      logic power     to kill  |    -----
                           +5        inductive -   | one of the
                           |           surge   ^   | motor windings
                           |          1N4002   |    -----
                           | pull up           |      |
             -----------   R resistor           ------|
            |   Open    |  | 470 ohm                  | C
  Logic in  | Collector |  |                        -----
       -----|   Buffer  |--------------------------| power darlington
            | (SN7407)  |                        B | transistor (NPN)
            |           |                           -----  RCA SK 3180
             -----------                              | E
                                                      |
                                                      |
                                                      - system ground

Each winding in the motor requires one darlington transistor, one diode,
one resistor, and one sixth of the SN7407 chip.  The same circuit will
work solenoids, model railroad uncoupling magnets, and other similar
things.  Because the transistors are being used for switching, they
don't dissapate much heat, and I just bolted all of them to a single
aluminum bar as a heatsink (with insulating washers where needed).
This is not expensive!

For small low-current motors (below a few hundred milliamps per winding),
consider using the Signetics ULN2003 chip.  This eliminates the need for
the darlington transistor, and can be directly driven by TTL or CMOS
logic.

If your motor has three windings, typically with 4 wires because one wire
is common to all three windings, it is probably a variable reluctance
stepping motor.  The common wire goes to the positive supply.  Assuming
positive logic, when the input is 1, the winding is on, and the following
outputs would rotate the motor:

  Winding 1 100100100100100100100100100
  Winding 2 010010010010010010010010010
  Winding 3 001001001001001001001001001
             time --->

There are also variable reluctance stepping motors with 4 windings and 5
wires.  The principle for driving these motors is the same as that for the
three winding variety, but it becomes important to work out the correct
order to energise the windings to make the motor step nicely.

If your motor has two center tapped windings, typically with 6 wires, it's
probably a unipolar permanent magnet stepping motor.  The center taps are
connected to the positive supply (possibly through a current limiter), and
we'll call the windings 1a, 1b, 2a, and 2b, where each of the two windings has
ends a and b.  Assuming positive logic on the 4 outputs needed to control
this motor:

  Winding 1a 1000100010001000  11000001110000011100000111
  Winding 1b 0010001000100010  00011100000111000001110000
  Winding 2a 0100010001000100  01110000011100000111000001
  Winding 2b 0001000100010001  00000111000001110000011100
              time --->

Note that the two halves of each winding are never energized at the same
time.  The left sequence shown above will rotate a permanent magnet one
step at a time, while the right sequence will rotate the motor one half
step at a time.  Half stepping works because if two windings are energized
at the same time, the motor will stop in a position midway between the
two.

Things are more complex with bipolar permanent magnet motors that have two
windings with no center taps.  You can distinguish such a 4 wire motor
form the 3 pole 4 wire variable reluctance motors with an ohmmeter.  In
that case, the simple drive circuit outlined above won't work, but the
control logic outlined above is still applicable.  Antonio Raposo
(ajr@cybill.inesc.pt) suggested the following circuit for each winding
of such a motor:

         0------0----0----------------0----0------0------ positive bus
         |      |    |                |    |      |
     2K2 R      |C   |                |    |C     R 2K2
         |   B ---   -                -   --- B   |
   BD679 0----|NPN|  ^ 1N4007  1N4007 ^  |NPN|----0 BD679
         |     ---   |                |   ---     |
         |      |E   |                |    |E     |C
   +5    |      |    |   ---------    |    |      |   +5
    |    0--|<--0----0--| Winding |---0----0-->|--0    |
2K2 R    |  1N5408   |   ---------    |   1N5408  |    R 2K2
    |   C|           |                |           |C   |
    | B ---          -                -          --- B |
 a -0--|NPN|         ^ 1N4007  1N4007 ^         |NPN|--0- b
        ---          |                |          ---
        E| BD679     |                |    BD679  |E
         |           |                |           |
         0-----------0----------------0-----------0------ negative bus
                                                          and logic ground

The a and b inputs to the above circuit can be driven by open collector
TTL outputs as in the first and simpler circuit.  The motor winding will
be energised if exactly one of the a and b inputs is high and exactly one
of them is low.  If both are low, both pull-down transistors will be off.
If both are high, both pull-up transistors will be off.  The a and b ends
of the control circuit can be driven exactly like the a and b ends of the
center tapped winding documented above.  Note the 4 diodes connecting
the ends of the motor windings to the positive and negative bus.  These
are normally reverse biased, but when the motor winding is turned off
or reversed, they will be forward biased for as long as it takes to
kill the current through the winding.

The UDN2998W Dual full bridge chip gives you an H-bridge circuit such
as the above in a power SIP package.  Another chip some people recommend
is the L298 (given the similarity in numbers, these may be the same chip
from different sources).  This is rated at up to 2 amps at 48 volts.
The companion L297 contains drive logic.  The one warning when using this
chip set is that the switching times are fast enough that commonplace
protection diodes (1N400X) aren't fast enough.  Instead, use a diode
such as the BYV27.


                         Current Limiting

Before talking about software, a note on powering stepping motors is
in order.  Small stepping motors, such as those used for head
positioning on floppy disk drives, are usually driven at a low DC
voltage and the current through the motor windings is usually limited
by the internal resistance of the winding.  High torque motors, on the
other hand, are frequently built with very low resistance windings;
when driven by any reasonable supply voltage, these motors usually
require external current limiting circuitry.

Microstepping, where the control system positions the motor rotor
between half steps, also requires external current limiting circuitry.
For example, to position the rotor 1/4 of the way from one step to
another, it might be necessary to run one motor winding at full current
while the other is run at approximately 1/3 of that current.

Another reason to run a motor from a supply voltage higher than that
needed to produce the rated current in the motor windings is to obtain
faster rise times when a motor winding is turned on.  The rates of
current rise and fall when a winding is turned on and off limit the
speed at which the motor can be stepped, and as a result, higher
operating voltages are required for higher stepping rates.

The easiest to understand current limiter is a series resistor.  Most
motor manufacturers recommended this approach in their literature up
until the early 1980's.  The typical circuit used was as follows
(illustrated with one center-tapped motor winding):

                         + 24
                    _____|_____
                   |     |     |   R1 limits the current through the motor
                   |     R1    |
                  _|_    |    _|_  Diodes allow current to flow when
                  /|\    |    /|\    transistors are turned off
                   |     |     |
                  R2  /\/\/\/  R3  R2 and R3 (optional) help drop current
                   |__|     |__|     on turn-off
                      |     |
                      X     X      Transistors to control which side
                                     of winding is powered.

Given the rated maximum current through each winding and the supply
voltage, the resistance and wattage of R1 are easy to compute.  R2
and R3, if they are included, pose more interesting problems.  The
resistance of these depends on the maximum voltage the control
transistors can handle.  For example, if your supply voltage is 24
volts, and your transistors are rated at 75 volts, the drop across
R2 and R3 can be as much as 51 volts without harming the transistors.
If the operating current through the motor is 1.5 amps, R2 and R3
can be 34 ohm resistors.  Note that an interesting alternative would
be to use zener diodes in place of R2 and R3.

Figuring the average wattage of R2 and R3 is a wonderful exercise in
dynamics, particularly when you consider that the inductance of the
motor windings is generally undocumented and varies with the rotor
position (which determines the reluctance of the magnetic circuit).

A couple of high wattage power resistors can cost more than a pair
of power transistors plus a heat sink plus a small fan for forced air
cooling!  Furthermore, it is easy to design a linear current regulator
that will give faster rise times than a current limiting resistor.
Consider the following:

                         +
         ________________|
        |                |
       Zener (Vref)      R1
        |                |
        |__________|/__|/   PNP Power transistor to control
        |          |\  |\   current through winding.
        |        diode   |
        R4               |
        |             /\/\/\/  One center tapped winding of motor
        |             |     |
       gnd            X     X  Transistors to control which side
                               of winding is powered.

If R1 is 0.5 ohms and the forward voltage drop across the diode and
emitter is 0.6 volts, a 1.7 volt zener diode will give a current of
1 amp through R1.  Zener diodes in this voltage range are available,
and can be connected as shown to provide the required reference
voltage for a fixed current regulator.

R4 in the above figure must be sized in terms of the current gain of
the PNP transistor so that sufficient current flows through R1 and R2
in series to allow the transistor to conduct the rated motor current.

Alternatively, Vref can be provided by an ADC for a variable current
application, as required for microstepping.  In this case, things are
complicated by the fact that Vref is measured relative to the motor
supply, and this is typically only minimally regulated.

Note that the protection diodes have been omitted from the above figure,
and also note that series resistors (R2 and R3 in the previous figure)
are extremely useful in this context.  Without these resistors, the fall
time of the current when a motor winding is turned off is determined only
by the low internal resistance of the winding plus the 0.5 ohm series
resistor.

Linear current regulation wastes energy, and for high current motors,
it requires expensive power transistors, heat sinks and forced air
cooling.  In the above example, assuming that the DC resistance of the
stepping motor winding is on the order of 4 ohms, the transistor will
be dropping 20 volts at 1 amp, requiring it to dissapate 20 watts.
Even R1 gets hot; for a 1 amp motor, half an ohm will dissapate
0.5 watts, but this loss is harder to avoid than the large loss in the
transistor itself.

Use of a switching regulator can avoid dissapating large amounts of power
in the transistor.  Such a regulator works by sensing the current through
the winding and turning the control transistor off when the current is
over the set point.  When the control transistor is off, the current
coasts back to the supply through the protection diodes until it falls
enough that the control circuit can turn it back on.

In the abstract, the necessary circuit looks like this:

                         + 24
                  _______|
                 |       |
                Vref     R1
                 |       |
                b|_    __|a
                   Comp  |
                _____|   |
               |         |
               |      /\/\/\/  One center tapped winding of motor
    Motor      |      |     |
    Control - And --- X --- X  Transistors to control which side
    Signals                    of winding is powered.

The protection diodes and any additonal dropping resistors R2 and R3
have been omitted from the above diagram, but they are necessary!

The comparitor compares the voltage at point a (the downstream side of
R1) with the voltage at point b, the reference voltage, provided by a
zener diode or DAC.  When Va > Vb, the current is too low, so the
output of the comparitor allows the control transistors to turn on, if
required by the motor control signals.  When Va < Vb, the current is
too high, so the comparitor, through the and gate, turns off both
transistors.

This circuit must oscillate, so there must be some time delay and
possibly some hysteresis in the feedback loop.  In this circuit, the RL
time constant of R1 and the motor winding, in series, provides the
necessary delay.  It may be necessary to add hysteresis, for example,
by using the comparitor output to perturb the reference voltage.

The sizes of the dropping resistors R2 and R3 pose interesting problems
when a switching regulator is used.  If no dropping resistor is used
with a motor with very low internal resistance, a switching regulator
can be an extremely efficient way to run a stepping motor, but it
doesn't allow fast stepping because the current through the windings
will take a long time to decay.  If R2 and R3 are high, fast stepping
is possible, but large amounts of power will be dissapated in R2 and R3,
leading to inefficient operation.

Computing the wattage of R2 and R3 is quite easy compared to the previous
examples.  Given the two RL time constants that govern the current rise
and fall through R1, the duty cycle for current in either R2 or R3 can
be computed, and as long as the current through R1 varies only slightly,
this lets you compute the peak average power dissapated in R2 and R3.

Note that the switching control system can be quite simple.  Neither
the comparitor nor the and gate imply the use of integrated circuits!
The following outline illustrates how simple things can get:

                         +
           ______________|
          |              |
          |              R1
         Vref            |
          |      ________|
          |_|/_|/        |  PNP transistor to do comparison
            |\ |\        |
          diode  |       |
     Open        R4   /\/\/\/  One center tapped winding of motor
     Collector   |    |
     Control ____|__|/  NPN Darlington pair to control half the winding.
     Signal         |\
                      |
                     Gnd

I haven't actually built a circuit based on the above, and I don't
know if the switching delays in the transistors plus the RL time
constant of the coil will be enough to guarantee that it oscillates!
If it doesn't, Vref will need to be perturbed by a small amount
depending on the state of the PNP transistor.  Unfortunately, straight
resistive feedback won't do because the sign is wrong.


                         Control Software

Now, here's the code to make your motor run as if you had one of those
fancy stepper controllers.  I've used Pascal for no particular reason.
This code assumes only one motor, and it assumes it's attached to the
least significant bits of one parallel output port.  In practice, it's
nice to have one parallel output port per motor, although with a bit of
care, you can use the high bits of a port for another motor or other
applications, and you can multiplex one port to handle multiple motors.
(The July 1993 issue of Model Railroader has plans for a parallel port
multiplexer circuit for IBM PC systems in it).

Assume these declarations and values for a three winding variable
reluctance motor:

     const maxstep = 2;
           steps = 3;
     var   steptab: array [0..maxstep] of integer;
           step: integer;
           motor: file of integer; { this is the I/O port for the motor }
     begin
           step := 0;
           steptab[0] = 1; { binary 001 }
           steptab[1] = 2; { binary 010 }
           steptab[2] = 4; { binary 100 }
           write( motor, steptab[step] );

Assume these declarations and values for a permanent magnet motor, whether
the windings are center tapped (allowing a simple drive circuit) or not
(requiring a messy drive circuit like the one outlined above):

     const maxstep = 3;
           steps = 4;
     var   steptab: array [0..maxstep] of integer;
           step: integer;
           motor: file of integer; { this is the I/O port for the motor }
     begin
           step := 0;
           steptab[0] = 1; { binary 0001 }
           steptab[1] = 4; { binary 0100 }
           steptab[2] = 2; { binary 0010 }
           steptab[3] = 8; { binary 1000 }
           write( motor, steptab[step] );

Assume these declarations and values for half-step control of a permanent
magnet motor:

     const maxstep = 7;
           steps = 8;
     var   steptab: array [0..maxstep] of integer;
           step: integer;
           motor: file of integer; { this is the I/O port for the motor }
     begin
           step := 0;
           steptab[0] = 1;  { binary 0001 }
           steptab[1] = 5;  { binary 0101 }
           steptab[2] = 4;  { binary 0100 }
           steptab[3] = 6;  { binary 0110 }
           steptab[4] = 2;  { binary 0010 }
           steptab[5] = 10; { binary 1010 }
           steptab[6] = 8;  { binary 1000 }
           steptab[7] = 9;  { binary 1001 }
           write( motor, steptab[step] );

The remainder of the code is the same and doesn't depend on the motor.
The following procedure will advance the motor one step in either
direction, where the direction parameter must be either +1 or -1 to
indicate the direction.

     procedure onestep( direction: integer );
     begin
         step := step + direction;
         if step > maxstep then step := 0
         else if step < 0 then step := maxstep;
         write( motor, steptab[step] );
     end;

Software control of a stepping motor is a real-time task, and you need
at least a bit of feedback.  One bit is enough; typically, this will be
a bit indicating that a cam on the turntable (or whatever the motor is
driving) is interrupting a light beam or closing a microswitch.  To avoid
hysteresis problems in reading the position from this cam, you should
only read zero to one transitions as indicating the home position when
the motor is spinning in one direction.  Especially with switches
or where gear trains are involved between the motor and the turntable,
the one to zero transition in the other direction won't usually occur
at exactly the same position.

Given that you can read the sense bit and that you have a programmable
interval timer interrupt on your system, it is easy to make the timer
interrupt service routine operate the motor as follows:

     const maxpos = 11111; { maxpos + 1 is calls to onestep per rev }
     var position: integer; { current position of motor }
         destination: integer; { desired position of motor }
         direction: integer; { direction motor should rotate }
         last: integer; { previous value from position sensor }
         sensor: file of integer; { parallel input port }
     begin
         read( sensor, last );
         position := 1;
         setdest( 0, 1 ); { force turntable to spin on power-up until
                            it finds it's home position }

     procedure timer; { interval timer interrupt service routine }
     var sense: integer;
     begin
         read( sensor, sense );
         if (direction = 1) and (last = 0) and (sense = 1)
           then position = 0;
         last := sense;

         if position <> destination then begin
             onestep( direction );
             position := position + direction;
             if position > maxpos then position := 0
             else if position < 0 then position := maxpos;
         end;

         if position <> destination
           then settimer( interval_until_next_step );
     end;

The following procedure is the only procedure that user code should call.
This procedure sets the destination position of the turntable and sets
the direction of rotation, then sets the interval timer to force an
immediate interrupt and lets the timer routine finish rotating the
turntable while the applications program does whatever else it wants.

     procedure setdest( dst,dir: integer );
     begin
         destination := dst;
         direction := dir;
         if position <> destination
           then settimer( min_interval ); { force a timer interrupt }
     end;

If you want to control multiple stepping motors, it is easiest if you have
one interval timers and one parallel port per motor.  If you hardware has
only one timer, then you can use it to simulate multiple interval timers,
but this is most of the way to the job of writing a real-time executive.

A final note:  If you try to step a motor too fast, it will slip and your
software will lose track of the motor position.  Motors typically come
with a rating that indicates a maximum number of steps per second, but
you may not be able to accelerate the motor to that number of steps per
second from a dead start without running it at a lower speed first.  This
is especially true if the inertia of the load is fairly large, and in
fact, with appropriate acceleration sequences, you can usually excede the
maximum rated speed.

In the above code, interval_until_next_step is shown as a constant.  If
you are dealing with high-inertia loads or very short intervals, you'll
have to make this a variable, using longer intervals during starting and
stopping to take care of accelerating and decelerating the motor.

