Introduction: Drive a Stepper Motor With an Arduino and a A4988 Stepstick/Pololu Driver
There are several ways to make a Stepper Motor run, and the best way will depend on the application, the motor and the electronics available. For running a stepper motor from an Arduino these are the main ways to go
1. A ULN2003 Darlington driver board. Typically sold with small geared steppers this requires four digital pins and the Arduino sketch needs to directly drive each coil
2. A driver board/shield with a constant voltage driver, such as the Adafruit Motor Shield. This runs over SPI (so only needs two pins) and can run many kinds of steppers and normal motors fine, unfortunately it couldn't run my steppers.
3. A 'chopper' driver that will vary the voltage to keep a constant current, such as the A4988 or the DRV8825 chip, either direct or via a board/shield such as the Stepstick or Pololu.
This instructable covers the third method, running one or more steppers via an A4988 IC on a StepStick board.
Step 1: A Little About Stepper Motors
There's lots of great resources out there about Stepper Motors, how they work and what kinds are available, I'd recommend
About Steppers on Adafruit Learn
Stepper motor page on RepRap wiki
I had acquired some Stepper Motors from Ebay, that didn't work well with the Adafruit Motor Shield. Looking at the specs the problem here was the resistance/current/voltage rating;
Rated Current/phase2.0A
Phase Resistance1.4ohms
Voltage2.8V
So, for Stepper motors, the resistance per phase is a constant. The Rated current is the MAXIMUM current the motor will take before bad things happen, and the voltage is the calculated voltage that will give a constant current at the rated current, for the motors resistance (V = I x R, V = 2.0A x 1.4Ohm = 2.8V).
The Adafruit stepper motor shield cant supply 2A,and has trouble with voltages below about 5V, so couldn't properly run my motors (they jittered but didn't smoothly move).
So, I got some stepsticks and decided to wire them up to my Arduino.
Other Materials
For this I also used;
An Arduino Uno, but any Arduino compatible should do
A Stepstick, or compatible stepper driver using a A4988 or DRV8825
A 12V power supply
A breadboard
Some hookup wire, I used solid Cat5 strands.
I also used a couple of LEDs and some 220Ohm resistors
Step 2: Wiring Up the StepStick and Arduino
The stepstick is an A4988 chip mounted on a small PCB with headers on either side. It's available in many places (Pololu). To use it it needs the following connections
- 4 connections to the stepper motor, marked 1A, 1B and 2A, 2B. Connect the first coil to 1A and 1B and the second coil to 2A and 2B.
- Logic Power and GND, Connect this to the GND and +5V of the Arduino
- Dir sets the direction the stepper will move. I connected this to Pin 4 on the Arduino
- Step will make the stepper step each time this pin goes form Low to High. I connected this to Pin 5 on the Arduino
- Enable. When this pin is pulled low the board is enabled and the motor energised. When set high the board is disabled and the motor is de-energised. I connected this to Pin 6 on the Arduino
- Sleep and Reset control the board, either sending it to sleep or resetting it. To use the board I tied these together which allows the board to run normally
- Motor Power and GND. This needs to be a high voltage/current supply to run the motor. I had a 12V, 2A wall Swart available. Do not connect this yet
See the fritzing diagram above. Next is loading an Arduino sketch and Setting the Current limit on the StepStick
Step 3: Initial Arduino Sketch
Here is the initial sketch I loaded to my Arduino
// Run a A4998 Stepstick from an Arduino UNO. // Paul Hurley Aug 2015 int x; #define BAUD (9600) void setup() { Serial.begin(BAUD); pinMode(6,OUTPUT); // Enable pinMode(5,OUTPUT); // Step pinMode(4,OUTPUT); // Dir digitalWrite(6,LOW); // Set Enable low } void loop() { digitalWrite(6,LOW); // Set Enable low digitalWrite(4,HIGH); // Set Dir high Serial.println("Loop 200 steps (1 rev)"); for(x = 0; x < 200; x++) // Loop 200 times { digitalWrite(5,HIGH); // Output high delay(10); // Wait digitalWrite(5,LOW); // Output low delay(100); // Wait } Serial.println("Pause"); delay(1000); // pause one second }
Load that into the Arduino Editor, Verify/Compile it, upload it to your Arduino. Remember, at this point the Arduino should be powered, but the Motor Power should be disconnected.
Step 4: Set the Maximum Current
To prevent damage to the driver chip, it uses circuitry to limit the maximum current that can be used. This is set via the adjustable resistor on the board, in co-operation with some of the other components, the sense resistors (S1 and S2) and the resistor (R1). As different drivers may have different components (especially generic Chinese imports) its best to check these values before continuing.
For my stepsticks S1 and S2 are marked 'R10' and R1 is marked '303' (in very small writing !). These correspond to 0.1Ohm for S1 and S2 and 30kOhm for R1. The trimpot should be 10kOhm
According to the A4998 datasheet, and substituting those values, gives
VREF max = (TrimpotMaxR/(TrimpotMaXR+R1)) x VDD = (10,000 / (10,000 + 30,000)) * 5 = 1.25V
ITripMAX (effectively max motor current) = VREF / ( 8 x Sense_resistor) = 1.25 / ( 8 * 0.1 ) = 1.5625A
To calculate amps from measured VREF: A = VREF / 0.8
To calculate VREF required for a target current: VREF = A * 0.8
As my stepper motors are 2.0A, I can't get maximum current from this driver, however,if I drive them at 70% (2.0A x 70% = 1.4A) I want to a VREF of 1.4A x 0.8 = 1.12V, plus driving them at 70% will reduce the temperature of the stepper.
I start with the trim pot turned anti-clockwise, and measure the voltage with my multimeter between the logic Gnd pin and the centre of the trimpot itself, slowly turning it up until I get just under 1.12V
Once that is done, you can connect the Motor power supply (12V). Hopefully your motor will start running !
If not, unplug the Motor power and recheck all the connections with a multimeter. Always unplug the motor power first, then the Arduino power before disconnecting the motor
Warning: Connecting or disconnecting a stepper motor
while the driver is powered can destroy the driver. (More generally, rewiring anything while it is powered is asking for trouble.)
Step 5: A More Complicated Program
Once you have this working, there’s several things you can do to expand.
Add another stepper (or more). Each driver needs at least two pins (step and dir) and possibly Enable. Use the same logic voltage, ground and motor voltage
Use the AccelStepper library to do fancier control of the stepper. Here's a sketch the randomly moves the stepper at random speeds and accelerations
// Run a A4998 Stepstick from an Arduino UNOusing AccelStepper // Paul Hurley Aug 2015 #include AccelStepper stepper(1,5,4);//initialise accelstepper for a two wire board, pin 5 step, pin 4 dir void setup() { Serial.begin(9600); pinMode(6,OUTPUT); // Enable digitalWrite(6,LOW); // Set Enable low } void loop() { digitalWrite(6,LOW); // Set Enable low 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() % 400); stepper.setMaxSpeed((rand() % 400) + 200); stepper.setAcceleration((rand() % 200) + 100); } Serial.println(stepper.distanceToGo()); stepper.run(); // Actually makes stepper move }