Part 3 built the loop that holds Iq, andIq is torque. Everything above that is a question of what torque to ask for. A speed loop asks for whatever torque keeps the speed on target. A position loop asks for whatever torque gets the shaft to an angle and keeps it there. The loops nest: position outside, current inside, each one trusting the one it wraps.
Three sensors, six states
Most BLDC motors carry three hall-effect sensors, placed 120° electrical apart. Each reads the rotor magnet's polarity, so together they produce a 3-bit code that steps through six valid states per electrical revolution. They exist for six-step commutation, which only needs to know which 60° sector the rotor is in. For FOC they give a coarse angle; for position control they are a very coarse encoder.
The motor used for this part has 7 pole pairs: 42 states per revolution, 8.6° mechanical each. Between two edges the drive knows nothing new about the rotor. At 1 rpm those edges are more than a second apart.
The loop
A position move has three pieces:
- A reference trajectory. Jumping the target straight to the end point asks for infinite acceleration. A trapezoidal profile ramps velocity up at a fixed acceleration, cruises at a speed limit, and ramps down so it arrives at zero speed.
- A PID on position error, whose output is the
Iqcommand. The derivative term needs a velocity, and with halls that is the hard part. - Feedforward for what the controller already knows: the friction torque it will have to push through while the reference is moving.
What to do between edges
There are two ways to get θ̂ and ω̂ from halls:
- Edge timing. Position is the centre of the current sector; speed is the sector width divided by the time between the last two edges, decaying as time passes without a new edge. Simple, and nearly useless at low speed: with no new edge there is no new information, so the derivative term has nothing to damp with. A rotor resting on a sector boundary also makes one sensor flicker, and every flicker looks like a burst of speed.
- A model-based tracker. Predict the rotor between edges from what the drive is doing to it — commanded torque divided by inertia, minus friction — and snap to the exact boundary angle when an edge arrives. The prediction is clamped to the current sector: if it would leave without an edge, the model is wrong, so it stops there. This is the approach the MMC uses.
Friction is the real limit
Real motors need more torque to start moving than to keep moving. On the bench motor it takes about 0.22 A to break loose but only 0.11 A to keep turning. A position loop asks for a gradually rising current as the error grows; the rotor stays put until that current reaches breakaway, then the friction halves and the surplus torque throws it forward. On long moves the loop absorbs this. On short moves it overshoots.
The simulator below has that friction, 8.6° hall resolution, and the bench motor's inertia and torque constant. Try a short move with edge timing, then switch to the tracker. Then raise the breakaway current: this simplified tracker does not learn the extra friction, so it believes the rotor is further along than it is and parks short of the target. The MMC's tracker learns a load term for exactly this reason.
Hall position loop with stiction
Simplified model of motor 3: J = 44 g·cm², kt = 0.070 N·m/A, 1 A limitDashed: trapezoidal reference. Blue: the true rotor angle. Green staircase: what the halls report. Holding inside one hall state of the target (the shaded band) is as good as this sensor allows.
On the bench (a maxon EC-i 40 on the F302 board), steps of 90°, −360°, 45°, −45°, 30° and −100° all settle and hold within the ±4.3° hall resolution, in 0.4–2.6 s. Long moves are clean; short moves overshoot by 30–60° for exactly the reason above. Slow constant-speed moves track on average down to about 1.4 rpm, but as stick-slip, and at 0.7 rpm the rotor never breaks loose. The captures are in theprogress post.
Getting there took five changes
Each of these was found on the simulator or the bench, in this order. They are the general problems of position control on a coarse sensor, not quirks of one motor.
- A plain PID on the interpolated hall angle limit-cycled ±10°: no velocity between edges, so no damping.
- The tracker fixed that in simulation, holding to 0.01° at a hall edge.
- On hardware, stiction: a friction feedforward, and no integration within half a sector of the target, where there is nothing left to measure.
- A rotor parked on a boundary made a sensor chatter, and each flicker kicked the derivative term. A reversal edge now means "passing through zero speed", not a speed measurement.
- Commutating FOC on the tracker's angle could be 60° off at rest and halve the torque. FOC now commutates on the raw hall angle (at most 30° off); the tracker only feeds the position loop.
The simulator had no stiction or cogging, so items 3 to 5 only appeared on hardware. That is the usual pattern: the model was right about everything it modelled.
Two levers are left on halls: a breakaway boost (extra current until the first edge of a move) to cut the short-move overshoot, and stiction in the simulator so these effects show up before the bench. Smooth sub-rpm motion needs a finer sensor; that comes later.