Newsgroups: comp.robotics
Path: cantaloupe.srv.cs.cmu.edu!das-news2.harvard.edu!news2.near.net!news.mathworks.com!udel!gatech!howland.reston.ans.net!agate!darkstar.UCSC.EDU!nic.scruz.net!earth.armory.com!rstevew
From: rstevew@armory.com (Richard Steven Walz)
Subject: Re: Stepper Motor
Cc: jfischer@moose.cs.umn.edu,rstevew@armory.com
Organization: The Armory
Date: Fri, 9 Dec 1994 12:10:03 GMT
Message-ID: <D0JLst.7tD@armory.com>
References: <3c1q5n$svm@srvr1.engin.umich.edu> <D> <D0GIEL.6w@news.cis.umn.edu>
Sender: news@armory.com (Usenet News)
Nntp-Posting-Host: deepthought.armory.com
Lines: 457

In article <D0GIEL.6w@news.cis.umn.edu>,
John D. Fischer <jfischer@moose.cs.umn.edu> wrote:
>I have been able to control 4 wire and 6 wire stepper motors.
>Basicly they all follow the same basic principles.
>1.  At least one wire should have power at all times.
>2.  No more than 2 wire should have power at any time.
>3.  Only wires next to each other should have power at the same time.
>
>For the 4 wire stepper motors, one wire will be connected to the
>other 3.  This wire is the ground.  The other wires will be
>connected to power or won't be connected at all.  Give the wires
>names 1,2, and 3.  The 4th wire is ground.  Apply power to wire 1.
>The stepper should jump to some position and stay there.  Now apply
>power to wire 2, while keeping the power to wire 1.  The stepper
>might move a little bit.  Now disconnect power from wire 1. The
>stepper will move.  Connect 3. Disconnect 2. Connect 1. Dicconnect 3.
>Keep doing this and the stepper will turn in one direction.  To
>reverse directions reverse the order.  Connect 1.  Connect 3.
>Disconnect 1.  Connect 2. Disconnect 3. and so on.
>
>For 6 wire steppers there are 2 grounds.  Two wires will be
>connected to one wire and another 2 wires will be connected to
>one wire.  Connect both of these one wires to ground.  The other
>4 wires will now follow the same pattern as the 4 wire one.
>
>Table shows which wires are attached to power.
>Step	Forward	Reverse
>1	1	1
>2	1 2	1 4
>3	2 	4
>4	2 3	4 3
>5	3	3
>6	3 4	3 2
>7	4	2
>8	4 1	2 1
-------------------------------------------
Oooohhhh GAWD NOoooooohhhH!!! I will email you the stepper tutorial files
immediately!!! You pooor pooooor soul!!!;->
(I'm not kidding. This method looks like empirical guess-work!)
-Steve Walz    rstevew@armory.com
--------------------------------------------
You are in the Cc: line of the header now. And I shall publish these two
files for all the poor tortured heads out there who have no means of
finding out how steppers REALLY are meant to be wired up!
-Steve
-------------------------------------------

            Visible Stepper Motor Driving

From: Jurgen Van Gorp <jvgorp@vnet3.vub.ac.be>
Subject: Re: Help with floppy drive stepper motors
Date: 9 Aug 1994 07:37:08 GMT
Organization: V.U.B. Free University of Brussels

1) If the stepper motor has 4 wires, then measure the impedances. The
wires normally come from two coils, like this: 

     1 -----)  (----- 3
            )  (
            )  (
     2 -----)  (----- 4

Driving the motor is done in four phases:

     a) ----) (----           b) ----) (---- 
         ^  ) (  !                !  ) (  !
        U!  ) (  !U              U!  ) (  !U
         !  ) (  v                v  ) (  v
        ----) (----              ----) (---- 

     c) ----) (----           d) ----) (---- and back to a)
         !  ) (  ^                ^  ) (  ^
        U!  ) (  !U              U!  ) (  !U
         v  ) (  !                !  ) (  !
        ----) (----              ----) (----


If the motor has 6 wires, the wires normally come from four coils, like
this:

     1 -----)  (----- 4
            )  (
     2 -----)  (----- 5
            )  (
     3 -----)  (----- 6

Getting the motor to work is done as follows (again, four phases):

 a)  1 -----)  (----- 4       b)  1 -----)  (----- 4
        ^   )  (   ^                 ^   )  (
       U!   )  (   !U               U!   )  (
     2 -----)  (----- 5           2 -----)  (----- 5
            )  (                         )  (   ^
            )  (                         )  (   !U
     3 -----)  (----- 6           3 -----)  (----- 6

 c)  1 -----)  (----- 4       d)  1 -----)  (----- 4
            )  (                         )  (   ^
            )  (                         )  (   !U
     2 -----)  (----- 5           2 -----)  (----- 5
        ^   )  (   ^                 ^   )  (   
       U!   )  (   !U               U!   )  (
     3 -----)  (----- 6           3 -----)  (----- 6

And that gives you the idea about bipolar two coil and unipolar center-
tapped two coil.
-----------------------------------------------------------------------

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

                          COPYRIGHT 1990
                originally posted on rec.railroad

                           REVISED 1994

                   All rights reserved.  Permision
                   is hereby given to make copies
                   for personal use and to distribute
                   copies of this material on the
                   USENET electronic network news
                   service.  All other copying of
                   this material is prohibited.

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.

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.

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

Before talking about software, a note on powering stepping motors is
in order.  Many stepping motors have low resistance windings, for example,
the Airpax 82911-M1 bipolar stepper has a 1.58 ohm windings rated to handle
2.8 amps.  Driving this motor with more than 4.42 volts will cause it to
overheat.  The impedance of the windings on such a motor limits the rise
time of the drive current, and this limits the torque at high speeds.

To overcome this problem, it is common to drive such motors with a much
higher voltage, typically 12 or 24 volts, with a current limiter of some
kind in series with the winding.  For unipolar motors, the manufacturers
frequently will recommend a large dropping resistor between the center
tap and the positive supply.  Even better performance can be obtained by
using a current limiting power transistor in place of the resistor;
given the cost of power resistors, you actually save money doing this!
The result is inefficient, but there are some nice chopper circuits,
similar to those used in switching power supplies, that avoid this.

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.

--------------------------------------------------------------------------
END

