SimpleFOClibrary support for stepper motors

Hey @Owen_Williams,
I’m sorry for a bit of delay but I wanted to take some time to answer this question properly.

Two phase stepper motors supported by this library have following structure:

You can see that from the images it is possible to achieve positive and negative voltages on each phase separately. This was not possible for BLDC motors, for BLDC motors our goal was to set a certain voltage in between phases A,B and C. For stepper motor can set any voltage in between V_power_supply and -V_power_supply to each phase A and B.

Now the PWM modulation implemented in this library is the sinusoidal modulation where we only keep Inverse park transformation and discard the Clarke transformation.
Inverse park transformation for stepper motor is:

U_alpha = - Uq* sin(angle)
U_beta = Uq* cos(angle)

where Uq is the q component of the volatge we want to set to the motor and angle is the current electrical angle of the motor.

So for the certain Uq which is fixed, we will get U_alpha and U_beta as negative sine and cosine waves. So from the image which follows and the one before we can conclude that the pattern of the voltages applied to the 1A,2A,1B and 2V is as follows

Now if you look closely, this is exactly what you have plotted in your message.
I hope this makes things a bit more clear. :smiley:

Now in terms of problematics that have arisen for stepper motors I think I have an idea why the cutoff in velocity happens.

For each electrical rotation of the stepper motor, for each time the electrical angle goes form 0 to 360 degrees ( this happens pole_pairs number for one rotor revolution ), the absolute minimum number of FOC algorithm executions (the algorithm calculating sine and cosine waves) is 4.
Which means that for nema 17 motor with 50 pole pairs:

N = 50 x 4 = 200

This means, in order for your rotor to make a full revolution you need to execute Arduino loop() minimally 200 times. And if you are using an I2C sensor it is likely that your loop time is close to 1ms.

This basically means that one motor rotation cannot be faster than 200ms. or in other words 5 rotations per second. This doesn’t explain fully the behavior we are seeing but in my opinion this is the problem we are facing.
For Arduino UNO, with 500ppr encoder I cannot exceed velocity 5-6 rad/sec. If I plug the same setup to Nucleo board I can produce velocities well above 30rad/s.
I will make one proper video soon to demonstrate this.

Therefore @Owen_Williams, can you please tell us the average loop time you are having with you setup to see if this explains it. :smiley:

3 Likes