Sinusoidal Commutation


The overwhelming motivation for sinusoidal commutation is to produce motion which is smooth and lacks the “cogging” associated with traditional “six-step” (or trapezoidal) commutation. These effects are particularly pronounced at low speed.

This section provides an overview of concepts for external sinusoidal commutation, as well as a primer in the use of this feature with the an MEI motion controller. It is intended as both a high-level reference to introduce the concepts, and as an MPI reference in the use of sinusoidal commutation.

Each XMP “Axis” (actually a Motor object) has a primary DAC channel and an auxiliary DAC channel. These outputs are used to provide ‘A’ and ‘B’ phase sinusoidal signals that are phase-shifted by 120 degrees. (MEI also supports other phase angles.) The third commutation signal is generated internally within the servo amplifier by balance loops in the power stage. Thus, an “8-axis” card can drive up to 8 axes of sinusoidally commutated motion.

NOTE: An 8-axis controller with an expansion card can drive up to 16 axes of sinusoidal commutation.

The firmware also supports mixed commutated and non-commutated motion on the same controller card.

Sinusoidal Commutation

Motors rotate due to the torque produced by two interacting magnetic fields. The resultant torque is proportional to the magnitudes of the rotor and stator fields, multiplied by the sine of the angle between the two vectors. Consequently, maximum torque is produced when the stator and rotor angles are at 90 degrees.

Torque Equation

Stator and Field Vectors


A better understanding of commutation can be gained by reviewing the four reference frames used by the XMP. Software links that tie these together are described in detail in Software Considerations and Setting Actual/Command Positions & Origin.

Open-loop Control

For open-loop operation, the Command Position provides the link that updates the Commutation Table Position and consequently moves the motor. In this case, the stage or motor is pulled into alignment with the magnetic stator position as determined by the Commutation Table Pointer (also called the Commutation Pointer). The magnitude of the current flowing through the motor is constant and set by a fixed (open-loop) output level. Only changes in Command Position which are issued from the trajectory calculator will update the Commutation Pointer. Consequently, command position and actual position can be changed by the user without affecting commutation.

Reference Frames—Open Loop

Closed-loop Control

In closed-loop control, the Commutation Table Position is updated from the Feedback Position. Thus, in each sample period, the change in motor-commutated “position” is based on the change in encoder reading from the previous sample.

Reference Frames—Closed Loop

The magnitude of the current is determined by the product of the error signal (i.e., Command Position – Actual Position) multiplied by the PID coefficients. The sign of the resulting signal determines the direction that the motor will travel. Here, a negative value will result in the application of 90 degrees of phase lead in the negative direction. Conversely, a positive signal will have an additional 90 degrees of phase lead in the positive direction with respect to the current Commutation (and Actual) Position.

Vector Relationships

Changing Between Open and Closed-loop Control

The XMP default configuration is for a standard (non-commutated) axis. Configuring the commutation structure enables sinusoidal commutation. Software functions for switching between open and closed-loop control are described in Data Structures & Parameter Definitions. During the software configuration of the board, the specific commutation parameters of the system are defined, and the control mode is set for open-loop.

Upon enabling the drive, the system will not move to the commanded position. Instead, the system will settle within one electrical cycle from its original rest location. If the (open-loop) DAC level is sufficient to move the motor, all subsequent moves (without slippage) will be based on changes to the Commanded Position.

The Command Position can be reset (to the actual position) without incurring motion, since the updating of the commutation pointer occurs only from trajectory calculator updates to the command position. Alternatively, the Actual Position can be reset to the Command Position so that a negligible error signal will be generated. Closed-loop control can then be invoked without causing the motor to jump. Additional information for resetting the ORIGIN is described in Setting Actual/Command Positions & Origin, and a sample program is provided in the ScOpen.c sample application.

Phase Finding—Initialization

