SimpleFOClibrary support for STM32 boards

Hey Guys,

I am in the middle of implementing the SimpleFOClibrary for Stm32 boards. Even before I am finished with it I wanted to release you give you some updates about what can you expect form it and it would be very cool to have some feedback from you guys!

I am primarily testing the code on Bluepill board and Nucleo64 stm32f401re, but most of the nucleo and bluepill boards are the same and you should have no problems running the library with them.

You will be able to use the the same Arduino IDE to upload the code. The sketch code and all the library features will stay the same, basically you will be able to upload your Arduino UNO, change the board type in the Arudino IDE, change the serial port and upload your Nucleo board directly.

The benefits of using stm32 boards are numerous, for example:

  • The PWM frequency is much higher - less noise
  • The clock is much higher - much faster execution (Arduino UNO 1ms/loop - Nucleo 100us/loop)
  • No performance problems reading encoders
  • You can attach encoder to any pin
  • Much more internal memory

To enable using the Arudino IDE I am using stm32duino project. I found it very very simple and with almost no changes I was able to run SimpleFOClibrary on Nucleo64 and Bluepill.

Hardware setup

Here are some photos of my setups:

Arduino IDE configuration

And the difference in configuration:

To run the same motor with Arduino SimpleFOCShiled using an Arduino UNO or Nucleo board you will run exactly the same sketch. You will initialize the BLDCMotor and Ecnoder class using the hardware pins and configure them exactly the same in setup() and run the exaclty the same loop() code.

//  BLDCMotor( int phA, int phB, int phC, int pp, int en)
BLDCMotor motor = BLDCMotor(5, 6, 9, 11, 7);

//Encoder(int encA, int encB , int cpr, int index)
Encoder encoder = Encoder(2, 3, 8192);

The only difference in comparison to a Bluepill board is the pinout. Since it ddoesnt have arduino headers you will need to specify the pins you wish to use with the BLDCMotor class and Encoder class. For example:

//  BLDCMotor( int phA, int phB, int phC, int pp, int en)
BLDCMotor motor = BLDCMotor(PB7, PB8, PB9, 11, PB6);

//Encoder(int encA, int encB , int cpr, int index)
Encoder encoder = Encoder(PB3, PB4, 8192);

As simple as that :smiley:


I am still in a process of implementing properly the magnetic sensors as504x and as soon as I have stable behavior the new library version will be released. I hope it will be in this week .
I am very excited to be enable using the stm32 chips so elegantly using the stm32duino.

Let me know what you think!

1 Like

Fantastic thank you so much for this library I had so many little BLDC motors from projects and its really fun to tune them all and see what they can do. I already used your library to test out using them on our little robots and its such an improvement. I dont seem to be able to get the arduini_minimal_magnetic to compile this morning though:(
BTW I guess there is enough pins on the blue pill to manage 3 BLDC motors right?

Hey @Adam_Donovan!
The version 1.3.0 is out so from now on it should be very easy to use this library with the stm boards :smiley:

I have updated the minimal branch this today to the new library version maybe it resolves your issues. But if you find something that makes compiling problems please don’t hesitate to post a Github issue!

I just checked in the STMCubeMX and Bluepill has 4 timers out of which you can use 3 of them in PWM mode and each of the three has 4 PWM channels. So you should be able to have at least 12 PWM output pins. So 4 motors potentially. :smiley:
But probably even more with some workarounds.


Fantastic cant wait to try that out later :smile:

I read the STM32 document. After you use STM32, SPI, ADC, serial… Can use more advanced DMA mode. This will make focloup faster and better

Unfortunately, these advanced applications are too difficult for me. I hope you can consider adding these functions

Hey Jack, DMA is very cool I agree and it would make a lot of improvements in communication interfaces I guess. But they are not really in my focus at the moment, since the code will become very specific to the STM boards.
At the moment the library is trading off the optimality for simplicity. :slight_smile:
Anyway, for example one thing that is a pity that the library doesn’t use are stm’s counters, instead of external interrupts.

If you really need the DMA for some reasons we can discuss it, but in general I don’t think we will go in that direction in near future.

Thank you very much.

As you said, simplefoc is first applied to Arduino UNO. As long as the project is still in progress, consider it slowly

Hi Antun,
I would say that it is straight forward to support the VESC architecture/controllers when supporting STM32. But I don’t know what is the strategic way you want to go with this library.

The VESC 6 hardware is high integrated, open source, well documented reliable and powerful. Beside this it is really cheap. Controllers are around €60 on aliexpress.
They use STM32F405 at 168 MHz. As far as I know they have also DSP functionality. Could be perfect to calculate the sine waves and transformations. USB is on board. Also 4 SPI channels…

As soon as you have implemented the current control loop and probably the Hall-sensor support there would no obstacle to port it to the VESC. This could give the SimpleFOC project a broad visibility.

The SimpleFOC library is not that overloaded as the VESC Tool and firmware. I think you could create the better VESC. Not for everyone but for the people that are willing to go deeper into the issue.

Probably I have overseen something, but this was my first idea when reading this thread.

I worked now for a while with the STM32 implementation of SimpleFOC. It is working fine, so far. I have just two suggestions:

  1. 50kHz is really silent, but it is pretty high if you are pushing a lot of current through the mosfets. The switching losses are increasing and also the skin effect in the wires are rising. Everyone can adjust this by his own in focutils.cpp, but maybe a hint in doc or a variable in defaults.h could be helpful to users that don’t want to go that deep inside.

  2. Beside setting the frequency for PWM on a STM32 you also can set the AnalogWriteResolution(bits).
    Especially for the guys with the very low resistance motors the default resolution is a little rough.
    If Voltage source is 12V and the resistance is 0.05 Ohms every 4 steps are 1 amp in change at the standard resolution.
    As far as I have tested some improvements you can either define an output-pin as “PWM” instead of “OUTPUT” what sets the maximum resolution of 65536 or use AnalogWriteResolution(bits) what is a little more flexible.

For sure item 2 doesn’t work out-of-the-box and need some further adjustment of the SimpleFoc-Library.


I have tried the new version library for stm32, however, in my case, it did not work.
My target is to enable tim1_ch1(PA8), tim1_ch2(PA9), tim1_ch3(PA10)

The code is like this:
BLDCDriver3PWM driver = BLDCDriver3PWM(PA8,PA9, PA10)

I know the pins should be remapped, but what is the correct way to fix it?
@Owen_Williams Do you have any idea?

@Antun_Skuric Could you give me any ideas? I am stuck because of this.

Hey Axe, which STM32 are you using?

Is it closed-loop or open-loop that is not working?

open-loop velocity control
Bluepill board.
In fact, if I choose B6, B7, B8 as PWM Pin, It works well.