Stepper motors are great for position control. They can be found in desktop printers, plotters, 3d printers, CNC milling machines, and anything else requiring precise position control.
### Pros
- Excellent position accuracy
- High holding torque
- High reliability
- Most steppers come in standard sizes
### Cons
- Small step distance limits top speed
- It's possible to "skip" steps with high loads
- Draws maximum current constantly
We will be using bipolar stepper motors. Compared to unipolar stepper motors, bipolar steppers require more complicated circuitry (in order to switch polarities) but are stronger by weight.
Microstepping is a method of controlling stepper motors, typically used to achieve higher resolution or smoother motion at low speeds. Microstepping control divides each full step into smaller steps to help smooth out the motor’s rotation, especially at slow speeds. For example, a 1.8 degree step can be divided up to 256 times, providing a step angle of 0.007 degrees (1.8 ÷ 256), or 51,200 microsteps per revolution.
Microstepping is achieved by using pulse-width modulated (PWM) voltage to control current to the motor windings. The driver sends two voltage sine waves, 90 degrees out of phase, to the motor windings. While current increases in one winding, it decreases in the other winding. This gradual transfer of current results in smoother motion and more consistent torque production than full- or half-step control.
We keep a number of chopper drivers around the lab:
- The most common, and cheapest, is the A4988 Driver. It works with voltages from 8-35 V, so it won't work for driving a stepper with 5 V.
- In order to work with lower voltages, we can use the DRV8834 Low-Voltage Stepper Driver. See our page on it here.
- Another, cheaper, low-voltage chopper driver is the STSPIN220. This works equally well, but pay attention to the wiring diagram.
Make sure to review the product description and datasheet for the device you plan to use.
_Note: These products can get hot enough to burn you long before the chip overheats. Take care when handling this product and other components connected to it._
### Stepper Motors
We have a number of different bipolar stepper motors in the lab. (We also have 28BYJ-48 unipolar steppers and drivers, but that's a separate topic).
Find motors around the lab and look up their data sheets, especially rated current/phase, voltage, and phase resistance (e.g. US-17HS441, 17HS19-2004S1, 17HS4401, etc.).
Let's use the [17HS19-2004S1](https://www.omc-stepperonline.com/nema-17-bipolar-59ncm-84oz-in-2a-42x48mm-4-wires-w-1m-cable-connector-17hs19-2004s1) for this example. Note some of the Electrical Specifications:
- Rated Current/phase: 2.0 A
- Voltage: 2.8 V
- Phase Resistance: 1.4 Ω
Our motors have a maximum current rating of 2 A with a 1.4 Ω coil resistance, which would indicate a maximum motor supply of 2.8 V. Using such a motor with a higher voltage would allow higher step rates, but the current must actively be limited to under 2 A.
Wire the board as described on the product page. Include a 100uF capacitor between the VCC and GND in order to protect the driver from voltage spikes.
At the most basic level, we can control the chopper driver simply by sending pulses to the STEP pin of the driver. Note: if you are using a driver with 4 wires connected to your MCU, you should use a different control program.
const int stepPin = 13;
const int dirPin = 12;
void setup() {
// put your setup code here, to run once:
pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);
digitalWrite(dirPin, LOW);
}
void loop() {
// put your main code here, to run repeatedly:
digitalWrite(stepPin, LOW);
delay(50);
digitalWrite(stepPin, HIGH);
delay(50);
}
Switching the DIR pin from LOW to HIGH will reverse the direction of the motor.
We can choose a library to help simplify control of stepper motors. The Arduino Stepper Motor Library supports differnt driver configurations. The AccelStepper library extends this functionality with acceleration/deceleration and non-blocking (no delay()) functions.
#include <AccelStepper.h>
const int stepPin = 13; // blue
const int dirPin = 12; // orange
// Define a stepper and the pins it will use
AccelStepper stepper(1, stepPin, dirPin); // initialise accelstepper for a two wire board
void setup()
{
}
void loop()
{
if (stepper.distanceToGo() == 0)
{
// Random change to speed, position and acceleration
// Make sure we dont get 0 speed or accelerations
delay(1000);
stepper.moveTo(rand() % 1000);
stepper.setMaxSpeed((rand() % 1000) + 1);
stepper.setAcceleration((rand() % 1000) + 1);
}
stepper.run();
}