Successful motor commutation requires initialization wherein the armature’s Field Vector is determined from either the feedback system or hall sensors. With incremental encoders, the location of the Field Vector is unknown at power-up. Consequently, the Field Vector location must be determined relative to a reference position. The feedback system and motion controller then track the Field Vector position for all subsequent moves. During these moves, the MEI motion controller calculates the 90 degree (stator) current phase advance required for closed-loop operation, while the magnitude of the current vector (or Stator Vector) is determined by the error signal and PID algorithm, as mentioned previously.

Three techniques are described in this section for initial armature phase finding (stepper, dither, and hall). Prior to running the phase-finding software, the exact number of encoder counts per electrical cycle must be known.

HINT: Look for the number of encoder counts per revolution and the number of electrical cycles, or pole-pairs, per revolution, on the encoder and motor specification sheets, respectively.

Stepper Technique

The “Stepper Technique” consists of setting the stator magnetic vector and drawing the armature Field Vector into alignment with the Stator Vector (see figure below). The process of energizing the stator winding results in movement of the armature (or “forcer” for a linear motor) to the nearest magnetic pole. To avoid incorrect phase finding at a null position of 180 electrical degrees between the stator and field vector (a zero torque condition), the technique implements a small (open-loop) move.

Stepper Technique: Aligned Vectors

Dither Technique

The “Dither Technique” can be used in situations where drawing the motor to a Stator Pole will cause excessive initial movement of the load. An example of this might be initializing near a limit switch or hard stop. The dither method is typically used only in situations where limitations on transceiver I/O prevent the use of the Hall Technique. Note that the dither scheme requires more knowledge of the response of the system than the Stepper Technique.

The Dither Technique locates the armature position by setting a known Stator Vector orientation, and then waits several milliseconds to observe the initial direction of the armature acceleration. Based on the initial acceleration, the angular extent of the region containing the armature vector can be continually reduced by repeating this process of successive approximation. Once again, the goal is to have small position change during the sequence of dithering. This may require initial testing for optimum open-loop voltage and a time period for acceleration averaging.

NOTE: The Dither Technique should NOT be used with systems subjected to external forces (i.e., gravitation force on vertical axes, large cable carrier forces, etc.), because stator-induced
force/torque acceleration is the critical measurement for successful dithering.

Hall Sensor Technique

Initialization of sinusoidal commutation using hall sensors has several advantages over the previous techniques. First, the motor can be ‘phase-found’ with zero initial movement. This avoids problems associated with uncontrolled movement into hard stops and inducing oscillations in the mechanical system. Another important feature of hall initialization is that its implementation can proceed in the presence of external forces, such as a gravitationally loaded vertical axis. The disadvantage of hall initialization is that it uses three channels of transceiver I/O for each motor. The six possible states of three hall sensors allow resolution of the armature position to within ± 30 electrical degrees. This is sufficiently accurate to close the PID
loop and move to the first hall transition; whereupon the commutation table pointer is updated to a known value.

The hall commutation position may also be updated by the user at an index, home or limit switch, etc. The ScHall.c sample application shows how to initialize off the halls and update the commutation position at the first hall transition.

Summary of Initialization Techniques

Set magnetic vector, wait for motor to settle, implement small move.

Dither stator magnetic vector until rotor position is known, initialize.

Check Hall sensor state (transceiver I/O) for rotor position, initialize. Move to first Hall transition (or move to a known electrical position) and update commutation table pointer.

IMPORTANT: Before setting phase-finding, open-loop current parameters, verify that there is a safe continuous current levels for your motor/drive combination. It is good practice to monitor the motor current or install protective fuses during this initial development period to prevent motor damage.

Encoder and Motor Phase Sense

Step 1: Encoder Phase Sense

Before attempting closed-loop operation with a system, you should verify that the system has the correct encoder and motor phase direction sense. The recommended approach is to first verify the encoder direction sense. This can be accomplished on most systems by manually moving the stage or motor. If moving the stage in a positive direction sense results in decrementing the encoder counter, then the encoder direction sense is reversed. The phase sense of the encoder can then be changed either by swapping A and B encoder leads or by the MPI software described in the Phase Sense section.

