Microstepping a stepper motor

I had planned to use a SparkFun ProDriver board to control the NEMA 8 stepper motor which I will use to drive my turntable on a T-TRAK module, but it would not behave properly in a test setup. I needed to demonstrate rotating a stepper motor using an Arduino-class microcontroller for an Arduino Day 2023 event I was putting on, so I ended up using an Adafruit Pro Trinket (5 volt 16 MHz version) driving a simple L293D quad half-bridge driver chip instead. This chip by itself does not support microstepping as the ProDriver is designed to do, where the 200 step/revolution stepper motor would move as if it were 400, 800, 1600… steps per revolution. This simple setup worked fine for demonstration purposes.

After the event, I decided to experiment with driving the stepper motor with the L293D in a non-standard way to do half-step microstepping. This turned out to be way more successful than I expected, so I decided to document here what I came up with. More information on stepper motors and how to drive them can be found on Wikipedia.

Full-step drive with both coils on

The typical four-wire bipolar stepper motor like the NEMA 8 motor I am using has two coils which are mechanically/electrically 90 degrees apart in phase. To get maximum torque during rotation, both coils are energized at the same time, and stepping is performed by reversing the polarity on the coils in sequence. Figure 1 below shows how this would work. The thick black arrow represents the total magnetic force produced by the two coils (red and blue arrows).

Figure 1: Full-step drive

If we assume each coil produces T units of torque, then since the coils are 90 degrees apart in phase, the total torque would be about 1.41 times T units, or more exactly T times the square root of 2.

Wave drive with one coil on

This drive method energizes only one coil at a time. The number of steps per rotation is the same as with full-step drive, with the stop positions halfway between those that full-step produces. Also, because at all times only one coil or the other is powered, the total magnetic torque is only T units, not √2 times T. Figure 2 below shows this.

Figure 2: Wave drive

This might be a bit clearer if we use an animation to show the stepping in action. Keep in mind that one full rotation in the animation is not a full rotation of the stepper motor, but four steps of the 200 step-per-rotation motor.

Half-stepping

Notice in the animation above that the head of the total-torque vector is moving around a circle, 90 degrees at a time. What if we make it take 8 steps, 45 degrees at a time, instead of 4 steps of 90 degrees? That means it would take 400 of these half-steps to get a full rotation… and we need to make those half-steps twice as fast as the full-steps or wave-steps took.

How do we accomplish this? We drive the coils with two GPIO pins on our microcontroller which are capable of PWM (pulse-width modulation) output. Then on our new half-step positions, each coil is being driven to 0.71 times T, more accurately T times √0.5. A little vector arithmetic shows that the total torque at these points is still T units.

But why stop there?…

Micro-stepping

What we’ve done is the first step into microstepping, by using PWM drive currents to produce as many substeps as we want between the original 200 wave steps per rotation.

Figure 5 shows what would happen if we used quarter-steps.

And Figure 6 shows eighth-step drive.

We could keep going, but there are good reasons not to push this too far.

  • Each time we cut the substeps in half, we have to double the rate at which we update the outputs to maintain the desired rotation speed of the whole motor.
  • The smaller the substeps, the less the change in the magnetic force vector between substeps, to the point where friction in the drive mechanism may cause tiny substeps to be missed.
  • Since an Arduino’s PWM-capable outputs only have resolution of 1 bit out of 256 possible values, the accuracy of the values produced for the substeps will be reduced.

For my turntable drive, I settled for eighth-step microstepping, because driving my stepper with 1600 microsteps per rotation will give me fine enough angular resolution on the turntable side of the belt drive at a manageable update rate of the drive signals. More information on the full drive design can be seen on these pages in this blog.