SimpleFOC port on STM32CubeIDE problem


I am quite new to the SimpleFOC library and I have been playing around with the DRV8302 example. I have successfully flashed and ran the DRV8302 example on an Arduino Mini.

Right now, I am trying to get a STM32 board running the HAL libraries from ST to work with the example. My setup is:

  • iPower Motor GM5208-24 Brushless Gimbal Motor (24N22P)
  • A generic STM32F103RCT6 Dev Board
  • 12V Supply
  • DRV8302 board from Aliexpress
  • AMT103 Encoder (I used all the A, B and Index pins)

I modified the library and used TIM1 (frequency: 25kHz, counter mode: center-aligned3) to drive all the 3 PWM pins. On initialization, I noticed the motor rotates smoothly to detect the Index pin. After that, the motor jerked and stopped immediately, idling at 0.08 - 0.1A.

I tried to change the controller to MotionControlType::angle and the motor vibrates violently after initialization, draining around 0.6-0.7A.

The very same parameters worked on the native library with Arduino Nano, so it is highly likely that I got a few bugs in the port.

Did I miss something when porting the code? Could this be a wiring problem? I really appreciate any suggestion for detecting and fixing the problem.


Dear @kilo-tons , welcome to SimpleFOC!

Do I understand you correctly that you ported the code to STM32CubeIDE - so HAL native, no Arduino framework?

If this is so, then the best case is the PID is sensitive to timings and loop execution speed, so you may just need to re-tune the PID values to get better results.

More likely is that there is some kind of problem in the port, maybe something to do with reading sensor values since open-loop seems to be working (used during alignment) while closed loop does not?

Some things to try:

  • is is working in open loop?
  • can you read the sensor values without the motor code (just using sensor.update() and sensor.getAngle())?
  • if all of this is working, but closed-loop is not, then try tuning the PID values
  • if you can’t get a tuning to work, then its probably some bug in the algorithm

May I ask why you port to STMCubeIDE rather than using Arduino framework for STM32? You can run the library directly on STM32 MCUs using Arduino IDE or PlatformIO and the STM32duino framework.

Hi @runger. Thank you for your suggestion.

I can only get my hand on the hardware next week, so in the meantime, I will take a look at the Sensor code in my port to find any bugs there.

I originally implemented a few functions using the native HAL library and I wanted to use them along with the simpleFOC library, so I decided to port the library to the HAL framework.

The SimpleFOC port is probably much more painful to do than re-writing a few lines of codes, but it’s too late for now and it might be nice to get it working, so I decided to stick with it :slight_smile:

Hi. I have solved the problem. I forgot to initialize the Sensor, along with a few weird problems in the firmware flashing procedure.

The example now generally works beautifully with the STM32 so far. However, I got a weird problem along the way.

When I added an RTOS and a few more threads in the equation, the MCU fails to detect the Index pin of the encoder. The external interrupt does trigger but after that, the MCU reads the Index pin as being LOW (I guess the overhead added by the RTOS created a few timing issues, along with the encoder outputting extremely short pulse?).

I took the liberty to read the Encoder.cpp file, and noticed that the the Index pin external interrupt is configured to CHANGE. It is highly likely that I am wrong but shouldn’t RISING or FALLING edge detection (depends on use-case) is suffice?

I modified the library to include that change, removed the debounce digitalRead() and the mentioned problem went away. So far, I haven’t encountered anything funny.


Hey, glad to hear it is working!

Thanks for reporting the interrupt problem.

We actually had a similar problem reported with the StepDirListener - the CHANGE interrupt combined with digitalRead() leads to timing dependent code - if the pulses are too short, or the interrupt gets delayed too long (due to other interrupts or interrupt disabling), the code “misses” the pulse.

1 Like