Step 2: Motor Phase Sense

The internal configuration of the amplifier and the wiring between the amplifier and motor will determine the resulting output phasing (i.e., whether the T phase leads the R phase, or the S phase leads the R phase). It is best to command a small open-loop move and see if the commanded move in the positive direction sense results in a positive or negative change in actual position. If the observed move direction sense is reversed, the phasing can be changed by swapping amplifier-to-motor S and T phase leads. Alternatively, this output phase sense can be changed in the controller by using the software functions described in the Phase Sense section.

Wiring Scheme for Axis 0

Commutation Phasing

Two-phase / Four-phase Brushless Motor Operation

The MEI motion controller can also be used to control two-phase or four-phase brushless servo motors. The only difference, from the perspective of the controller, is that the phase separation between the A and B phase is 90 degrees rather than 120 degrees. This is easily changed by a single line in software (see parameter PhaseDelta), or within Motion Console’s Motor Object: SinCom tab. In general, the XMP can control any poly-phase motor/drive combination requiring two sinusoidal analog inputs. Contact MEI for more information.

Hardware Considerations

Select Your Amplifier Carefully

MEI recommends that you carefully select the amplifier to be used for sinusoidal commutation applications. Linear amplifiers are attractive for their high precision, absence of zero-crossing current ripple, and low noise characteristics. PWM drives are generally favorable from a cost, package volume, efficiency, and waste/heat perspective.

At MEI, the top five amplifier-related problems that our customers have when developing a sinusoidal commutation application are:

  1. If the drive is a PWM type, the amplifier can radiate significant EMI, which tends to cause problems with encoders and I/O. Consequently, proper shielding and grounding are critical.
  2. The amplifier’s output stages are unbalanced, with a consequent torque ripple. This also results in poor phase-finding.
  3. At low current levels, the amplifier distorts the current wave form (sometimes called phase-to-phase distortion). Again, the motor will display torque ripple.
  4. The amplifier’s gain characteristics vary significantly from one unit to the next.
  5. In some systems, changing the current output limit switch can result in altering the amplifier’s gain. This often results in destabilization of a previously tuned system.

Wiring for Sinusoidal Commutation

Each STC block has DAC pinouts for two “axes” and includes the “B phase” Auxiliary DAC channels. Both Command (“A phase”) and Auxiliary DACs (“B phase”) are pseudo-differential (with a clean reference) and switch to ground during power-up, power-down, and during faults.

Example for STC – 0, Axis 0:

Cmd_Dac_OUT_0 AGnd
Aux_Dac_OUT_0 AGnd

Wiring Scheme for Axis 0

Motor and Encoder Information

Before programming the XMP, you must know the resolution of the encoder (counts per revolution) and the number of pole-pairs per revolution (i.e., electrical cycles per revolution) of the rotary motor. Alternatively, if a linear motor is used, you only need to know the number of encoder counts per electrical cycle (i.e., the resolution of the encoder) and the length of one complete electrical cycle.

Motor and Amplifier Protection

MEI recommends limiting motor current during initial testing and development with sinusoidal commutation. To protect the motor, verify the safe, continuous current level established by the manufacturer. Next, using the amplifier gain (in torque mode, the output current to input voltage value), calculate the maximum safe input voltage to the amplifier. The XMP voltage output limits are defined in the OutputLevel parameter.

Note that two DAC output level controls are used by the MEI motion controller. OutputLevel (associated with the Motor object commutation structure) controls the constant DAC output used in open-loop control, and OutputLimit (associated with the Filter object PID coefficient structure) places an upper limit on the DAC level for closed-loop control.

To protect your motor and amplifier during initial development with sinusoidal commutation, you should set both of these values (OutputLevel, OutputLimit) to a safe continuous current level.

Example: OutputLimit

Motor Continuous Current Limit
1.0 Amp
Amplifier Current Gain 2.0 Amp/Volt
XMP (software voltage gain)
32,767 DAC units/10 Volts

