SimpleFOClibrary support for stepper motors

Hi guys,

I was thinking lately how simple would it be to extend the SimpleFOClibrary to support FOC for stepper motors.

I was also maybe thinking of creating a very simple arduino shield (StepperFOCShield) to control it. Based on L298N for example.
But the idea is to support any board with double full bridge (or at least as many as possible :smiley: ).

From the point of view of the code, what would change is that we need a new motor class. class StepperMotor. We would need a bit different pwm setting code, but this is a minor change.

Stepper motors use only two phases to work so we would not need park Clarke transfrom. It would be just Park. The equations of the space vector will change, but I am not even sure that we need them any more.

The cool thing with the extension of this library to the Stepper motors is that you would be able to use all the sensor implementations without any changes. :smiley:

I have not really done a thorough research to see if there is an interest from the community for an open-source code that would implement such a thing. Maybe it already exists.

Anyway, let me know what you think and if you think there is an interest for this.

I was thinking the same a few weeks back. They have a super high pole count so I imagine would be buttery smooth. Would they necessitate a high precision encoder due to the high pp?

I guess we could use any dual board in place of l298m e.g gimbal controller. The storm32 might be able to drive 2 steppers.

If I calculated right the pole count is 50 for regular 200 step stepper motor (nema 17 for example)

Which means that you need your encoder to be at least 200 to be able to do the commutation. So for micro-stepping equivalent of 16 you would need an encoder CPR of:

16*200 =3200

What is not too much. Especially since the sinusoidal waves would be used and not square ones.

Regarding the gimbal controllers, this will work as well. But for steppers we are required to have two full bridges (not half bridges) which means that one double three phase controller would be able to run one stepper and ha half :smiley:

But boards like this one will do the job:

My main usage of steppers is in open loop (CNC, 3D printers,…). For this (basic) usage you can find a lot of cheap drivers on internet (ex : easystepper)

