Control Stepper Motor with DRV8825 Driver Module & Arduino

If you are planning to build your own 3D printer or CNC machine then you will need to control a bunch of stepper motors. And having only one Arduino to control all of them can take a lot of processing and leave no room for anything else; Unless you use a self-contained dedicated stepper motor driver – DRV8825.

It can control both the speed and the spinning direction of a bipolar stepper motor like the NEMA 17 with just two pins. How cool that is!

Do you know how stepper motors work?

Stepper motors use a cogged wheel and electromagnets to rotate the wheel one ‘step’ at a time.

Each HIGH pulse sent energizes the coil, attracting the teeth closest to the cogged wheel and driving the motor one step forward.

stepper motor working animation

The way you pulse these coils greatly affects the behavior of the motor.

  • The sequence of pulses determines the spinning direction of the motor.
  • The frequency of the pulses determines the speed of the motor.
  • The number of pulses determines how far the motor will turn.

DRV8825 Stepper Motor Driver Chip

At the heart of the module is a microstepping driver from Texas Instruments – DRV8825. It is smaller in stature (only 0.8″ × 0.6″) but still packs a punch.

DRV8825 Stepper Motor Driver Module

The DRV8825 stepper motor driver has an output drive capacity of up to 45V. Which lets you control a bipolar stepper motor such as the NEMA 17 at up to 2.5A output current per coil.

The driver has a built-in translator for easy operation. This reduces the number of control pins to just two, one for controlling the steps and the other for controlling the spinning direction.

The driver offers six different step resolutions such as full-step, half-step, quarter-step, eighth-step, sixteenth-step and thirty-second-step.

Technical Specifications

Here are the specifications:

Motor output voltage8.2V – 45V
Logic voltageBuilt-In 3.3V output
Continuous current per phase1A
Maximum current per phase2.5A
Microstep resolutionfull, 1/2, 1/4, 1/8 and 1/16

For more details, please refer below datasheet.

DRV8825 Motor Driver Pinout

The DRV8825 driver has a total of 16 pins that connect it to the outside world. The connections are as follows:

DRV8825 Stepper Motor Driver Pinout

Let’s get acquainted with all the pins one by one.

Power Pins

Unlike other typical stepper motor drivers, the DRV8825 has only one power supply connection.

DRV8825 Stepper Motor Driver Motor Power Supply Pins

VMOT and GND MOT supplies power to the motor. You can connect an input voltage anywhere between 8.2V to 45V to this pin.

The module does not have any logic supply pin; because the DRV8825 draws its power from the motor power supply using an internal 3V3 voltage regulator. However, you should connect your microcontroller’s ground to the GND LOGIC pin.

According to the datasheet, the motor supply requires a suitable decoupling capacitor close to the board to be able to sustain 4A.

Warning:

This driver has low-ESR ceramic capacitors on board, which makes it vulnerable to voltage spikes. In some cases, these spikes can exceed the 45V (the DRV8825’s maximum voltage rating), potentially permanently damaging the board and even the motor.

One way to protect the driver from such spikes is to put a large 100μF (at least 47μF) electrolytic capacitor across the motor power supply pins.

Microstep Selection Pins

The DRV8825 driver allows microstepping by dividing a singular step into smaller steps. This is achieved by energizing the coils with intermediate current levels.

For example, if you choose to drive the NEMA 17 (with 1.8° step angle or 200 steps/revolution) in quarter-step mode, the motor will produce 800 microsteps per revolution.

DRV8825 Stepper Motor Driver Microstep Selection Pins

The DRV8825 driver has three step size(resolution) selector inputs namely M0, M1 and M2 . By setting the appropriate logic levels for these pins we can set the motor to one of six step resolutions.

M0M1M2Microstep Resolution
LowLowLowFull step
HighLowLowHalf step
LowHighLow1/4 step
HighHighLow1/8 step
LowLowHigh1/16 step
HighLowHigh1/32 step
LowHighHigh1/32 step
HighHighHigh1/32 step

