Playing with Brushless Motor Field Oriented Control
This post details some tests I have done using Field Oriented Control (FOC) of BLDC motors.
I often use brushless (BLDC) motors for drone projects as they provide a high power to weight ratio, and fast control of speed. They are however more complex to control than many other types of electric motor, especially at low speeds. This means that accuracte position control has often been done using stepper or servo motors instead, or if brushless motors are used, it is often through large gear reductions. Being able to accurately and precicely control the position of a BLDC motor makes them much more suitable for use in
Field oriented control (FOC) is a method of driving BLDC motors which provides an increased amount of control and efficiency. Up until recently, BLDC motor drivers which used FOC were either expensive and used closed source software. SimpleFOC is an open source FOC project, which is Arduino compatable, meaning it is easy to modify and run on a wide range of hardware. Although the project has files and a store with their own BLDC driver hardware, it is intended to be used with a separte Arduino Uno, and it is relatively low power (max 120W), at least compared to what drones or larger robots require.
The B-G431B-ESC1 is an Electronic Speed Controller (ESC) by ST which features an STM32G431CB microcontroller and other hardware required for field oriented control of brushless motors, in a footprint not much larger or expensive than similarly powerful drone ESCs. With a peak current capability of 40A, it is also much more powerful than the SimpleFOC driver. It is intended to be used with a suite ST applications, but it is also possible to use it with the Arduino IDE, and therefore, the SimpleFOC library. The below image shows the B-G431B-ESC1, where the top section is a removable daughterboard which contains an ST-LINK programmer and a potentiometer, and the lower section is the ESC itself (the STM32G431CB is on the back of the lower ESC board). The daughterboard is able to be snapped off for final use, or it can be left on for easier programming and the use of the potentiometer.
To test SimpleFOC on the B-G431B-ESC1, I connected it to a an EMAX MT3515-650KV BLDC motor. The below video shows SimpleFOC running on the B-G431B-ESC1, controlling the position of the motor very fast in 1/4 steps, using no external position sensor.
Although no external sensor is required for FOC, it can be very helpful for slow speeds and fine position control. The external sensor I am using is an AS5048A 14-bit rotary position encoder. Instead of making direct contact with the motor, a diametric magnet is attached to the motor shaft, and the sensor is placed approximately 1mm from it. The AS5048A can either be used in SPI or PWM output mode, but the B-G431B-ESC1 does not have SPI, and SimpleFOC does not support PWM sensor inputs. As the SimpleFOC library is open source, I was able to look at the existing sensor types to implement a PWM sensor input, which allowed me to use the AS5048A in PWM mode with the B-G431B-ESC1. There are however some issues with my implementation of the sensor which will be shown later.
The below video shows the slow speed control of the motor, spinning much slower than is possible using a conventional drone ESC which does not use FOC or an external position sensor.
The below video shows a postion control test with the external rotation sensor, where the motor returns to the upright position every time the angle is manually changed, or when the ESC regains power. It can be seen that the control is not perfect, as there are oscillations during the movement. I think that this is mostly due to the pulseIn() function I am using to read the PWM from the rotation sensor, as it is a blocking function which causes issues with the FOC algorithm loop. The knocking sound in the video is caused by the rod hitting the desk, the motor/ESC operation is near silent.
I also want to experiment with other sensor types that are not currently implemented within SimpleFOC for position control of BLDC motors. The first is using an old gimbal which had a broken driver board. The IMU is able to output an angle, which could be converted to a position input for the two BLDC motors for control. The result of this would effectively just be a gimbal again, but it would still be interesting to implement the IMU as a sensor type within SimpleFOC.
The second input type I am working on is based on tracking the angle of a visual marker (ArUco in this case) attached to the BLDC motor. The complexity in this case is that the B-G431B-ESC1 is not able to directly interface with a camera or detect the marker, meaning it must be done on a separate device (e.g. Raspberry Pi) and then the position must be send to the B-G431B-ESC1 with minimal delay.