Give away medical masks when you place an order. learn more

Dual-Motor FOC Secured by Robust Programming with STM32 PMSM SDK

Field Oriented Control (FOC) of sensorless vector DC motors is a complex task, made more so when you add a second motor. Fortunately new CortexTM-M3 powered MCUs are up to the task.

Sensorless vector control of two Permanent Magnet Synchronous Motors (PMSM), simultaneously driven by one microcontroller, is getting more and more convenient as new low-cost, high-performance 32-bit general purpose microcontrollers can now take over the task.

In addition to computational power, it takes the right peripherals and a strong software layer. These are the foundation pillars whereupon the STM32 PMSM software development kit (SDK) has been built: Object Oriented Programming (OOP), Real-Time Operating Systems (RTOS) interoperability, and GUI driven reconfiguration to seamlessly adapt to the target solution.

This article introduces these concepts while looking into the consequences they bring from both the viewpoint of development timing and quality; OOP’s safe data structures (data hiding, encapsulation), modularity (abstraction), code size efficiency (inheritance), RTOS’s qualified scheduling, easy maintenance and upgradability, and a defined and clear Motor Control Application Programming Interface (API) all are valuable features offered in the competitive world of motor control applications from home appliances to factory automation.

MCUs for motor control

Permanent Magnet Synchronous Motors drive using vector-control techniques, such as Field Oriented Control (FOC), are a must for today’s new designs that want to attain performance figures that show optimization of energy efficiency and control dynamics.

Bestselling cores by ARM®, such as the ubiquitous CortexTM-M3, deliver enough computational power to efficiently do the job, frequently also carrying out the execution of mathematical algorithms to detect – while the motor is running – the rotor angular position, thus removing speed sensors from the bill. That is why they are called “sensorless” drives.

A Cortex-M3 based MCU running at 24 MHz (like the cost-effective STM32F100) delivers 30 DMIPS, enough for the sensorless drive, for instance of a silent three-phase dishwasher pump, with the PWM at 16 kHz, FOC at 8 kHz, can still leave 47 percent of the CPU time for other purposes.

It is easy to understand that a Cortex-M3 clocked at 72 MHz (like the mainstream STM32F103), or faster at 120 MHz (like the STM32F2x, 90 nm lithography process), can raise the bar and be a candidate for sensorless FOC driving of two PMSMs. Does it make sense and is it convenient to design an architecture with one MCU and two drives?

This solution scores a lot of points that translate to a reduction in the final cost of the application:
  • Flash size required is easily less than two times.
  • Dedicated room and routing on the PCB are reduced, a 64-pin MCU is suitable: each motor needs 3+3 PWM outputs, one break input, 3+2 analog inputs for current reading plus DC bus voltage and temperature protection, three digital inputs for speed sensor reading (if needed);
  • External components count is reduced (in terms of oscillators, connectors, opto-isolators, passives).
  • Current consumption, in run or sleep mode, is straightforwardly halved.
  • The effort of appliance certification for IEC 60335-1 Class B compliancy can be focused on only one microcontroller.
  • Design and development of an application layer aimed at the coordination of the motors’ activities is simplified, requiring only one tool chain (any IDE supporting 32-bit ARM cores).
On the other hand, a two microcontroller solution introduces redundancy of resources, which supposedly should increase reliability. However, for applications where each of the two motors cannot do without the other, this advantage remains only on paper. For example, think about a room air conditioning set. A failure of the outdoor fan drive causes the appliance to go off, even if the compressor unit is able to work, and vice versa. The same holds true in the case of a washing machine. A working drain pump is of no use if the drum motor is out of order.

Peripherals are central

A dual FOC drive works well if the on-board peripherals are designed for that purpose and solve some technical challenges for the software. The MCU must be able to handle the demands of two “advanced timers.” Each timer should be able to produce six PWM signals (high sides and low sides complemented through dead time insertion). The MCU must be responsive to a fault protection signal – even during a failure on the oscillator clock – and put the timer’s output signal in reset state or in a known configurable state. The MCU must also contain a synchronization circuit to trigger the ADC peripherals at any point during the PWM period.

Three independent ADC peripherals are needed, particularly if the hardware configuration of the system uses a three-shunt-resistor topology to read the first motor’s currents (two ADCs reserved, operating in dual injected simultaneous mode) and a single DC bus shunt resistor to read the second motor’s currents (one ADC reserved, operating in injected discontinuous mode). A dual three-shunt configuration can actually be addressed with just two ADCs by carefully sharing the resources between the two drives.

When sharing resources it is necessary to allocate CPU time for each motor’s FOC tasks. A sensorless FOC runs at high frequency (in the range of 16 kHz in the case of a washing machine, for example), and its execution is extremely time-critical since it has to be synchronous with the related PWM period. This limits the possible configurations and forces some tough design choices. The two drives must have PWM frequencies in integer ratio to each other; the two drives may have different PWM-to-FOC frequency ratios; and the two timers must be synchronized so that their update events do not overlap (see Figure 1).

Figure 1: Timer’s synchronization for CPU load sharing.

Last but not least, from a purely software point of view there is the risk of a complex, highly product-specific design that cannot easily be reused for other configurations.

Here, the challenge can be overcome by designing robust firmware architecture for a single-motor application that can also be used in dual-motor control systems, resulting in a saving in code size and efficiency.

With this in mind, STMicroelectronics has designed its PMSM FOC SDK, offering the broadest choice of configurations. The same architecture and firmware is scalable and fits the entire STM32 family from F10x to F2x. It handles all system hardware requirements (motor power, current sensors, and speed sensor), uses the same algorithms (sensorless, based on State Observer, PLL, Cordic, and I-PMSM efficiency optimization), and enables both single- and dual-motor control.