XMP Max Safe Output Limit (DAC units)
= (32767 DAC units/10V) * (1V/2.0A) * (1.0A)
= 1638 DAC units

Software Considerations

This section supplements the MPI Software section and assumes that you are already familiar with programming the XMP. The section first presents the sequence of operations for initializing sinusoidal commutation. It then defines the commutation specific parameters, and concludes with code examples.

Programming Sequence for Initializing Commutation (Stepper Mode)

The sequence for initializing XMP commutation is listed below. Descriptions of commutation
functions and parameters are found in Data Structures & Parameter Definitions.

  1. Create: Control Object, Axis Object, Filter Object, Motor Object.
  2. Disable amplifier, disable the software error limit.
  3. Define PID and commutation parameters (set for OPEN-LOOP mode, set the PID Integral Gain term to zero and initial DAC open-loop output level).
  4. Stepper initialization mode: enable amplifier and ramp DAC value to openloop output level. Command a small open-loop move (typically ¼ of an electrical cycle). Wait for system motion to settle.
  6. Go to CLOSED-LOOP mode.
  7. Restore software error limits and PID Integral Gain.

For dithering initialization, Step 4 would be replaced by the Dither Technique. Following Step 7, the usual program sequence would be to find HOME (or an INDEX) and then set the ORIGIN.

NOTE: When transitioning from open to closed-loop mode, initial PID estimates are required, which provide a stable system. MEI recommends that “pre-tuning” values for PID use Ki = 0.0 and low values for Kp, with Kd ~ 4 x Kp. Should the gains be too high, the resulting unstable system may behave in a similar fashion to a system with incorrect phasing.

Data Structures and Parameter Definitions

The commutation structures are defined in header file xmp.h.

Structure: MPIXmpCommMode

In closed-loop mode, the commutation table pointer is based on the actual position. Ninety degrees of phase advance is added to the motor “Field” position to provide maximum torque. First, the XMP is initialized in open-loop mode for phase-finding. Following phase-finding, the position error between command and actual position is zeroed. Finally, the commutation mode is switched to CLOSED_LOOP.

In open-loop mode, the commutation table pointer is based on trajectory calculation updates to the command position. This member is used to configure open-loop commutation and to transition from closed-loop mode back to open-loop control.

Structure: MPIXmpCommutationBlock

Length (long)
Length is the number of encoder counts per revolution of a rotary motor. Most brushless servo motors have several electrical cycles per revolution of the shaft. Consequently, Length usually represents the number of encoder counts across several electrical cycles. The XMP will use 1024 commutation points for each electrical cycle.

Alternatively, with a linear motor, Length will be the number of encoder counts traversed in moving through one electrical cycle length (refer to manufacturer’s data sheet for electrical cycle length).

Scale (float)
The Scale parameter is the total number of commutation points per revolution divided by the total number of encoder counts per revolution (i.e., the length). Every sample period, the XMP multiplies the change in encoder counts by the Scale parameter to determine the new commutation table entry point. As an example, consider a rotary motor with 3 electrical cycles (pole-pairs) per revolution and an encoder with 4096 counts per revolution. Refer to the next figure.

Encoder Counts & Commutation Tables

*ClosedLoopPointer (long)
The XMP updates commutation based on the feedback position at this address location. The default source for the closed-loop pointer is Motor[].IO.Encoder[].IO

*OpenLoopPointer (long)
Commutation updates for open-loop motion are directed by changes in the command position generated by the axis trajectory calculator. The default location for this pointer is Axis[].TC.Delta.

*SinLookup (float)
SinLookup points to the first entry of the commutation table. This is usually left in the default state and is not altered by the user.

OutputLevel (float)
In open-loop mode, OutputLevel is the fixed magnitude of the voltage level that results from the respective contributions of each phase. Note that 32,767 is the maximum value which corresponds to 10 volts. For example, to limit the drive input voltage to 2 volts, OutputLevel would be 6553. In closed-loop mode, OutputLevel is ignored and the maximum DAC output is set by the Filter object’s OutputLimit.

