Deadtime
The previous page ended with three duty cycles and a claim that loading them into the timer produces the requested voltage. It does not, quite.
Both transistors in a leg must never conduct at once. If they do, they short the DC link through themselves, and the resulting current is limited only by the loop inductance and the devices’ own resistance. It is called shoot-through and it destroys bridges.
The defence is to insert a gap — a deadtime — between one device turning off and the other turning on. A few hundred nanoseconds is typical. During that gap neither transistor is on, and the leg’s output voltage is decided by something other than your modulator.
What actually happens in the gap
The current in a motor winding is through an inductor, so it cannot stop or jump. During the deadtime it must keep flowing, and with both transistors off the only path left is through a body diode. Which diode depends on which way the current was already going, and that decides where the leg’s output voltage sits for the duration.
Follow the two cases:
Current flowing out of the leg (into the winding). During the deadtime it has to be pulled up from the negative rail through the low-side body diode, so the output is clamped low. The leg spends the deadtime at the bottom rail no matter what you asked for, and the high pulse comes out shorter than commanded.
Current flowing into the leg (back from the winding). Now it pushes out through the high-side diode to the positive rail, clamping the output high, and the high pulse comes out longer.
So the error has a fixed magnitude and a sign that follows the phase current:
For a 500 ns deadtime at 20 kHz — 1% — on a 48 V link, that is 0.48 V per phase. It sounds small. It is not.
Why it matters more than it looks
Three properties make deadtime worse than its size suggests.
It does not scale with what you asked for. The error is a fixed fraction of the DC link, not of the demanded voltage. Ask for 30 V and 0.72 V of error is 2.4%. Ask for 5 V — which is what a low-speed drive asks for — and the same 0.72 V is 14.4%.
Drag the speed slider in the bench below and watch as % of demanded V:
| Speed | Voltage demanded | 1.5% deadtime error as a share of it |
|---|---|---|
| 300 rpm | 5.43 V | 13.3% |
| 1200 rpm | 8.31 V | 8.7% |
| 3500 rpm | 16.77 V | 4.3% |
Deadtime is a low-speed problem. At high speed the back-EMF forces you to demand a large voltage, and a fixed error disappears into it.
It is a square wave, not a smooth error. The sign flips whenever a phase current crosses zero — six times per electrical cycle across three phases. A square wave at the fundamental frequency carries strong 5th and 7th harmonics, and those land on the dq axes as sixth-harmonic ripple.
The current loop cannot remove it. The PI integrator removes the average error, and it does — mean comes out at 8.000 A with or without deadtime. What it cannot do is track a sixth harmonic sitting far above its bandwidth. So deadtime in a closed current loop does not cost you average torque. It costs you ripple, noise and heat.
On the bench This is worth being precise about, because plenty of references say deadtime “reduces the available torque”. In an open-loop V/f drive it does. In a closed current loop with an integrator it does not — the loop restores the average and you are left with harmonic distortion. If your torque is genuinely down, look for an angle error, not deadtime.
The consequence
Look at the phase current as it passes through zero: it flattens. This is sometimes called zero-current clamping, and it is the single most recognisable deadtime signature on a scope. Around the crossing the current is small, the demanded voltage for that phase is small, and the fixed error is comparable to it — so for a few PWM periods the leg produces roughly nothing and the current sits near zero instead of moving smoothly through it.
The id panel shows where the energy goes: ripple at six times the electrical
frequency, on the axis that produces no torque at all.
Compensation, and where it fails
The fix is obvious enough. You know the deadtime and you can measure the current, so add back what is about to be taken away:
/* Applied to the duties BEFORE the gate driver sees them. */
for (int k = 0; k < 3; k++)
duty[k] += sign(i[k]) * (t_dead / t_pwm);
In simulation with a perfect current measurement this is exact — the ideal trace
in the figure sits on zero ripple. On hardware it is not, for one specific
reason: sign(i) is unknowable near a zero crossing.
The measured current there is a small number buried in switching ripple and ADC noise. Its sign flips essentially at random from period to period, and a compensator that follows it injects its own square wave — a loud, audible one — on top of the problem it was meant to solve.
Every real implementation therefore fades the correction out below some current threshold, which is exactly an admission that the sign cannot be trusted there:
/* Ramp through zero instead of stepping. */
float s = clampf(i[k] / i_threshold, -1.0f, 1.0f);
duty[k] += s * (t_dead / t_pwm);
That fade is not free, and the bench measures what it costs. At 1200 rpm with 8 A of demand and 1.5% deadtime:
| Compensation | id ripple (RMS) | Ripple removed | Cycle spent under threshold |
|---|---|---|---|
| none | 0.163 A | — | — |
| ideal (perfect sign) | 0.000 A | 100% | — |
| threshold 1 A | 0.058 A | 65% | 9% |
| threshold 2 A | 0.105 A | 36% | 17% |
| threshold 4 A | 0.165 A | 0% | 35% |
The last row is the lesson. A 4 A threshold on an 8 A peak current leaves the compensator switched off for 35% of the cycle, and it removes no ripple at all — it is pure code with pure risk and no benefit. The threshold has to be small compared with the current you actually run, or compensation is theatre.
On the bench Note the metric in that table is RMS, not peak-to-peak. With a threshold the residual error is a narrow spike at each zero crossing, so peak-to-peak barely moves — 0.485 A uncompensated versus 0.455 A with a 2 A threshold — while the RMS has fallen by a third. Peak-to-peak reports the worst instant; RMS reports the distortion. Measure the one that matches the symptom you care about.
Practical ordering
Deadtime compensation belongs in a specific place in the control chain, and getting the order wrong quietly breaks it:
- Current loop produces , .
- Inverse Park, inverse Clarke → three phase references.
- Modulator → three duty cycles.
- Deadtime compensation adjusts the duties here, using the current sampled this period.
- Compare registers.
- The gate driver inserts the deadtime, and the physics does the rest.
Compensating before the modulator does not work, because the correction is per-leg and depends on each phase’s own current sign — it is not a voltage vector and cannot be expressed as one.
On the bench Before reaching for compensation, ask whether the deadtime is bigger than it needs to be. It is set for the worst-case turn-off delay of the devices plus driver propagation mismatch, and default values in vendor examples are usually conservative. Halving 1 µs to 500 ns halves the error for free, costs nothing, and needs no new code — it needs a datasheet and a scope on the gate nodes. Modern devices with fast, well-matched drivers manage 150–300 ns comfortably.
What to take away
- Deadtime exists to prevent shoot-through and it is not optional. The voltage error it produces is a consequence of physics, not a design mistake.
- The error is a fixed fraction of with the sign of the phase current, so it hurts most at low speed where the demanded voltage is small.
- In a closed current loop it costs ripple, not average torque. Sixth-harmonic ripple on dq, and flattened zero crossings on the phase currents.
- Compensation is three lines, and it works — except near the zero crossings, where the current sign is unknowable and every real implementation has to fade out.
- Keep the fade threshold small relative to your operating current. A threshold comparable to the current amplitude removes no ripple whatsoever.
- Reducing the deadtime itself beats compensating for it.
Next: where the rotor angle comes from when there is no encoder — and why every sensorless scheme struggles at exactly the low speeds where deadtime is already hurting.