Stepping motors, as discrete state devices, are extremely valuable when precision position or velocity is needed. Being discrete state devices, these motors are particularly well suited to digital system control. Although microcontrollers are suited for this application, programmable logic devices (PLDs) hold several advantages. Being a far more energy efficient and flexible system, a PLD also provides easy on chip integration of communication standards, parallel performance, and high pin count for multiple motor control. Here, we cover some basic considerations for programming a PLD with very high speed integrated circuit hardware description language (VHDL) to function as a stepping motor controller.
A stepping motor is a discrete state device. Since two winding machines are by far the most typical, they are the only motors considered here (although the concepts covered here bleed very easily to controlling motors with more windings).
Figure 1. A control system for a simplified 45º bipolar permanent magnet stepping motor. Notice that the two opposing windings are spaced ¼ of the distance that the magnet pattern repeats; this corresponds to a 90º phase shift in the influence capable by each winding. The drive circuitry in the middle (transistors) is required to handle the current through the motor; the diodes exist to protect the switches against inductive kickback.
When a constant current is run through one of the motor’s windings an approximately sinusoidal torque curve with fixed nodes results (the blue curve in Figure 2). Half of the motor’s steps are present in the nodes of the curve, but only half of them are lowest energy states that the motor will tend towards. Reversing the current (the cyan curve in Figure 2) will flip the sinusoid about the torque equals zero axis and the highest energy states and the lowest energy states will swap; this always results in the motor being approximately halfway between the two nearest lowest energy states, so there exists nearly no control of the motor with one winding. With the introduction of the second winding, we can control a sinusoid whose nodes are fixed halfway between the nodes of the first sinusoid (the red and orange curves in Figure 2). Since the two curves from each winding are directly additive, the resultant torque vs. rotational position curve’s phase is now controllable.
Figure 2. Individual torques possible from driving current I and --I through either winding in a two-winding motor. Note that at any one time each winding only generates one torque sinusoid.
With step cycling, we consider the possibilities given two trinary variables, one for each winding, Each winding has current of I, 0, or --I so there are nine possibilities, and cycling through relevant states in a certain order at a certain rate provides the fundamental control of stepper motors. If it is realized that analog values are obtainable for current in each winding, their amplitudes can be varied sinusoidally 90º out of phase to generate a much more accurate wave of torque for the motor to ride upon; this method of control is known as sinusoidal micro-stepping and is comparable to driving a synchronous motor.
As in almost any case, motors draw far too much current to be connected directly to any PLD. As such, external drive transistors are necessary for switching the current through the motor’s windings. The necessary external hardware is beyond the scope of this application note and is not considered.
Substantial documentation exists regarding hardware associated with stepping motor control. For a respectable overview of stepping motors in general, Jones on Stepping Motors is an easily accessible and readily available source of information.
When using a PLD to control a stepping motor, there are several components of code to consider. Of course, this will depend on how the motor is intended to be driven i.e. step cycling or micro-stepping.
Regardless of which drive method chosen, there are certain inputs and outputs required for a basic stepper motor control system. Control inputs are typically either velocity or position (or both). Another important input is a clock input of known frequency on which to base other important controller frequencies. Outputs will either be the two switch bits per winding for uni-polar motors or four switch bits per winding for bi-polar motors, but this may differ accordingly depending on the drive hardware chosen for the motor.
For half-stepping or full-stepping a stepping motor, the control system is at its simplest. For two-winding motors, the machine is either a four-state or eight-state machine with four or eight outputs per motor.
Figure 3. A simple bipolar stepping motor velocity control unit. UPDOWNcounter increments or decrements state if forward is ‘1’ or ‘0’ respectively. The rate at which state is changed depends on the values of speed and the frequency of the system’s base clock. MotorOutput converts the variable state to relevant control bits tied directly to the transistors of Figure 1.
For velocity control, an up/down variable frequency counter is necessary. Phase-locked loops (PLLs) will not provide the adequate frequency control needed for this, so a custom clock or counter control unit is most likely necessary. A simple method for generating a new clock is to use a reset counter whose duration is inversely proportional to the velocity intended. The following code segment shows a simple process for progressing a state variable based on speed and direction input.
PROCESS (clk) VARIABLE t :INTEGER RANGE 0 TO 2097151:= 0; CONSTANT dividend :INTEGER RANGE 0 TO 1048575:= 498047; BEGIN IF (clk'EVENT AND clk='1') THEN IF (speed > 0) THEN --t increments at the same frequency of clk and corresponds with --how much time (in periods of clk) is taken before state is --incremented. Speed, in short, increases how fast speed*t --increments and changes how quickly states are stepped through. t := t + 1; IF (CONV_INTEGER(speed)*t >= dividend) THEN t := 0; --The following 5 code lines either increment or decrement the state. --With only 4 or 8 states needed, a nice round 2 or 3 bit number --will suffice for state and automatically roll over from 0 --to the highest value or visa versa. Also, if state is expanded --beyond the two or three bits its entire value is representative of --the motor’s position where the 2 or 3 least significant bits are --all that are needed to control the current through the windings. --The bit forward represents which direction the motor should turn. IF (forward = '1') THEN state <= (state + 1); ELSE state <= (state - 1); END IF; END IF; END IF; END IF; END PROCESS;
The constant dividend is determined by the following equation:
Where (resolutionofspeed – 1) is equal to the maximum numeral value allowed for speed.
For position control, the state variable can be conveniently expanded beyond the four or eight necessary steps (which conveniently correspond to the first two or three bits of any binary number) for a more expansive image of the motor’s current position. In addition to the added range of position data, a separate control unit for stepping the motor to its intended position will be needed. The following example is a simple way of implementing this:
PROCESS(clk) VARIABLE t :INTEGER RANGE 0 TO 2097151:= 0; CONSTANT dividend :INTEGER RANGE 0 TO 1048575:= 498047; BEGIN IF (clk'EVENT AND clk='1') THEN IF (speed > 0) THEN t := t + 1; IF (CONV_INTEGER(speed)*t >= dividend) THEN t := 0; --the following SIGNAL position has replaced SIGNAL state and is --meant to be far more than 2 or 3 bits IF (forward = '1') THEN position <= (position + 1); ELSE position <= (position - 1); END IF; END IF; END IF; END IF; END PROCESS; state <= position(2 DOWNTO 0); ---For half-stepping, 3 bits are used; for full-stepping, 2 speed <= '1' WHEN (position /= positionintended) ELSE '0'; forward <= '0' WHEN (position > positionintended) ELSE '1';
If an actuated load has a significant amount of inertia, limiting acceleration can be an extremely important issue. In this situation, the motor might slip if acceleration is too great and the open loop position or velocity control will be rendered erroneous. A simple way of getting around this is by using another up/down counter to linearly increment the actual rotational velocity with respect to time; the actual velocity increments when the intended velocity is greater and decrements when the intended velocity is less:
Figure 4. The actual velocity safely increments and decrements based on what the intended velocity is. Notice that the slope is different for increasing and decreasing speed; this corresponds to differences in acceleration and deceleration capable of a motor.
PROCESS (clk) VARIABLE t :INTEGER RANGE 0 TO 2097151:= 0; CONSTANT accel :INTEGER RANGE 0 TO 2097151:= 390625; CONSTANT decel :INTEGER RANGE 0 TO 2097151:= 195312; BEGIN IF (clk'EVENT AND clk = '1') THEN t := t + 1; IF (t > accel) THEN IF (vactual < vintended AND vactual > 0) THEN vactual <= vactual + 1; t:=0; ELSIF (vactual > vintended AND vactual < 0) THEN vactual <= vactual - 1; t:=0; END IF; END IF; IF (t > decel) THEN IF (vactual < vintended AND vactual < 0) THEN vactual <= vactual + 1; t:=0; ELSIF (vactual > vintended AND vactual > 0) THEN vactual <= vactual - 1; t:=0; END IF; END IF; END IF; END PROCESS;
Typically this code segment can be simplified by assuming acceleration and deceleration rates of the motor are identical. Regardless, the constants accel and decel can be determined by the following equation:
This is a great solution for position negligent velocity control but that is often undesirable. For acceleration compensated position control, position is not linear with respect to velocity once acceleration becomes nonzero, so some calculation may be necessary to accelerate, coast at a constant speed, and decelerate to a clean stop at an intended final position.
One way to get an adaptive acceleration position control using previously mentioned elements is to simply create an intended velocity vs. position profile curve for the actual velocity to approach that is dependant on the deceleration intended. Ignoring constants of integration and using basic time equations for acceleration, velocity, and position, we can arrive at the following:
Using common sense gives the following relation for intended velocity and ∆p where ∆p is intended position – current position:
Figure 5. Parametric representation of velocity and position for using a velocity approach algorithm to move safely to a final intended position.
An inherent problem with this solution is the fact that actual velocity inherently lags the intended velocity to guarantee a continuous function with time. Another problem is the need to match the intended velocity curve to the deceleration limiting the velocity as mismatch causes a seemingly over or under damped system. One solution for this is to follow the equation directly once an intersection of the intended velocity and the actual velocity occurs, but this involves consideration of extra potentially complicated coding.
One advantage to this acceleration compensated position control solution is its failsafety. With it, the intended final position can safely be instantaneously changed at any time before the final position is reached without the need to recalculate a position vs. time relation or finish moving to a previously intended position.
A more common way to move from one position to another is to calculate the time to stall between steps using motor position data and the motor’s intended final position. This system isn’t the greatest for on the fly decision changing when position control is concerned, but is great when accurate control is needed and decision changing isn’t an issue (following predefined instructions). In this case the counter for stepping up and down velocity to guarantee constant acceleration is not desirable because two variables incremented differently based on time could lead to some inaccuracy in the system’s position.
If a simple point to point control system is desired and it is assumed that the motor will remain busy and stop before new instructions are followed the simple approximate equation can be used:
Δt is the time needed to wait between steps, Δx is a constant equal to how much the motor moves per state change, and s, speed, can be calculated as follows where Δp is intended position – current position and Δn is initial position – current position:
Figure 6. Speed Vs. Position Profile for a Point to Point Movement.
A counter can be built that waits the amount of time necessary and steps accordingly in the direction towards the intended position. Also, care should be taken so that Δn is offset slightly so that it is never zero.
There are several reasons to drive a stepping motor via micro-stepping, better accuracy and reduced effects of resonance (the inhibiting effect of matching stepping frequencies with mechanical load vibration frequencies) are just two of them. With a few additions and alterations, the previous design elements can be used to employ micro-stepping quite simply.
For purely open loop motor control, pulse width modulation (PWM) is a great means of varying time average current through the motor windings. Because of this, a PWM generating circuit is discussed.
Figure 7. Component schematic and a simple timing diagram of a PWM uni-polar stepping motor controller.
The first need is a fixed frequency pulse width modulation (PWM) base counter which would be comparable to a saw tooth function for analog PWM generation. The frequency at which the counter resets is the primary PWM frequency while the frequency at which it increments is the base frequency. The primary frequency should be limited to somewhere between 10KHz and 30KHz. Lower frequencies are a source of audible noise. Higher frequencies cause the external driver to become progressively less power efficient and can cause a lot of relevant electromagnetic interference. The base frequency should be equal to the primary PWM frequency * resolution of the pulse width. This frequency may not be fast enough to match the stepping of states through the sinusoid, but at such high frequencies the advantages of switching to full-stepping the motor should be considered.
The output of the counter serves as an input to the second additional element: a comparator set. This controls switching based on whether the PWM value is greater than or less than another input value.
Another logic element is a sinusoid function or lookup table. For this application, a lookup table saves time, processing power, and possible chip space for low resolutions that are more than adequate for micro-stepping motor control. The input resolution determines how many states there are per sinusoid and the output resolution is the same as the resolution of the pulse width. This element’s output is a sinusoidal value for the comparator element.
As the torque vs. rotational position curve for each winding is not perfectly sinusoidal, using a perfect sine lookup table may not always be the best solution. Also, the curve is not always the same shape for different applied voltages across the windings. To improve accuracy of the motor’s micro-stepping, this sinusoid table may be altered to compensate for the imperfections in the torque vs. rotational position curve for the motor. In the following equation where n is an integer from 0 to StatesPerSinusoid -1, K is some real number typically less than one that can be altered until the curve provides sufficient accuracy for the controller. This technique is a quick fix and is not guaranteed to always work but can usually provide improvement noticeable by the naked eye at low stepping frequencies.
The previous up/down counter can still be used, but the constant dividend must be recalculated as there are now more than four or eight states to cycle through. Equation (1) can still be used.
It should be noted that PWM controlled micro-stepping is progressively less accurate and relevant at higher motor speeds. Once the inductive properties of the motor begin dominating, the sinusoidal PWM doesn’t result in an entirely sinusoidal current through the windings and the rotor’s actual position will lag approximately an entire step as it approaches the point at which it slips. Also, since step cycling results in a higher average current through the windings, it can drive the motor slightly faster than micro-stepping is inherently able.
CLOSED LOOP CURRENT CONTROLLER
Most typically, stepping motors are attached to an excessive voltage supply to compensate for the motor’s inductive properties to result in faster more responsive motors. This implies current limiting of some sort and the tool of choice is usually an external chopper circuit.
Figure 8. A workable current limiting hardware setup. The Q-bit of the latch is ANDed with each line of the switch data bus hence an equivalent width bus output at the AND gate.
The only difference in controlling stepping motors with hardware based current choppers is the abandonment of PWM generation for micro-stepping. Simple cycle stepping circuitry can work just as well with current chopper based hardware drivers as without, but micro-stepping control requires a means of comparing actual motor current with the intended sinusoid lookup table data. There are several ways to do this, but the most common and simple of which is to include a digital to analog converter (DAC) to output the sinusoid data to external comparators (replacing the constant bias voltage source in Figure 8). Sampling rate is important because a system that’s too slow may not cycle as intended. To keep up with the sinusoid data output, the DAC must convert the data at a rate equal to the state progression frequency (which is typically never more than 30KHz).
FOLLOWING AN INSTRUCTION SET
In many instances, such as multiple motor coordinated control, where precision velocity and position control need to be extremely precise and coordinated, the best solution may be to feed time based instruction for every individual step the motor takes. Rather than having hard coded safety considerations for maximum velocities and accelerations, the instructions can just be generated while taking these limitations into consideration. This system can be more complicated computation wise but guarantees that the motor’s position will follow far more accurately where and when it is intended. With this consideration will most likely come the need for more memory.
Accompanying this application note are two identically coded VHDL examples for an acceleration compensated dynamic position uni-polar motor control system. The first folder contains an entire Quartus project built for the ALTERA DE2 (development and education) board. The second folder only contains the individual text files of component and package VHDL code.
The code was built to control a 100 step per revolution two winding bi-polar motor (Portescap 42M100B1B) via 64 states per step micro-stepping. The control system limits the motor to run at a maximum of four revolutions per second in either direction. The motor is also limited to accelerate at two revolutions per second2 and limited to decelerate at four revolutions per second2. The sinusoid table has been simplified assuming symmetry and distorted to match the motor using K = 0.7 in equation (8).
Figure 9. A schematic representation of the example code. With ALTERA’s DE2 board, the pin assignments correspond to the switch array for pi (position intended), the 50 MHz clock for clk, and the first four pins on the left side of the first general IO header for the motor switches.
Any PLD can be used, but the PLD the system was designed with is the Cyclone II EP2C35F672C6N on the ALTERA DE2 board which utilizes a 50 MHz clock. Certain constants must be changed if a different base frequency signal is used so the equations in this application note are repeated in comments within the code. The 18 bit positional input data is provided by the simple bitwise representation of the 18 switch array on the DE2 board so another means of delivering an 18 bit binary number to the PLD will be required if the DE2 board is not used.
Figure 10. Schematic of motor drive circuitry for the example.
This covered some basic considerations for a few simple VHDL based PLD stepper motor controllers.