Offset (long)
Offset resets the commutation table entry point without affecting Theta. Typically, Offset is used in only two situations. First, it provides a way to update commutation position in open-loop mode without using the trajectory calculator (see ScStep.c) Finally, in closed-loop mode, it allows “fine tuning” the phase-finding commutation entry point. (Be careful, it must be used with care.) Offset has a range of 1024 entry points per electrical cycle.

PhaseDelta (long)
This is the AB phase separation angle. The XMP commutation table length is set at 1024, so a 3-phase brushless motor has 120 degrees of phase separation, or a value of 341 (i.e., 1024/3). For a 2-phase brushless motor, the value is 256 (90 degrees).

Theta (long)
Theta is derived by the motion controller and should not be updated by the user. Theta is the commutation position (in encoder counts) along the complete commutation table as spanned by the Length parameter (see previous figure). Thus, Theta varies between 0 and (Length – 1) in encoder counts and may extend across multiple electrical cycles. For all control modes, the motion controller calculates a new value for Theta every sample period.

OldPosition (long)
OldPosition is the previous sample period's reference position (in encoder counts) used in commutation. OldPosition is updated by the trajectory calculator Command Position in open-loop mode, and by the Actual Position in closed-loop mode. Consequently, the motion controller updates OldPosition every sample period. The difference (in counts) between OldPosition and the current sample position is used to update the commutation Theta. OldPosition should not be directly modified by the user during normal use.

Phase Sense

Encoder Phase Sense

Encoder phase sense can be altered in software when motion in a positive direction
sense decrements the encoder counter (and vice versa). In the MPIMotorConfig structure, encoderPhase = 0 for normal operation; = 1 for reversed phase sense. (see ScStep.c)

DAC Output Phase Sense

Once the encoder phase sense has been set, you will need to verify that you also have the correct DAC phase sense. This can be checked by commanding a small open-loop move. If the resulting direction of the motor is opposite to that expected, you will need to change the DAC output phase sense. This can be implemented by swapping the “A” and “B” DAC wiring to the drive, changing the drive to motor wiring, or via reassigning the motor DACs in software as shown in the ScStep.c sample application using mpiMotorDacGet and mpiMotorDacSet calls.

This will reverse the DAC phase sense each time it is invoked!

Setting Actual/Command Positions and Origin

The Command and Actual Positions for an Axis are generally used for position error calculations for servo control. New Actual Positions are read from the feedback device(s) and new Command Positions are calculated each sample period. An Origin variable (which can be set by the host) is used to determine the relationship between Command and Actual Positions for an Axis, and physical positions on the machine. This Origin can be set in 2 ways, depending on the desired result:

  1. Use mpiAxisOriginSet(...) if it is important to set the Command or Actual Position to an exact value. Calling mpiAxisOriginSet(...) will modify both Command and Actual Positions by the same amount. For example, assume the Command and Actual Positions are 10,000 and 10,024 counts, respectively (and that the Axis is not moving). Setting the Origin to 10,000 will result in Command and Actual Positions of 0 and 24. Similarly, setting the Origin to 10,024 will result in Command and Actual Positions of –24 and 0. This is the most frequently used method for setting the Origin after Homing.
  2. Use mpiAxisCommandPositionSet(...) to primarily reset the Origin for repetitive moves. Here, the Origin is reset with a Null Command Position pointer (i.e., mpi-AxisCommandPositionSet(axis,&newpos,NULL)). This sets the new Origin so that the Command Position takes on the value specified by newpos. The new Actual Position will differ from the old Actual Position by – newpos. For example, to perform an unlimited number of 10,000 count moves, a sequence consisting of a single 10,000 count move followed by a mpiAxisCommandPositionSet(...) call specifying zero for the new position, would be repeated in a loop. For setting the relationship of the Actual Position to a specific machine position, mpiAxisOriginSet(...) should be used.

