Supported microcontrollers

Arduino SimpleFOClibrary allows you to chose from more than 20 architectures of microcontrollers to chose from for your projects.
The main families supported off-the-shelf are:

And we will continue the extending the support to as many architectures as possible. πŸ˜ƒ

Choosing the microcontroller

This is the comparison of the PWM features implemented for different microcontroller families:

MCU2 PWM mode4 PWM mode3 PWM mode6 PWM modepwm frequency config
Arduino (8-bit)βœ”οΈβœ”οΈβœ”οΈβœ”οΈβœ”οΈ (either 4kHz or 32kHz)
Arduino DUEβœ”οΈβœ”οΈβœ”οΈβŒβœ”οΈ
esp32 MCPWMβœ”οΈβœ”οΈβœ”οΈβœ”οΈβœ”οΈ
esp32 LEDCβœ”οΈβœ”οΈβœ”οΈβŒβœ”οΈ
Raspberry Pi Picoβœ”οΈβœ”οΈβœ”οΈβœ”οΈβœ”οΈ
Portenta H7βœ”οΈβœ”οΈβœ”οΈβŒβœ”οΈ
Renesas (UNO R4 Minima)βœ”οΈβœ”οΈβœ”οΈβœ”οΈβœ”οΈ

From this table you can see that if you need the 6 PWM mode for your application you should avoid using the families with ❌ sign.

Also, for ESP32 board the situation is confusing as only those ESP32 chips with a built-in MCPWM peripheral can do the 6 PWM mode. While most ESP32 chips do support it, a few of them (like the C3), don’t have MCPWM support. These chips are still supported via their LEDC peripheral, but can’t do 6 PWM.

Even though all the MCUs from the table above (and many more) are supported in the library and all of the will work with most of the BLDC motors+BLDC driver+sensor combinations, their performance will not be the same. So here is a quick guide how to choose which MCU to use.

BoardFamilyloopFOC() + move() - encoderloopFOC() + move() - magnetic sensor SPIloopFOC() + move() - magnetic sensor I2C
HMBGC V2.2Arduino 8-bit800us (ipr = 0), ~10ms (ipr > 10000)(doesn’t support SPI)1100us
Arduino UNOArduino 8-bit800us (ipr = 0), ~10ms (ipr > 20000)1200us~1000us
BluepillSTM32200us (ipr = 0), ~1ms (ipr > 50000)300us~1000us
Nucleo-64STM32100us (ipr = 0), ~500us (ipr > 50000)200us~1000us
Arduino DUEArduino SAM200us (ipr = 0), ~800us (ipr > 50000)300us~1000us
ESP32 D1 R32ESP32100us (ipr = 0), ~500us (ipr > 50000)200us~1000us
Teensy3.1Teensy200us (ipr = 0), ~800us (ipr > 50000)300us~1000us
Nano 33SAMD21200us (ipr = 0), ~800us (ipr > 50000)300us~1000us

*ipr = interrupt callbacks per second.

In the table above you can a comparison of the execution times of the FOC loop for different MCUs. When you are deciding which MCU to use with your project please make sure that your loop execution time loopFOC() + move(), in the worst case, will not be greater 3-4ms. And for optimal performance your loop time should be under 2ms. Make sure to account for multiple motors.

The current sensing support for all the architectures is shown in the table below:

Arduino AVR (8-bit)βœ”οΈβŒβŒ
Arduino DUEβœ”οΈβŒβŒ
stm32 (in general)βœ”οΈβŒβŒ
stm32f1 familyβœ”οΈβœ”οΈ (one motor)❌
stm32f4 familyβœ”οΈβœ”οΈ (one motor)❌
stm32g4 familyβœ”οΈβœ”οΈ (one motor)❌
stm32l4 familyβœ”οΈβœ”οΈ (one motor)❌
stm32f7 familyβœ”οΈβœ”οΈ (initial)❌
stm32 B_G431B_ESC1βŒβœ”οΈ (one motor)❌
samd21βœ”οΈβœ”οΈ (one motor)❌
teensy4βœ”οΈβœ”οΈ(one motor)❌
Raspberry Pi Picoβœ”οΈβŒβŒ
Portenta H7βœ”οΈβŒβŒ
Renesas (UNO R4 Minima)❌❌❌

Most of the boards will support inline current sensing, and support for the low-side current sensing is available for esp32, stm32, teensy4 and samd21, which is the least well tested.

