My BLDC controller can use different control strategies to drive a brushless motor. The simplest method is called block, trapezoidal or six-step commutation, whereas the more advanced method is called field-oriented control. The board also gives you the option to use position sensing based on either hall sensors or an encoder. In this post I will first present a block commutation method. Since the motor I had available did not have hall sensors, I have first developed a sensorless approach using back EMF sensing.
It has taken quite a bit of time for me to continue with this project. One of the main drivers has been the chip shortage. I wanted to develop the firmware for this board in the context of another project, for which I needed more than one prototype. Unfortunately the specific STM32 variant I am using has been out of stock for more than a year already, and still there is no clarity on when it will become available again. Without wanting to redesign the PCB for another microcontroller, I finally managed to take some time to complete and publish the first firmware for this board.
My small motor test bench
The base layer for the motor control is the sequential switching between the three phases in order to rotate the rotor, in other words, the commutation. More information on this can found in the project intro. The simplest way to rotate the motor is by just energizing the stator phases one after the other, and the rotor will start moving at this same speed. This is indicated with the blue lines in the figure below. However, this will be very inefficient, since just applying the DC voltage to the coils (which have a very low resistance) will draw a lot of current. To prevent this we need a more intelligent control of the phases.
The common method to limit or even control the current in the motor is, you guessed it, PWM. As indicated with the small red lines below, the switches are in fact not only switched on and off when the motor position changes, but also at a fixed switching frequency, and a certain duty ratio. This is the basic approach of BLDC block commutation.
Switching pattern for motor block commutation
A hardware timer of the STM32 is used to drive a loop at the switching frequency. In this loop, the PWM is updated in function of the manually set duty ratio target, or by means of closed-loop control on the phase current. The PWM is applied using a hardware timer from the MCU as well. The frequency is set at 20 kHz. In principle, a faster switching frequency gives better control with less current ripple and motor noise. In practice, there are drawbacks of setting the frequency too high. It becomes more challenging to measure the current for lower duty cycles, and of course you might run into processing power limitations.
If you paid attention to the figure above, you might have wondered why the PWM is only applied to the high side switch of the motor and not to the low side switch. This is called soft chopping as opposed to hard chopping where the PWM is also applied to the low side switch. Soft chopping is known to reduce the current ripple in the motor, which is why I selected this method.
So, now we know how to spin the motor, but we don't know it's position. This means that we can only try to rotate it at a certain speed without knowing for sure if the motor is actually tracking the request. That being said, if we do this with a slow ramp-up of the speed and a high PWM duty ratio, we can be quite certain that the motor rotor follows the stator commutation. I will call this open loop commutation. Keep this in mind, as this effect will be used later on.
Even if there are no actual rotor position sensors in the motor, we can still measure it's position by looking at the voltages of the three phases.
An example back EMF waveform is shown in the figure above. The most common approach is to detect the zero crossing point at point 1, and then wait for a specific time until point 2 is reached. At this point phase C should be turned on, since driving the phase where the back EMF voltage is the highest is the most efficient.
The simplest implementation would be to have a fixed delay between point one and point two, but this is also inaccurate, since this time delta will change with the speed of the motor. A better approach is to define an integral, which is the surface of the red triangle. Because if the speed is lower, the amplitude of the back EMF is also lower, leading to a flatter more stretched triangle with roughly the same area.
Using the back EMF method described above, the motor speed is calculated using the time in microseconds between each commutation change. A PI controller is implemented that can track a requested motor speed and output a phase current request. To reduce the load on the microcontroller, this speed controller is run at a slower rate, of 100 Hz. The phase current is then translated into a requested duty ratio by another PI control loop that is running at the switching frequency of 20 kHz.
As you can see the performance of the speed control is great. The slower ramp up from zero speed is where the motor is still using open loop commutation
Putting all the functionality described above together we get the high level implementation shown in the diagram below. The commutation logic determines the active phase, while the closed loop controllers on the speed and the current lead to the target PWM duty ratio for the switches. These are then updated every time step.
The final block commutation firmware
The implementation code, which is of course highly specific to the MBLDC hardware, can also be found on GitHub .