These three microstep selection pins are pulled LOW by internal pull-down resistors, so if you leave them unconnected the motor will operate in full step mode.

Control Input Pins

The DRV8825 has two control inputs – STEP and DIR.

DRV8825 Stepper Motor Driver Motor Control Pins

STEP input controls the microsteps of the motor. Each HIGH pulse sent to this pin drives the motor according to the number of microsteps determined by the microstep selection pins. The faster the pulses, the faster the motor will spin.

DIR input controls the spinning direction of the motor. Pulling it HIGH drives the motor clockwise and pulling it LOW drives the motor counterclockwise.

If you want the motor to spin in only one direction, you can connect the DIR directly to VCC or GND accordingly.

Pins For Controlling Power States

The DRV8825 has three separate inputs to control its power states – EN, RST, and SLP.

DRV8825 Stepper Motor Driver Power States Control Pins

EN pin is an active low input. When this pin is pulled LOW the DRV8825 driver is enabled. By default this pin is pulled low so the driver is always enabled unless you pull it high.

SLP pin is an active low input. Pulling this pin LOW puts the driver into sleep mode, minimizing power consumption. You can use this especially when the motor is not in use to save power.

RST is also an active low input. When this pin is pulled LOW, all STEP inputs are ignored. It also resets the driver by setting the internal translator to a predefined home state. Home state is basically the initial position from where the motor starts and it varies depending on the microstep resolution.

Fault Detection Pin

The DRV8825 also features a FAULT output that drives LOW whenever the H-bridge FETs are disabled as the result of over-current protection or thermal shutdown.

DRV8825 Stepper Motor Driver Fault Detection Pins

Actually the Fault pin is shorted to SLEEP pin so, whenever the Fault pin is driven LOW, the whole chip is disabled. And it remains disabled until either RESET, or Motor Voltage VMOT is removed and reapplied.

Output Pins

The output channels of the DRV8825 motor driver are broken to the side of the module with pins B2, B1, A1 and A2 pins.

DRV8825 Stepper Motor Driver Motor Connections

You can connect any small to medium sized bipolar stepper motor like NEMA 17 to these pins.

Each output pin on the module can deliver up to 2.5A to the motor. The amount of current supplied to the motor, however, depends on the system’s power supply, cooling system, and current limiting setting.

Cooling System – Heatsink

Excessive power dissipation of the DRV8825 driver IC results in a rise in temperature that could potentially damage the IC if it exceeds its capacity.

Even though the DRV8825 driver IC has a maximum current rating of 2.5A per coil, the chip can only supply about 1.5A per coil without overheating. To get more than 1.5A per coil, a heat sink or other cooling method is required.

DRV8825 Stepper Motor Driver Heatsink

The DRV8825 driver usually comes with the heatsink. It is advisable to install it before use.

Current limiting

You have to make a small adjustment before running the motor. You need to limit the maximum amount of current flowing through the stepper coils and prevent it from exceeding the rated current of the motor.

DRV8825 Stepper Motor Driver Current Limiting Potentiometer

To set the current limit, a small trimmer potentiometer is provided on the DRV8825 driver.

There are two methods for making this adjustment:

Method 1:

In this method the current limit is determined by measuring the voltage (Vref) at the “ref” pin.

  1. Take a look at the datasheet for your stepper motor. Note down its rated current. In our case we are using NEMA 17 200steps/rev, 12V 350mA.
  2. Put the driver in full-step mode by disconnecting the three microstep selection pins.
  3. Hold the motor in a fixed position without clocking the STEP input.
  4. Measure the voltage (Vref) on the metal trimmer pot as you adjust it.
  5. Adjust the Vref voltage using the formula

    Vref = Current Limit / 2

    For example, if your motor is rated for 350mA, you would adjust the reference voltage to 0.175V.
measuring vref voltage setting current limit for drv8825 with multimeter