Gimbal controllers

Gimbal controllers are the most simple and surely the cheapest solution for running FOC algorithm with your gimbal motor. They are perfect for smooth position/velocity controlling two BLDC motors with sensors if you don’t have high constraints on dynamics. Their main disadvantage is that they use all the external interrupt pins for PWM signals and therefore you cannot access them from outside. That would mean that even if you only need one motor (3 PWMs) you will still not be able to use pin 2 and 3 for encoder A and B signals. This means, if you are planing to use encoders with these boards you will need to use software interrupts. The good news is that this will work, the bad news is that the performance of counting encoder signals will be impaired. So I would suggest you to use Magnetic sensors with communication interface (SPI, I2C…) with these boards if possible.

Don’t let this discourage you from using the gimbal controllers with FOC, just be aware of possible side-effects when deciding which motor and sensor to use.

Make sure your gimbal controller has communication interface pins you need, available before buying it.

Arduino MCUs

Arduino devices, such as UNO, MEGA, NANO and similar, are probably the most commonly used microcontrollers there is, and therefore probably with this library as well. The simplicity of using these boards si incomparable. If you are planning to run this library with the Arduino device I would certainly suggest you to think about using Magnetic sensors instead of encoders. Encoders are highly inefficient sensors (at least their implementation for Arduino UNO & MEGA) and due to constant counting the interrupt signals of the encoder produces a large difference of execution time depending on velocities you are driving your motor.

Encoder CPR: Rule of thumb for Arduino UNO/MEGA

For Arduino UNO, the maximum number of pulses/second should not exceed 20,000. After this value it start to have execution issues. Please take this in consideration when choosing the encoder and especially if using more than one motor.


If your CPR value is 10000, you will be able to spin your motor with max velocity 120rpm - 2 rotations/second

Additionally Arduino UNO has only two encoder interrupt pins and if you are running two motors with encoders on your Arduino UNO you will be forced to use software interrupt callback which introduce additional augmentation in execution times. Arduino MEGA has 6 interrupts and you should not have this problem.

This library will enable you to use Arduino UNO/MEGA as your FOC brain and you can still do a lot of cool stuff with it even with two motors. Just be aware of the role of thumb if you are using the encoders.

STM32 devices

Stm32 devices are probably the best choice for the FOC implementation MCU. They are very powerful and have many external interrupt pins. They don’t loose too much performance due to counting and have much lower loop times making the FOC algorithm much smoother. Stm32 Bluepill can run up to 4 BLDC motors without a problem and Nucleo-64 can run 6+.

The biggest problem of using the STM32 boards in the community is the complexity of programming these devices. But since they have been integrated into the Arduino IDE even this is not a problem any more. Arduino SimpleFOClibrary code for stm32 devices is exactly the same as for Arduino UNO except the different pin numbers. Therefore I strongly urge you to consider using these devices in your projects because the results are awesome. πŸ˜ƒ

Arduino SimpleFOCShield is completely compatible with Nucleo-64 devices. And from the shield version 1.3.1 you will be able to stack 2 of the shields with the Nucleo boards as well.

ESP32 devices

ESP32 devices are very interesting choice for running this library. They have superb communication interfaces and they move the user interaction with the motor to the next level. ESP32 devices are, in theory, capable of running 4 BLDC motors at the same time with this library. ANd their performance will be much better than the one of the Arduino devices. Especially since they don’t have problems with external interrupt limitations.

There are two main problems when using ESP32 boards with for real time motor control.

  • ESP32 boards were not originally designed for precise real-time control tasks, they have exceptional communication capabilities, therefore sometimes you can have some strange problems due to this fact. But in 99% of situations this board will perform exceptionally well, it is just if you were planning bring it to its limits when the strange things can happen.
  • The other problem of this board is the pinout limitations. Make sure, if you are new with the ESP32, that you watch this YouTube video. On startup some of the GPIOs have to be in specific states in order to the ESP32 to boot normally. But this is not a big problem once you get used to it!

This board has a lot of benefits and it seems like we will see much more of it in the domain of real-time motor control in future.

SimpleFOC Community

If you have ported the library to another device or you are searching for help to port it to some specific device don’t hesitate to post in community forum

It is always helpful to hear the stories/problems/suggestions of people implementing the code and you might find a lot of answered questions there already!