FOC Reference Field-oriented control, from the equations to the ISR

What goes wrong

The pages on this site explain mechanisms, and each carries a note about the trouble that mechanism causes. This is those notes the other way up: the symptom first, for a reader who already has the problem.

32 of them, and most come from a drive that actually ran.

See also the formula sheet and notation.

The machine does something that cannot happen

Physics that does not add up almost always means the drive is not applying the voltage it computed. Suspect the actuation path before the control law.

The duty is intermittently not the one that was computed
Two pieces of code write the duty registers in the same interrupt. While a reload is pending the second write is silently discarded, and whether it is depends on where the counter happened to be. The reload rule
Runt pulses, or a destroyed bridge
Compare registers written asynchronously to save a period. The shadowing is what stops a duty update landing mid-pulse. The chain
The drive loses the plot around 87% of full output
Plain sinusoidal PWM clips above a modulation index of 0.866 — √3/2, the ratio between the two limits. The 15.5%
Current ripple at six times the electrical frequency
Inverter deadtime. A distinct signature from a sensor fault, and a different fix. What actually happens in the gap

The loop rings, overshoots or will not settle

Stability in a well-tuned current loop is a timing property, not a gain property. Look at delay before reaching for the gains.

A current step overshoots by about half, but is stable
The f_pwm/10 rule of thumb is exactly a 36° phase margin. Stable, marginal, and oversold. Prefer f_pwm/20. Where the rule of thumb comes from
The integrator winds up even though anti-windup is implemented
Feedforward added after the output clamp. The controller saturates without knowing it has, so the anti-windup never fires. Anti-windup
Speed overshoot far worse than the design predicts
The speed loop saturates on every startup, because the current limit is what makes acceleration finite. Anti-windup there is structural rather than optional. The speed loop saturates on every startup
A quiet speed loop that has lost most of its bandwidth
Filtering the speed estimate. Any filter in the feedback path is inside the loop and its phase lag comes off the margin. Buy encoder counts instead. Where speed comes from
Measured bandwidth misses the design by about 5%
The integrator discretisation. Forward Euler is ~5% low in gain at crossover, backward ~5% high. Rule it out before re-identifying the machine. It is not, and here is why

Torque or current is not what was asked for

The awkward ones, because the drive keeps working. Nothing faults, and the number is merely wrong.

One axis responds differently from the other
A salient machine has L_d ≠ L_q, so the axes want different gains — 57% more K_p on q for the reference machine. One shared set is a compromise, not a design. Tuning is not trial and error
√2 more current through the machine than the limit allows
Clamping i_d and i_q separately instead of limiting the vector. On the diagonal the two clamps permit 1.41× the intended magnitude. Where it fits in the loop
MTPA that is wrong by milliamps and looks right
The widely-quoted closed form is parameterised by current *magnitude*. Feeding it i_q gives a plausible, wrong answer. The closed form, and a trap
Efficiency below the datasheet, and different in each direction
A constant angle offset from alignment. Cogging against the alignment current leaves degrees — and at ten degrees a salient machine still makes 100.8% of the aligned torque, so nothing reveals it. The offset is the whole problem

The measurement is lying

Every control decision rests on four numbers and two currents. When the behaviour is inexplicable, doubt those before the algorithm.

Resistance measures tens of percent high
Two-wire measurement. 0.35 Ω is the same order as the leads and connectors. R_s, and the factor of two
Resistance or inductance out by exactly two
A line-to-line measurement puts two windings in series. Halve it. R_s, and the factor of two
Flux linkage out by 1.73, 0.71 or the pole count
Back-EMF to flux linkage is three conversions: √3 for line-to-line, √2 for RMS, and pole pairs for electrical speed. Each dropped factor gives a believable number. λ_m, and three conversions in a row
Current ripple at one or two times the electrical frequency
Sensor offset gives 1×; gain mismatch gives 2×. FFT before correcting. Reading the error from the harmonic
A slow beat in the measured current that no filter removes
The sample instant is not locked to the carrier. Synchronous sampling folds the switching ripple onto DC; 100 Hz out and it returns as a real 100 Hz component. Aliasing is the third thing
Inductance that is optimistic exactly where the machine works hardest
L moves with current through saturation, not with temperature. Measure it near the operating current, not at LCR-meter milliamps. All four numbers move with temperature

The motion is wrong, and the motor is innocent

Symptoms that look mechanical and are not.

A commanded ramp delivered at a fraction of its rate
Reference generation in a task whose period is not scheduled. A nominal 10 Hz UI task measured at 2–3 Hz turned 500 rpm/s into about 80. The same control law, scheduled two ways
Speed wrong by an exact integer ratio
The pole count. Distinctive enough to recognise, and nowhere near the loop you will blame. Pole pairs are worth measuring too
A speed estimate that is useless below some speed
Counting edges in a fixed window quantises speed in steps that do not depend on speed, so the error grows as a fraction as the machine slows. Where speed comes from

Something trips, gets hot, or will not stop

Where the energy is going, and whether there is anywhere for it to go.

Over-voltage on deceleration
Braking energy has nowhere to go. The supply will not sink it, the capacitor holds millijoules, and kinetic energy goes as speed squared. Injected d-axis loss makes the machine its own brake resistor. Braking has to put the energy somewhere
A link capacitor running hotter at part load than at full
Its RMS current peaks near half modulation depth. A drive specified at full load is specified at the wrong point. What the capacitor carries
Better transistors, and more heat than before
Lower R_ds(on) halves conduction loss and does nothing to switching loss, so the crossover frequency falls. To buy PWM frequency, buy faster switching. The trap
Modulation range that disappears on a long cable
Bus sag. The volts at the bridge are not the volts on the front panel, and the modulator scales by whatever V_dc it is told. Sag is a modulation limit

Sensorless is confidently wrong

An estimator that has lost the rotor does not report that it has. Keep a measurement the control law never uses.

A healthy RUN state at speed, with a stationary shaft
The observer locked onto a phantom. The frozen encoder count — a value nothing in the control path consumed — was the only thing that disagreed. Guards, and a witness
A flat few degrees of angle error at every speed
Saliency, not tuning. A flux observer that subtracts a single L carries a load-dependent error on a machine where L_d ≠ L_q. Observer 1: the flux-linkage observer
Sensorless that works at speed and falls apart slowly
Deadtime error is negligible against back-EMF at speed and comparable to it at low speed. The trouble is at the bottom of the range. The comparison

The numbers are right and the code is wrong

Scaling and arithmetic, which is where a correct design goes wrong on the way to a target.

A per-unit value that is meaningless
Bases are a convention, not a fact. Almost every scaling bug is bookkeeping — a quantity converted with the wrong base, or twice. Per-unit: divide everything by its rating
A fixed-point value that wraps instead of clipping
C integer arithmetic wraps. Saturation has to be asked for. Fixed point: representing those numbers
A torque constant out by 1.5 or √1.5
Amplitude-invariant and power-invariant conventions mixed. Neither is wrong; taking half a calculation from each is. Where the 3/2 comes from