So what would be the main driver to use simpleFoc ?
is it to jump to closed loop or to get a smoother commutation ? (see trinamic’s solutions :


In my opinion, there are several benefits of closing the loop of stepper motors.

Benefits versus open-loop stepper motors:

  • No missing steps
  • Backdrivable (torque control possibility)
  • Possible smoother operation - depending of a micro-stepping you are comparing to
  • Better performance
  • Lower power consumption - much lower

Benefits versus regular 3 phase bldc motors:

  • cheaper
  • simpler to find
  • smoother (more pole pairs)

that would be great to have it, can we support the step dir? so we can adapt to a closed loop brushless and use on cnc/laser cutter.

1 Like

Hey @bgvsan,

I was not really thinking to implement this as an option. This would be a bit as a step backwards in terms of control. But this can be easily integrated.

Here, I wanted to discuss the dynamics of stepper motors and the potential to use it with the Arduino and similar boards.

But you are right that it would be cool to have this option as well. But in my opinion the library will not support this internally.
I will try to provide an example code to create this behavior in the next release of the library.

1 Like

I do agree that a close loop system with a “standard” step/dir interface (for a stepper) would be a great product.
My idea would then be to simply replace the current driver by this new one (even if an ESP32 or an arduino is needed). simple replacement of the driver by a plug and play backward compatible one (but with no loss of steps !)

@freedom2000 - the easystepper (a4988) and similar drv8825 do a great job of openloop and are cheap (~$2) but they waste energy and/or can lose position. So IMHO SimpleFOC + steppers only makes sense in closed loop particularly where energy is important.

I kind of agree that it might be a solution looking for a problem!

As @Owen_Williams pointed out, the stepper drivers do a great job. More than enough for 99% of applications. Especially for position control.

Implementing FOC just to avoid loosing steps would be a bit stupid. There a lot simpler ways to solve this problem. So in that sense it is merely a consequence of this type of control, not the goal.
As well as the step/for interface. It can be implemeted but is very very constraining. It can be implemeted to support legacy software, but for me this is not the goal at all.

What motivates me is that stepper motors will be more smoother than the regular BLDC motors, they will not draw too much current, they will be capable of pretty high loads, they are standardized in terms of size and they are everywhere.
Also, you don’t really think about stepper motors in terms of FOC control, even though it perfectly makes sense.
And finally, it is not a big change in code :slight_smile:

So as you can see guys, I already kida decided :smiley:

Wisely said :ok_hand:

1 Like

Hey guys,
Just a quick update.
I implemented the foc support for stepper motors. I am very happy with the results and especially with the simplicity. Basically all you need to do is change the line:

//  BLDCMotor( phA, phB, phC, pp, (en optional))
BLDCMotor motor = BLDCMotor(9, 13, 5, 11, 8);


//  StepperMotor(ph1A,ph1B,ph2A,ph2B,pp,( en1, en2 optional))
StepperMotor motor = StepperMotor(9, 5, 10, 6, 1, 8);

nothing else in code you won’t need to change to run the FOC on steppers :smiley:

If someone has L298n or two SimpleFOCShields or a gimbal controller with two bldc motor terminals you’ll be able to test it directly :smiley:

The code is in the dev branch.

Hey guys,
I just wanetd to share my setup:

  • regular nema17 steppr motor
  • CUI AMT103 encoder directly on its shaft.
  • 2x Arduino SimpleFOCShield
  • 3s lipo battery

Here is a quick video of the backdrivability of the stepper motor. It is a bit strange to see this, since I’m always picturing stepper motor with the the characteristic noise and stiffness.


Thanks Antun, I’ve tried it out and it’s working great! :clap: :clap: :grinning:

Here is a video with two steppers using 1x storm32 controller:

1 Like

Please do.
This is what I’m looking for.
Thanks by the way Anton.
Your link to this group has been a great read.
I want to use the step direction /step from conventional printer board, then run a linear ironless servo motor with a encoder.
I have found a leadshine servo driver that goes just that.
But this system might be more configurable.
It’s a ACS606 .
Would this do the same thing with out to much Hart ache.
Thanks in advance

This is wreally Wow !

Considering adding a 4th halfbridge to the Dimmer and make the current sensor sensitive in the lower regions :stuck_out_tongue:

What I have discovered with the Nema 23 is that they do pull a lot of juice. Monitoring the current would in that regard be a nice to have.

And for our next trick! Controlling high current LED strings 100w grow light from a single PSU 500w: (Edit: Maybe 250w total per lamp / 4 strings = 62.5w per string = (12v) 5.2 amp per string)( = 150um copper = 3mm (24amp total) main pwr line.)

2.Edit: Considering using a bidirectional current sensor. Would you agree, that two bidirectional current sensors is enough to monitor the 4 wires to the steppers 2 windings alternating current flow.

  1. Edit: This 4th halfbridge, could actually control the valve (solenoid) sitting on the openPNP nozzle/head. In that regard a 4th current sensor it is.

  2. Edit: Can you trick a stepper driver intro driving two 12v coolers/fans?

  3. Edit: I have been in contact with MAX integrated. The WLP package MAX40056 will be available next year.

  4. Edit: PS. I like this editing feature and controlling the pnp machine with dedicated subrivers like i kinda understand is where you are getting at, will effectively turn the machine intro a hexacore. One controller per nozzle (4 nozzle confiq.) One for each X and Y axis. Maybe even a small IC per feeder. The camera’s in them selves are small cores. So octa core with the two cameras.

  5. Edit: I will constrain the dimensions (length) to the 42.5mm of the Nema 17. A small breakout with a angle sensor or the one you use for the shaft, will close the loop. Mounting this to a motor will need some kind of 3d printed bracket with a slot for the angle sensor.

Software wise, someone in the pnp community mentioned, that a Gcode interface would be sweet.

Regarding the interest from the community: take a look at mark’s work on S-curve motion control in the openPnp community. Maybe there is something there to be discovered…

Maybe there is a hidden file / tressure. All we need is single axis s-motion. Right?

Edit: Here is the Dimmer with a 4th half bridge (two full bridges). The lenght is exactly 42.5mm. MAX integrated state in the datasheet, that you can monitor the 3phases in a 3phase motor confiq, with only two MAX40056 sensors. This, i suppose, is because the phases is connected. Would you pay the extra (1.15$ per current sensor) and have a current sensor on each phase. I guess you can control a solenoid without, by just feeling how hot it gets over time, and adjusting the pwm if it gets hot.

In order to use the bidirectional properties of the current sensor, i think i have to measure directly on the phase and not on the high side, as you se here.

  1. Edit: Regarding controlling power LED´s, the temperature of the individual lamp and/or string is quite important. Really you can se it just like the heated bed of a 3d printer, which you pwm control in order to dissipate heat. The objective is the same when driving LED´s, although most or alot of that energy will be emitted as light in different wavelengths. Yes a light controller. Which is why a temperature input or several inputs (one per string) in that regard would be important.

So why not just use a single MOSFET for driving LED´s you ask. Well we need those bridges man. And the heat rating for the MOSFET stays the same. Often the switching generated heat sets the limit for driving a MOSFET.


I tried the dev build but some problems.
I can get it to turn open loop, although at low velocity, similar to the video above, it won’t turn fast. In any case this is okay.
When trying it with the encoder, it seems to calibrate and picks up the motor direction, when sending a velocity or angle command it moves one step then locks up.

Any idea how to get it working?

Hey Jonathan
Could you give us a bit more info about the MCU, BLDC driver, stepper motor and the sensor you’re using.

Dev branch has gone through a lot of refactoring and it is possible that I broke something. :smiley:
Even though I have tested all the features a priori.


I’m using 2 of these:
STM32F767ZI Nucleo 144
Stepper motor is this one, 4 wire:
And a CUI AMT112 Incremental encoder, I removed the index portion and trying with only A/B

For the motor I’m using pins PE9, PE11, PE13 and PE14 since the default didn’t work enable pins aren’t used, the driver is bridged to enable, encoder is on default D2, D3 and 8192.

I’ve reduced frequency from the default 500000(I think this is a mistake in the firmware) to 20000.

Like I say open loop is fine but as soon as I try to put it into closed loop it will calibrate, the moment you send it a move command it will lock up. I see someone else is seeing something similar with a BLDC.

Hey Jonathan, 500000 is a mistake, I wanted to put 50khz. I’ll update this immediately.

Encoder class needs ppr(impulse per rotation) not cpr so make sure to put the right number. This might explain your problems.

You can try the encoder test example to se if you’re getting the good measurement. Beware: the angle is in radians.