Modification of only Command Position can be accomplished by calling mpiAxisCommandPositionSet(...) with a NULL Actual Position pointer (mpiAxisPosition- Set(axis,NULL,&newpos)). This will set the Command Position to the value specified by newpos without affecting the Actual Position or Origin.

Warnings & Caveats

  1. mpiAxisOriginSet(...) and mpiAxisCommandPositionSet(...) should never be called during motion. The controller would immediately act on the new positions (or create a position error event), thus causing the move to complete at a different point than that specified in mpiMotionStart(...).
  2. Using mpiAxisCommandPositionSet(...) to set a new Command Position should be done with caution because the controller will immediately try to servo to the new position. If the new and old Command Positions differ by a large amount, the Axis may Fault (Limit Error) or jump to the new position at a very high speed.
  3. The effect of mpiAxisOriginSet(...) and mpiAxisPositionSet(...) calls will not be observed by the Host until the next controller sample following the call. For example, a mpiAxisPositionGet(...) call made immediately after calling mpiAxisOriginSet(...) or mpiAxisPositionSet(...) may return the old position values.

Example Programs

This section provides sample programs and subroutines used to configure the motion controller for sinusoidal commutation and operation in open and closed-loop modes. A significant part of this process is “phase finding” the motor’s magnetic position though the use of the feedback system (see Phase Finding: Initialization).

The open-loop program, ScStep.c, presents a single-axis configuration that is “phase found” under open-loop control along with a “Stepper” type initialization move. The axis remains in open-loop mode after initialization.

The closed-loop program, ScStep.c demonstrates changing the commutation mode for closed-loop control. It is intended to be run following the open-loop program. This program also contains a subroutine which resets the origin (see Setting Actual/Command Positions & Origin).

The open-loop program, ScOpen.c, transitions the control mode from closed-loop to open-loop. Remeber, a safe open-loop DAC level must be set within the program.

The program, ScDither.c, phase-finds a single axis using the open-loop “dithering” method. Tthe program leaves the axis in closed-loop mode and resets the origin.

The initialization program, ScHall.c, phase-finds a single axis using the initial reading of the hall sensors. The commutation is then updated at the first hall transition.

Stepper Phase Finding Program (open-loop)—ScStep.c

The ScStep.c sample application sets up the commutation parameters for a single-axis system using the motor described in Data Structures & Parameter Definitions (see Scale parameter). A small open-loop move is implemented at the end of the program to verify that the motor is not situated in a null position with the magnetic field vector and stator vector is aligned by 180 electrical degrees. This small move constitutes a simple form of “Stepper” phase-finding. Note that the sample program shows methods for reversing encoder and DAC phasing.

See ScStep.c sample application.

Open-loop to closed-loop Program—ScClose.c

This program assumes that the open-loop “phase-finding” process is complete. It then transitions the control mode into closed-loop and sets the origin. Note that the actual and command positions are set to zero. This prevents the motor from jumping to a new position after closing the PID loop.

See ScClose.c sample application.

Dithering Phase-Finding Program—ScDither.c

This program “phase-finds” the motor Field vector by successive “dithering” of the Stator vector. Typically, this method can be used in situations where the “Stepper” phase-finding technique results in too much initial motion of the system. An example of this would be initializing a stage near a hard stop or limit switch. Note that the dithering technique requires tuning the time delay and DAC level to your system. Also note that this routine will leave the commutation Mode in a Closed_Loop state.

See ScDither.c sample application.

Hall Phase-Finding Program—ScHall.c

The ScHall.c program initializes commutation from the motor hall sensors. The sample code uses three transceiver I/O bits to provide the hall state. A closed-loop move is implemented beyond the first hall transition. Position capture is used at the transition to update the commutation table entry point based on the exact position of the hall.

NOTE: An index or home switch may also be used for the position capture.

See ScHall.c sample application.

       Legal Notice  |  Tech Email  |  Feedback
Copyright ©
2001-2010 Motion Engineering