An easy way to make this adjustment is to use an alligator clip on the shank of a metal screwdriver and connect it to your multimeter so you can measure and adjust the voltage at the same time.

Method 2:

In this method the current limit is determined by measuring the current running through the coil.

  1. Take a look at the datasheet for your stepper motor. Note down its rated current. In our case we are using NEMA 17 200steps/rev, 12V 350mA.
  2. Put the driver in full-step mode by disconnecting the three microstep selection pins.
  3. Hold the motor in a fixed position without clocking the STEP input.
  4. Place the ammeter in series with one of the coils on your stepper motor and measure the actual current flowing.
  5. Take a small screwdriver and adjust the current limit potentiometer until you reach the rated current.
measuring coil current setting current limit for drv8825 with multimeter

If you ever change the logic voltage (VDD) you will need to redo this adjustment.

Wiring a DRV8825 Stepper Motor Driver to an Arduino

Now that we know everything about the driver, let’s connect it to our Arduino.

The connections are quite simple. Start by connecting RST pin to the adjacent SLP/SLEEP pin and both to the 5V on the Arduino to keep the driver enabled.

Connect GND LOGIC pin to the ground pin on the Arduino. Connect the DIR and STEP input pins to the #2 and #3 digital output pins on the Arduino.

Connect the stepper motor to the B2, B1, A1 & A2 pins. Actually DRV8825 is conveniently laid out to match the 4-pin connector on several bipolar motors so, that shouldn’t be a problem.

Warning:

Connecting or disconnecting the stepper motor while the driver is in operation may destroy the driver.

Remember to keep the microstep selection pins disconnected to operate the motor in full step mode.

Finally connect the motor power supply to the VMOT and GND MOT pins. Remember to put a large 100μF decoupling electrolytic capacitor across the motor power supply pins to avoid large voltage spikes.

Wiring Nema 17 Stepper Motor to DRV8825 driver & Arduino
Wiring Nema 17 Stepper Motor to DRV8825 driver & Arduino

Arduino Code – Without a Library

The following sketch will give you a complete understanding on how to control the speed and spinning direction of a bipolar stepper motor with the DRV8825 stepper motor driver and can serve as the basis for more practical experiments and projects.

// Define pin connections & motor's steps per revolution
const int dirPin = 2;
const int stepPin = 3;
const int stepsPerRevolution = 200;

void setup()
{
	// Declare pins as Outputs
	pinMode(stepPin, OUTPUT);
	pinMode(dirPin, OUTPUT);
}
void loop()
{
	// Set motor direction clockwise
	digitalWrite(dirPin, HIGH);

	// Spin motor slowly
	for(int x = 0; x < stepsPerRevolution; x++)
	{
		digitalWrite(stepPin, HIGH);
		delayMicroseconds(2000);
		digitalWrite(stepPin, LOW);
		delayMicroseconds(2000);
	}
	delay(1000); // Wait a second
	
	// Set motor direction counterclockwise
	digitalWrite(dirPin, LOW);

	// Spin motor quickly
	for(int x = 0; x < stepsPerRevolution; x++)
	{
		digitalWrite(stepPin, HIGH);
		delayMicroseconds(1000);
		digitalWrite(stepPin, LOW);
		delayMicroseconds(1000);
	}
	delay(1000); // Wait a second
}

Code Explanation:

The sketch starts with defining the Arduino pins to which the DRV8825’s STEP and DIR pins are connected. A variable called stepsPerRevolution is also defined. You can set it to match your stepper motor specifications.

const int dirPin = 2;
const int stepPin = 3;
const int stepsPerRevolution = 200;

In the setup section of the code, all motor control pins are configured as digital OUTPUT.

pinMode(stepPin, OUTPUT);
pinMode(dirPin, OUTPUT);

In the loop section, the motor is rotated slowly clockwise and then rapidly counterclockwise with an interval of one second.

