Here a picture of the BLDC motor jig that holds a 4108 hobby BLDC motor along with the magnetic encoder for servo control of the motor.
I completed programming the BLDC motor controller and now have a power dense closed loop BLDC servo! Here is the demo:
After getting STM32CubeIDE setup and building drivers for the motor PWM timer, ADC, Serial, and SPI peripherals I had a BLDC testbed that was capable of reading the motor position and phase currents then driving the H bridge to control the motor.
The basic working principle of field oriented control of brushless motors is that the motor controller knows what position the rotor is in and drives currents through the stator to generate a magnetic field in the correct position to generate maximum torque. For this BLDC motor, that means the magnetic field generated by the stator should always be 90 degrees offset from the magnetic field of the rotor.
To drive currents through the stator and make a magnetic field at a particular angle, two PID loops are used to control the currents in the stator: one in the 'X' direction and one in the 'Y'. The currents in the motor are measured, converted from a three phase to a two phase system using the Clarke transformation, then run through the PID loops which output a desired control voltage. The control voltages from each PID loop is then combined into a vector in which voltage should be applied to the motor which is then sent to an SVM algorithm that converts the control voltage vector to PWM values for the H bridge to execute.
With control over the magnetic field generated by the stator, the position of the rotor can be found by running a magnetic field in a known orientation across the stator and using the magnetic encoder to measure the position of the rotor. Knowing this offset the position of the rotor's magnetic field can be found.
The torque of the motor can be controlled by changing the magnitude of current sent through the stator, and the angle of the current in the stator is always perpendicular to the rotor magnetic field. One last PID loop is required for position control that takes a position setpoint and the current position and outputs the torque that should be applied to the rotor.
Putting all of those control algorithms together, we have a functional BLDC servo motor with position control. There are a few more components that can be added to this system to improve reliability and make the system respond faster to disturbances that I do more work on in the future.