Figure 2: Scalability of features and microcontroller (*F20x support in the SDK is in beta version).

A foundation concept at the heart of the SDK is conceptual restructuring of the motor control according to the Object Oriented Modeling paradigm. C++ is a programming language that embeds and optimizes its dictates, which actually is entirely generic and can be implemented in any language, as has been done in standard C, for example.

Object Oriented Analysis, on the other hand, is one step short of OOP. It dictates the way a system is approached and then modeled in terms of internal/external relationship, data structures, and functionalities. For example, motor control usually involves sensors to measure motor speed (hence, closing a speed feedback loop) and rotor angle (for the purpose of carrying out a vector control algorithm). Generally, following the Procedural Programming paradigm, a motor control library will have software “modules” specialized for decoding sensors, with one module for each different typology: encoder, Hall Effect, sensorless, resolver, and tachometer being the five most common. Therefore GetSpeed or GetAngle, for example, will be executed by five different functions but with different implementations, data structures, and names.

Let’s now consider the consequences of this classic approach. In the case of a single motor drive, implementation is straightforward and code size can be optimized. On the other hand, for dual or multiple drives the implementation can be far more complex, since functions that are common to all members of the family probably have not been isolated. Moreover, due to different interfaces, modules have a rigid integration with other entities, both from top (final user) and bottom view (relation with other modules). Switching between different system configurations (current/speed sensor, for example) is difficult and requires a dense net of preprocessing conditional instructions or runtime switch cases.

Moving closer to Object Oriented Modeling, let’s say that there is a “class” speed sensor, from where “objects” with different parameters or properties are instantiated – for example, the maximum allowed speed beyond which a fault is to be signaled; the electrical/mechanical angle ratio; and the bandwidth of digital filters to be applied. Each object brings inside (“encapsulates”) a data structure related to its state and exposes an interface – that is, the list of functions or “methods” we can call upon. Further classes can be derived starting from a base class, creating a hierarchical relationship between the “parent class” and “child class” according to which the data structure and methods of the parent are “inherited” by the child. Moreover, derived classes can add new methods or differentiate the behavior of those inherited from the base class (polymorphism).

Returning to our example, it will be possible to instantiate an object from the “Speed Sensorless State Observer” class derived from the “Speed Sensor” class. Once created, its users don’t have to know the exact type of the object (state observer or encoder); it’s enough to call its base methods and the behaviors will be different, determined at runtime from the ability of the specific object itself.

Advantages of this object oriented programming are plain:
  • Polymorphism eases the creation of complex relations between classes, greatly simplifying system configurability.
  • Code size shrinks when instantiating two or more objects from the same class (base or derived).
  • “Encapsulation” secures the code robustness, since data is accessible only through methods, thus preventing object variables from being accidentally modified.
  • User friendliness (granted by the “abstraction” feature) ensures that one only needs to know the interface without taking care of implementation details, focusing on specific software development.
  • Library expansion and maintenance is made easier; adding a new class or modifying it is made faster by inheriting what was already implemented in the parent class.
Mode Test no. HW configuration Flash (bytes) RAM (bytes)
Single Drive #1 3 shunts + sensorless 14628 2306
#2 1 shunt + sensorless 16100 2326
Dual Drive #1 3 shunts + sensorless 17136 3662
3 shunts + sensorless
#2 1 shunt + sensorless 18672 3694
1 shunt + sensorless
#3 3 shunts + sensorless 21940 3794
1 shunt + sensorless

Table 1: Hardware configurations and memory requirements for single and dual drives.

The motor control library is the core of the multi-layer STM32 FOC PMSM SDK. Modeled and implemented according to an OOP paradigm, it is written in ANSI C language and composed of 32 classes among base and derivates that provide all needed functional elements: FOC and derivates (Flux weakening, feed forward current regulation, and I-PMSM optimization); current sensors (one shunt, three shunt, isolated sensors); speed sensors (sensorless, Hall, encoder); speed or torque controllers; and temperature sensors.

Figure 3: STM32 PMSM FOC SDK layer architecture.

The motor control application exposes its Application Programming Interface (API). High-level commands such as Start Motor, Stop Motor, Execute Speed Ramp, and Get State simplify its integration with the User Project. Inside, the motor control application, during the boot stage, creates the required objects from the motor control library in accordance with actual system parameters (as described by a PC graphical configuration tool, the ST Motor Control Workbench). Then it coordinates them continuously for the purpose of receiving commands by means of tasks of proper priority and periodicity.

For the execution of its runtime tasks, the application clearly needs precise timing that, in the architecture of the SDK, is received through a short list of clock functions to be called from the outside (see Table 2).

Task Number Function to call Periodicity Priority Pre-emptiveness
#1 LowFrequencyTask 10 ms Base Yes, over non MC functions
#2 MediumFrequencyTask Equal to that set as speed regulation rate Higher than #1 Yes, over #1
#3 SafetyTask 0.5 ms Higher than #2 Yes, over #1 and #2

Table 2: Task-related timing calls.

A straightforward scheduler, based on Cortex-M3 SysTick timer (SysTick and Pended System Call handlers), is exemplified in a demonstrative user project. At the same time, with minimum effort it is possible to utilize a real-time operating system.

Here, the additional benefit, besides 2.3 kB additional Flash memory, is the scheduler’s proven reliability and configurable services (mainly to the user project advantage) typically offered by operating systems: tasks, queues, semaphores, and mutexes.

As we’ve shown, new microcontrollers such as the STM32F1x and STM32F2x, based on Cortex-M3 cores, are more than up to the job of driving two motors in FOC sensorless mode. The practicability of this architecture, at the end of the day, relies on the integrated peripherals and software structures.