Controlling the Spinning Direction: The DIR pin is set HIGH or LOW to control the spinning direction of the motor. A HIGH input will turn the motor clockwise and a LOW one will make it turn counterclockwise.

digitalWrite(dirPin, HIGH);

Controlling Speed: The speed of the motor is determined by the frequency of pulses sent to the STEP pin. The higher the pulses, the faster the motor runs. A pulse is nothing but pulling the output HIGH, waiting a bit then pulling it LOW and waiting again. By changing the delay between two pulses, you change the frequency of those pulses and consequently the speed of the motor.

for(int x = 0; x < stepsPerRevolution; x++) {
	digitalWrite(stepPin, HIGH);
	delayMicroseconds(1000);
	digitalWrite(stepPin, LOW);
	delayMicroseconds(1000);
}

Arduino Code – Using AccelStepper library

Controlling a stepper without a library is perfectly fine for simple, single motor applications. But when you want to control multiple steppers, you’ll need a library.

So for our next experiment we will be using an advanced stepper motor library called AccelStepper library. It supports:

  • Acceleration and deceleration.
  • Multiple simultaneous steppers, with independent concurrent stepping on each stepper.

This library is not included in the Arduino IDE so you will need to install it first.

Library Installation

To install the library navigate to Sketch > Include Libraries > Manage Libraries… Wait for Library Manager to download the library index and update the list of installed libraries.

manage libraries

Filter your search by typing ‘accelstepper‘. Click on the first entry and then select Install.

installing accelstepper library

Arduino Code

Here is the simple sketch that accelerates the stepper motor in one direction and then decelerates to come to rest. Once the motor makes one revolution, it changes the spinning direction and continues to do so over and over again.

// Include the AccelStepper Library
#include <AccelStepper.h>

// Define pin connections
const int dirPin = 2;
const int stepPin = 3;

// Define motor interface type
#define motorInterfaceType 1

// Creates an instance
AccelStepper myStepper(motorInterfaceType, stepPin, dirPin);

void setup() {
	// set the maximum speed, acceleration factor,
	// initial speed and the target position
	myStepper.setMaxSpeed(1000);
	myStepper.setAcceleration(50);
	myStepper.setSpeed(200);
	myStepper.moveTo(200);
}

void loop() {
	// Change direction once the motor reaches target position
	if (myStepper.distanceToGo() == 0) 
		myStepper.moveTo(-myStepper.currentPosition());

	// Move the motor one step
	myStepper.run();
}

Code Explanation:

The sketch starts by including the newly installed AccelStepper library.

#include <AccelStepper.h>

First the Arduino pins are defined to which the STEP and DIR pins of the DRV8825 are connected. The motorInterfaceType is also set to 1 (1 means an external stepper driver with step and direction pins).

// Define pin connections
const int dirPin = 2;
const int stepPin = 3;

// Define motor interface type
#define motorInterfaceType 1

After this, an instance of stepper library named myStepper is created.

AccelStepper myStepper(motorInterfaceType, stepPin, dirPin);

In the setup function, first the maximum speed of the motor is set to 1000. Then an acceleration factor is set for the motor to add acceleration and deceleration to the movements of the stepper motor.

After this, the regular speed has been set to 200. And since the NEMA 17 takes 200 steps per turn, the number of steps the motor is going to take has also been set to 200.

void setup() {
	myStepper.setMaxSpeed(1000);
	myStepper.setAcceleration(50);
	myStepper.setSpeed(200);
	myStepper.moveTo(200);
}

In the loop function, an If statement is used to check how far the motor needs to travel (by reading the distanceToGo property) until it reaches the target position (set by moveTo). Once distanceToGo reaches zero, the motor is rotated in the opposite direction by changing the moveTo position to negative of its current position.

Now at the bottom of the loop you will see that a run() function is called. This is the most important function because the stepper does not move until this function is executed.

void loop() {
	if (myStepper.distanceToGo() == 0) 
		myStepper.moveTo(-myStepper.currentPosition());

	myStepper.run();
}