DRV8825 Arduino stepper motor wiring schematic diagram pinout

How to control a stepper motor with DRV8825 driver and Arduino

This article includes everything you need to know about controlling a stepper motor with the DRV8825 stepper motor driver and Arduino. I have included a wiring diagram, a tutorial on how to set the current limit, and many example codes.

Although you can use this driver without an Arduino library, I highly recommend you also take a look at the example code for the AccelStepper library at the end of this tutorial. This library is fairly easy to use and can greatly improve the performance of your hardware.

PCBWay

After each example, I break down and explain how the code works, so you should have no problems modifying it to suit your needs.

If you would like to learn more about other stepper motor drivers, then the articles below might be useful:


Supplies

Hardware components

DRV8825DRV8825 stepper motor driver× 1Amazon
Stepper MotorNEMA 17 stepper motor× 1Amazon
Arduino Uno Rev 3Arduino Uno Rev3× 1Amazon
Power supply (8.2-45 V)× 1Amazon
Breadboard× 1Amazon
capacitorCapacitor (100 µF)× 1Amazon
Jumper wires~ 10Amazon
USB cable type A/B× 1Amazon

I like to use this driver in combination with a CNC-shield or expansion board. Such a shield already includes capacitors and offers an easy way to select the microstepping resolution. It makes wiring much easier and is a great option if you need a more permanent solution than a breadboard.

Tools

Small screwdriverAmazon
multimeterMultimeterAmazon
Alligator test leads (optional)Amazon

Software

Arduino IDEArduino IDE

Makerguides.com is a participant in the Amazon Services LLC Associates Program, an affiliate advertising program designed to provide a means for sites to earn advertising fees by advertising and linking to products on Amazon.com.


About the driver

At the heart of the DRV8825 driver, you will find a chip made by Texas Instruments: the DRV8825 Stepper Motor Controller IC. This integrated motor driver makes interfacing with a microcontroller super easy as you only need two pins to control both the speed and the direction of the stepper motor.

The driver has a maximum output capacity of 45 V and ± 2 A which is great for driving small to medium-sized stepper motors like a NEMA 17 bipolar stepper motor.

If you need to control larger stepper motors like a NEMA 23, take a look at the TB6600 stepper motor driver. This driver can be used with the same code as the A4988 and has a current rating of 3.5 A.

The DRV8825 driver chip has several safety functions built-in like overcurrent, short circuit, under-voltage lockout, and over-temperature protection. You can find more specifications in the table below.

DRV8825 Specifications

Minimum operating voltage8.2 V
Maximum operating voltage45 V
Continuous current per phase1.5 A
Maximum current per phase2.2 A
Minimum logic voltage2.5 V
Maximum logic voltage5.25 V
Microstep resolutionfull, 1/2, 1/4, 1/8, 1/16 and 1/32
Reverse voltage protection?No
Dimensions15.5 × 20.5 mm (0.6″ × 0.8″)
CostCheck price

For more information you can check out the datasheet here.

Differences between DRV8825 and A4988

The DRV8825 is quite similar to the A4988 but there are some key differences:

  • The DRV8825 offers 1/32 microstepping, whereas the A4988 only goes down to 1/16-step. Higher microstepping results in smoother, quieter operation but is not always needed.
  • The current limit potentiometer is at a different location
  • The relation between the reference voltage and the current limit is different.
  • The DRV8825 requires a minimum STEP pulse duration of 1.9 µs, the A4988 requires 1 µs minimum.
  •  The DRV8825 can be used with a higher voltage motor power supply (45 V vs 35 V). This means it is less susceptible to damage from LC voltage spikes.
  •  The DRV8825 can deliver slightly more current than the A4988 without any additional cooling.

Note that the pinout of the DRV8825 is exactly the same as for the A4988, so it can be used as a drop-in replacement!

A4988 vs DRV8825 stepper motor driver
A4899 (left) vs DRV8825 (right)

Microstep settings

Stepper motors typically have a step size of 1.8° or 200 steps per revolution, this refers to full steps. A microstepping driver such as the DRV8825 allows higher resolutions by allowing intermediate step locations. This is achieved by energizing the coils with intermediate current levels.

For instance, driving a motor in quarter-step mode will give the 200-step-per-revolution motor 800 micro steps per revolution by using four different current levels.

DRV8825-pinout
DRV8825 Pinout

The resolution (step size) selector pins (M0, M1, and M2) allow you to select one of the six step resolutions according to the table below.

M0M1M2Microstep resolution
LowLowLowFull step
HighLowLow1/2 step
LowHighLow1/4 step
HighHighLow1/8 step
LowLowHigh1/16 step
HighLowHigh1/32 step
LowHighHigh1/32 step
HighHighHigh1/32 step

All three inputs have internal 100 kΩ pull-down resistors, so leaving the three microstep selection pins disconnected results in full-step mode.

I often use a CNC-shield or expansion board in combination with these drivers. The expansion board has 3 dip switches to set M0 – M2 high or low and on the CNC-shield you can install jumpers. If you are using the driver with a breadboard, you can just use jumper wires to connect the selector pins to 5 V (i.e. make them HIGH).


Wiring – Connecting DRV8825 to Arduino and stepper motor

DRV8825 Arduino stepper motor wiring schematic diagram pinout
Wiring diagram/schematic for DRV8825 stepper motor driver with Arduino and stepper motor.

The wiring diagram/schematic above shows you how to connect the DRV8825 driver to a stepper motor and the Arduino.

The connections are also given in the following table:

DRV8825 Connections

DRV8825Connection
VMOT8.2-45 V
GNDMotor ground
SLP5 V
RST5 V
GNDLogic ground
STPPin 3
DIRPin 2
A1, A2, B1, B2Stepper motor
  • The motor power supply is connected to GND and VMOT (top right).
  • The two coils of the stepper motor are connected to A1, A2 and B1, B2 (see below).
  • The GND pin (lower right) is connected to the ground pin of the microcontroller and VDD is connected to 5V.
  • The STP (step) and DIR (direction) pin are connected to digital pin 3 and 2 respectively. You can choose a different digital pin if you want, but these are the ones I used for this tutorial and the example code.
  • You need to connect RST (reset) and SLP (sleep) to 5 V otherwise, the driver won’t turn on.
  • The EN (enable) pin can be left disconnected, it is pulled low by default. When this pin is set high the driver is disabled.
  • 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. This pin is left disconnected for this tutorial.

In the rest of this tutorial I have left M0, M1 and M3 disconnected, so the driver operates in full-step mode. This makes explaining the code a bit easier. Normally I would use 1/16 or 1/32 microstepping and connect the appropriate pins to 5 V (see table in the introduction).

Warning

The DRV8825 carrier board uses low-ESR ceramic capacitors, which makes it susceptible to destructive LC voltage spikes, especially when using power leads longer than a few inches.

To protect the driver you can connect an electrolytic capacitor between VMOT and GND. Pololu suggests a capacitor of 47µF or more (I used a 100 µF capacitor). I like these assortment boxes from Amazon, this way I always have some capacitors of the right size on hand.

How to determine the correct stepper motor wiring?

If you can’t find the datasheet of your stepper motor, it can be difficult to figure out how to wire your motor correctly. I use the following trick to determine how to connect 4 wire bipolar stepper motors:

The only thing you need to identify is the two pairs of wires which are connected to the two coils of the motor. The wires from one coil get connected to A1 and A2 and the other to B1 and B2, the polarity doesn’t matter.

To find the two wires from one coil, do the following with the motor disconnected:

  1. Try to spin the shaft of the stepper motor by hand and notice how hard it is to turn.
  2. Now pick a random pair of wires from the motor and touch the bare ends together.
  3. Next, try to spin the shaft of the stepper motor again.

If you feel a lot of resistance, you have found a pair of wires from the same coil. If you can spin the shaft freely, try another pair of wires. Now connect the two coils to the pins shown in the wiring diagram above.

(If it is still unclear, please leave a comment below, more info can also be found on the RepRap.org wiki)


How to set the current limit?

Before you start programming your Arduino and start using the driver there is one very important thing you need to do that a lot of people forget: set the current limit!

This step is not very complicated but absolutely necessary to protect your stepper motor and the driver. If you do not set an appropriate current limit, your motor can draw more current than it or your driver can handle, this is likely to damage one or both of them.

To set the current limit you need to measure a reference voltage and adjust the on-board potentiometer accordingly. You will need a small screwdriver, a multimeter to measure the reference voltage, and alligator test leads (optional but very handy).

DRV8825-current-limit-wiring-diagram-schematic
Current limit wiring diagram for DRV8825 driver.

To measure the reference voltage, the driver needs to be powered. The DRV8825 only needs power via VMOT (8.2-45 V) and you need to apply 5 V to RST and SLP otherwise, the driver won’t turn on. It’s best to disconnect the stepper motor while you do this.

If you have already wired up the driver as I have shown before, you can leave the Arduino connected to power the RST and SLP pins.

DRV8825Connection
VMOT8.2-45 V
GNDMotor ground
SLP5V
RST5V
GNDLogic ground

Current limit formula

The next step is to calculate the current limit with the following formula:

Current Limit = Vref × 2

So this means that for a current limit of 1 A the Vref should be 0.5 V.

To select the right current limit, take a look at the datasheet of your stepper motor. If you can’t find the current rating of your motor, I recommend starting with a current limit of 1A. You can always increase it later if your motor/driver is missing steps.

Bonus info: When using the driver in full-step mode, the current through each coil is limited to approximately 70% of the set current limit. This means that you would need to set the current limit 40% higher or 1.4 A in full-step mode. When using microstepping, the formula above applies.

If your motor is making a lot of noise, try to lower the current limit. It’s best to set the current limit just high enough so the motor doesn’t miss steps.

Measuring Vref

Now you will need to measure the reference voltage (Vref) between the two points marked on the picture below (GND and the potentiometer) and adjust it to the value you calculated.

DRV8825-Current-limit-probe-points
Vref probe points (GND and potentiometer).

I recommend using alligator test leads clamped to the screwdriver to set the current limit. This allows you to adjust the potentiometer and measure the reference voltage at the same time.

Note: There is another way to measure the current limit and that is to directly measure the current draw of the stepper motor. Personally I find the above method a lot easier.

Pololu mentions the following on their website:

Note: The coil current can be very different from the power supply current, so you should not use the current measured at the power supply to set the current limit. The appropriate place to put your current meter is in series with one of your stepper motor coils.

Pololu

Current limit FAQ

Do I need to have the stepper motor connected or not?
No, you don’t need to connect the stepper motor to the driver when setting the current limit. To be on the safe side, disconnect your motor, it sometimes interferes with measuring the Vref voltage.

Do I need to turn the motor by running the Arduino motor sketch?
No, see question above.

Do I need to turn the potentiometer clock- or counterclockwise to raise Vref?
This depends on the manufacturer of the driver. If you have a genuine Polulu breakout board of the DRV8825 or A4988 you turn the potentiometer clockwise to raise Vref and counterclockwise to lower it.


Cooling the driver

The DRV8825 driver IC has a maximum current rating of 2.5 A per coil but without a heat sink, it can only supply about 1.5 A per coil before it starts to overheat.

The driver usually comes with a small adhesive-backed heat sink, which I recommend you to install right away. You can also buy a bunch of small heat sinks from Amazon for really cheap.


Basic Arduino example code to control a stepper motor

Now that you have wired up the driver and set the current limit, it is time to connect the Arduino to the computer and upload some code. You can upload the following example code to your Arduino using the Arduino IDE. For this specific example, you do not need to install any libraries.

This sketch controls both the speed, the number of revolutions, and the spinning direction of the stepper motor.

You can copy the code by clicking on the button in the top right corner of the code field.

/*Example sketch to control a stepper motor with A4988/DRV8825 stepper motor driver and Arduino without a library. More info: https://www.makerguides.com */

// Define stepper motor connections and steps per revolution:
#define dirPin 2
#define stepPin 3
#define stepsPerRevolution 200

void setup() {
  // Declare pins as output:
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
}

void loop() {
  // Set the spinning direction clockwise:
  digitalWrite(dirPin, HIGH);

  // Spin the stepper motor 1 revolution slowly:
  for (int i = 0; i < stepsPerRevolution; i++) {
    // These four lines result in 1 step:
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(2000);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(2000);
  }

  delay(1000);

  // Set the spinning direction counterclockwise:
  digitalWrite(dirPin, LOW);

  // Spin the stepper motor 1 revolution quickly:
  for (int i = 0; i < stepsPerRevolution; i++) {
    // These four lines result in 1 step:
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(1000);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(1000);
  }

  delay(1000);

  // Set the spinning direction clockwise:
  digitalWrite(dirPin, HIGH);

  // Spin the stepper motor 5 revolutions fast:
  for (int i = 0; i < 5 * stepsPerRevolution; i++) {
    // These four lines result in 1 step:
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(500);
  }

  delay(1000);

  // Set the spinning direction counterclockwise:
  digitalWrite(dirPin, LOW);

  //Spin the stepper motor 5 revolutions fast:
  for (int i = 0; i < 5 * stepsPerRevolution; i++) {
    // These four lines result in 1 step:
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(500);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(500);
  }

  delay(1000);
}

How the code works:

The sketch starts with defining the step and direction pins. I connected them to Arduino pin 3 and 2.

The statement #define is used to give a name to a constant value. The compiler will replace any references to this constant with the defined value when the program is compiled. So everywhere you mention dirPin, the compiler will replace it with the value 2 when the program is compiled.

I also defined a stepsPerRevolution constant. Because I set the driver to full step mode I set it to 200 steps per revolution. Change this value if your setup is different.

// Define stepper motor connections and steps per revolution:
#define dirPin 2
#define stepPin 3
#define stepsPerRevolution 200

In the setup() section of the code, all the motor control pins are declared as digital OUTPUT with the function pinMode().

void setup() {
  // Declare pins as output:
  pinMode(stepPin, OUTPUT);
  pinMode(dirPin, OUTPUT);
}

In the loop() section of the code, we let the motor spin one revolution slowly in the CW direction and one revolution quickly in the CCW direction. Next, we let the motor spin 5 revolutions in each direction with a high speed. So how do you control the speed, spinning direction, and number of revolutions?

  // Set the spinning direction clockwise:
  digitalWrite(dirPin, HIGH);

  // Spin the stepper motor 1 revolution slowly:
  for(int i = 0; i < stepsPerRevolution; i++)
  {
    // These four lines result in 1 step:
    digitalWrite(stepPin, HIGH);
    delayMicroseconds(2000);
    digitalWrite(stepPin, LOW);
    delayMicroseconds(2000);
  }

Control spinning direction:

To control the spinning direction of the stepper motor we set the DIR (direction) pin either HIGH or LOW. For this we use the function digitalWrite(). Depending on how you connected the stepper motor, setting the DIR pin high will let the motor turn CW or CCW.

Control number of steps or revolutions:

In this example sketch, the for loops control the number of steps the stepper motor will take. The code within the for loop results in 1 step of the stepper motor. Because the code in the loop is executed 200 times (stepsPerRevolution), this results in 1 revolution. In the last two loops, the code within the for loop is executed 1000 times, which results in 1000 steps or 5 revolutions.

Note that you can change the second term in the for loop to whatever number of steps you want. for(int i = 0; i < 100; i++) would result in 100 steps, or half a revolution.

Control speed:

The speed of the stepper motor is determined by the frequency of the pulses we send to the STEP pin. The higher the frequency, the faster the motor runs. You can control the frequency of the pulses by changing delayMicroseconds() in the code. The shorter the delay, the higher the frequency, the faster the motor runs.


AccelStepper library tutorial

The AccelStepper library written by Mike McCauley is an awesome library to use for your project. One of the advantages is that it supports acceleration and deceleration, but it has a lot of other nice functions too.

You can download the latest version of this library here or click the button below.

You can install the library by going to Sketch > Include Library > Add .ZIP Library… in the Arduino IDE.

Another option is to navigate to Tools > Manage Libraries… or type Ctrl + Shift + I on Windows. The Library Manager will open and update the list of installed libraries.

Installing an Arduino library step 1 open Library Manager

You can search for ‘accelstepper’ and look for the library by Mike McCauley. Select the latest version and then click Install.

Installing an Arduino library step 2 AccelStepper

1. Continuous rotation example code

The following sketch can be used to run one or more stepper motors continuously at a constant speed. (No acceleration or deceleration is used).

/*Example sketch to control a stepper motor with DRV8825 stepper motor driver, AccelStepper library and Arduino: continuous rotation. More info: https://www.makerguides.com */

// Include the AccelStepper library:
#include <AccelStepper.h>

// Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:
#define dirPin 2
#define stepPin 3
#define motorInterfaceType 1

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

void setup() {
  // Set the maximum speed in steps per second:
  stepper.setMaxSpeed(1000);
}

void loop() {
  // Set the speed in steps per second:
  stepper.setSpeed(400);
  // Step the motor with a constant speed as set by setSpeed():
  stepper.runSpeed();
}

How the code works:

The first step is to include the library with #include <AccelStepper.h>.

// Include the AccelStepper library:
#include <AccelStepper.h>

The next step is to define the DRV8825 to Arduino connections and the motor interface type. The motor interface type must be set to 1 when using a step and direction driver. You can find the other interface types here.

The statement #define is used to give a name to a constant value. The compiler will replace any references to this constant with the defined value when the program is compiled. So everywhere you mention dirPin, the compiler will replace it with the value 2 when the program is compiled.

// Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:
#define dirPin 2
#define stepPin 3
#define motorInterfaceType 1

Next, you need to create a new instance of the AccelStepper class with the appropriate motor interface type and connections.

In this case, I called the stepper motor ‘stepper’ but you can use other names as well, like ‘z_motor’ or ‘liftmotor’ etc. AccelStepper liftmotor = AccelStepper(motorInterfaceType, stepPin, dirPin);. The name that you give to the stepper motor will be used later to set the speed, position, and acceleration for that particular motor. You can create multiple instances of the AccelStepper class with different names and pins. This allows you to easily control 2 or more stepper motors at the same time.

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

In the setup() section of the code we define the maximum speed in steps/second. Speeds of more than 1000 steps per second can be unreliable, so I set this as the maximum. Note that I specify the name of the stepper motor (‘stepper’), for which I want to define the maximum speed. If you have multiple stepper motors connected, you can specify a different speed for each motor:

void setup() {
  // Set the maximum speed in steps per second:
  stepper.setMaxSpeed(1000);
  stepper2.setMaxSpeed(500);
}

In the loop() we first set the speed that we want the motor to run at. For this, we use the function setSpeed(). (you can also place this in the setup section of the code).

stepper.runSpeed() polls the motor and when a step is due, executes 1 step. This depends on the set speed and the time since the last step. If you want to change the direction of the motor, you can set a negative speed: stepper.setSpeed(-400); turns the motor the other way.

void loop() {
  // Set the speed in steps per second:
  stepper.setSpeed(400);
  // Step the motor with a constant speed as set by setSpeed():
  stepper.runSpeed();
}

2. Example code to control number of steps or revolutions

To let the motor rotate a specific number of steps I prefer to use a while loop in combination with stepper.currentPosition(). You can use the following example code, to let the motor run back and forth.

/*Example sketch to control a stepper motor with DRV8825 stepper motor driver, AccelStepper library and Arduino: number of steps or revolutions. More info: https://www.makerguides.com */

// Include the AccelStepper library:
#include <AccelStepper.h>

// Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:
#define dirPin 2
#define stepPin 3
#define motorInterfaceType 1

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

void setup() {
  // Set the maximum speed in steps per second:
  stepper.setMaxSpeed(1000);
}

void loop() { 
  // Set the current position to 0:
  stepper.setCurrentPosition(0);

  // Run the motor forward at 200 steps/second until the motor reaches 400 steps (2 revolutions):
  while(stepper.currentPosition() != 400)
  {
    stepper.setSpeed(200);
    stepper.runSpeed();
  }

  delay(1000);

  // Reset the position to 0:
  stepper.setCurrentPosition(0);

  // Run the motor backwards at 600 steps/second until the motor reaches -200 steps (1 revolution):
  while(stepper.currentPosition() != -200) 
  {
    stepper.setSpeed(-600);
    stepper.runSpeed();
  }

  delay(1000);

  // Reset the position to 0:
  stepper.setCurrentPosition(0);

  // Run the motor forward at 400 steps/second until the motor reaches 600 steps (3 revolutions):
  while(stepper.currentPosition() != 600)
  {
    stepper.setSpeed(400);
    stepper.runSpeed();
  }

  delay(3000);
}

Code explanation:

The first part of the code up to the loop() section is exactly the same as in the previous example.

In the loop I make use of a while loop in combination with the currentPosition() function. First, I set the current position of the stepper motor to zero with stepper.setCurrentPosition(0).

  // Set the current position to 0:
  stepper.setCurrentPosition(0);

Next we make use of the while loop. A while loop will loop continuously, and infinitely, until the expression inside the parenthesis, () becomes false. So, in this case, I check if the current position of the stepper motor is not equal to 400 steps (!= means: is not equal to). While this is not the case, we run the stepper motor at a constant speed as set by setSpeed().

  // Run the motor forward at 200 steps/second until the motor reaches 400 steps (2 revolutions):
  while(stepper.currentPosition() != 400)
  {
    stepper.setSpeed(200);
    stepper.runSpeed();
  }

In the rest of the loop, we do exactly the same, just with a different speed and target position.


3. Acceleration and deceleration example code

With the following sketch, you can add acceleration and deceleration to the movements of the stepper motor,  without any complicated coding. In the following example, the motor will run back and forth with a speed of 200 steps per second and an acceleration of 30 steps per second per second.

/*Example sketch to control a stepper motor with DRV8825 stepper motor driver, AccelStepper library and Arduino: acceleration and deceleration. More info: https://www.makerguides.com */

// Include the AccelStepper library:
#include <AccelStepper.h>

// Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:
#define dirPin 2
#define stepPin 3
#define motorInterfaceType 1

// Create a new instance of the AccelStepper class:
AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin);

void setup() {
  // Set the maximum speed and acceleration:
  stepper.setMaxSpeed(200);
  stepper.setAcceleration(30);
}

void loop() {
  // Set the target position:
  stepper.moveTo(600);
  // Run to target position with set speed and acceleration/deceleration:
  stepper.runToPosition();

  delay(1000);

  // Move back to zero:
  stepper.moveTo(0);
  stepper.runToPosition();

  delay(1000);
}

Code explanation:

In the setup(), besides the maximum speed, we need to define the acceleration/deceleration. For this we use the function setAcceleration().

void setup() {
  // Set the maximum speed and acceleration:
  stepper.setMaxSpeed(200);
  stepper.setAcceleration(30);
}

In the loop section of the code, I used a different way to let the motor rotate a predefined number of steps. The function stepper.moveTo() is used to set the target position. The function stepper.runToPostion() moves the motor (with acceleration/deceleration) to the target position and blocks until it is at the target position. Because this function is blocking, you shouldn’t use this when you need to control other things at the same time.

  // Set the target position:
  stepper.moveTo(600);
  // Run to target position with set speed and acceleration/deceleration:
  stepper.runToPosition();

Conclusion

In this article I have shown you how to control a stepper motor with the DRV8825 stepper motor driver and Arduino. I hope you found it useful and informative. If you did, please share it with a friend who also likes electronics and making things!

I have personally used this driver a lot for a bunch of 3D printers and other CNC related projects but I would love to know what projects you plan on building (or have already built) with this driver. If you have any questions, suggestions, or if you think that things are missing in this tutorial, please leave a comment down below.

Note that comments are held for moderation to prevent spam.

Creative Commons License

49 thoughts on “How to control a stepper motor with DRV8825 driver and Arduino”

  1. Hi Benne,
    How would you add 1/32 microstepping to this? Would you wire the M0, M1 and M2 to digital pins on the arduino then set those pins to high in the code?

    Kind regards,

    Jess

  2. Dear Benne,

    I have a simple question, is it possible for DRV8825 to drive NEMA17 of operating voltage of 3.6V instead of 12V?

    With best regards

    Tassos Makris

    1. It’s possible. The voltage provide by the motor’s manufacture is only for reference, it is not mandatory

  3. Hi I have a question! I have carefully studied this tutorial an I used a DRV8825 a breadboard and an arduino. I ha sucess with your examples! But then I started to put the drv8825 on a cncv3 and then nothing happnd! My question now is, how I have to modify your code that this will also work with an cncv3. Currently I haven understood how the cables are connected inside the cncv3

    1. Benne de Bakker

      Hi Wolfgang,

      If I remember correctly, you need to enable the drivers when you are using the cncv3. I think by default the enable pin (pin 8 on the shield I used) is pulled high, which disables the drivers. So you need to set this pin LOW in your code to enable the drivers.

      Benne

      1. Hi Benne,

        well I have these pins enabled when I used the breadboard!

        #define dirPin 2
        #define stepPin 3
        #define motorInterfaceType 1

        Currently I don’t understand what I have to change and how this can be done so that these cncv3 board works! Please can you give me some more detailed instructions how I have to modify the code? I am currently working with the Continuous rotating example!

        Wolfgang

        1. Benne de Bakker

          Hi Wolfgang,

          When using the breadboard you didn’t connect anything to the EN (enable) pin of the driver (see the pinout and the schematic in the tutorial). This means that this pin is LOW and the driver is always enabled. However, when you use the CNC shield, the EN pin is pulled high via a resistor on the shield which disables the driver. So in your code, you need to set this pin LOW. As far as I know, all the enable pins are connected to pin 8 of the Arduino. So simply add:

          #define enablePin 8

          and in the setup():
          pinMode(enablePin, OUTPUT);
          digitalWrite(enablePin, LOW);

          Benne

          1. Sorry, I had a loner break now, but this still doesnt work! This is my full code!

            // Include the AccelStepper library:
            #include

            // Define stepper motor connections and motor interface type. Motor interface type must be set to 1 when using a driver:
            #define dirPin 2
            #define stepPin 3
            #define enablePin 8
            #define motorInterfaceType 1

            // Create a new instance of the AccelStepper class:
            AccelStepper stepper = AccelStepper(motorInterfaceType, stepPin, dirPin, enablePin);

            void setup() {
            // Set the maximum speed in steps per second:
            stepper.setMaxSpeed(600);
            pinMode(enablePin, OUTPUT);
            digitalWrite(enablePin, HIGH);
            }

            void loop() {
            // Set the speed in steps per second:
            stepper.setSpeed(400);
            // Step the motor with a constant speed as set by setSpeed():
            stepper.runSpeed();
            }

            I cannot understand what I did wrong!

          2. Benne de Bakker

            Like I said, the enable pin of the driver needs to be pulled LOW, not HIGH. So try digitalWrite(enablePin, LOW); instead. Oh and the step and dir pin are not pins 2 and 3 of the arduino when you use a cnc shield, you should look up the exact pinout online.

            Benne

  4. Found this site some time ago and forgot about it. Getting ready to make a go at it again. My project is for a automatic blast gate for saw dust collection in my wood working shop. Using a Nano, ACS712 current sensor, MKS 42b smart stepper. Each tool would have a current sensor going to an analog port. When current is detected the digital side would direct a single stepper to rotate to a predetermined position for that tool ( to open path to the vacuum system). Would use a array to monitor analog inputs and specify the set degrees for each tool. Also need to check current position to see if any change is required. (not unusual to use same tool repeatedly. Have had portions of this working in the past. Think I’m trying to code to much at once. Need to work on one part at a time. Changed to Platformio in the middle of this as well .

  5. Hi Benne
    I am building a CNC Router with 2 motors for Y axis and 1 each for X and Z axis. I have an Arduino UNO driving a Protoneer CNC Shield Ver 3.0 with DRV8825 Stepper Drivers. There is a 12V 5A power supply to the CNC Shield. I am using CNCjs software to control it, and I have installed GRBL ver 1.1. The CNCjs software says I have control and the X,Y & Z axis appear to function in the software. I have adjusted the Vref to 1V for the NEMA 17 Stepper Motors. I have checked the wiring to each motor and it appears that it is connected correctly, that is, green & black for 1 winding and red & blue for the other.
    When I command a move, I get no response. No motor hum and obviously no movement. Is there a way to check the output of the DRV8825 Stepper Driver without disconnecting the Stepper Motors and possibly destroying the Driver?

  6. Your tutorial was quite good. However, I believe my DRV8825s are faulty. I have tried them on a self-balancing robot project and had very odd and inconsistent results. I did use your tutorial to set the current limit on the DRV8825 (0.45v = 0.9a).

    I am trying to teach a class of middle-school students how to build their own self-balancing robot. I have almost 2 dozen 8825s and I find that their reference voltage is either 0.45v or 1.6v…and tweaking the pot does not make any difference at all. I am measuring from the VMOT ground and an alligator clip to a phillips screwdriver touching the potentiometer on the driver. Turning many dozens of times in either direction does not change the reference voltage. As I said, I highly suspect the modules are duds…but it also seems unlikely that so many of them should fail.

    I am testing them without a motor attached, but I also tried WITH a motor…no difference.

    Do you have any ideas what might be going on? Would you expect the $11 for 5 drivers (amazon.com) would indicate a strong likelyhood for bad boards, or am I just likely screwing something up?

    https://assoc-redirect.amazon.com/g/r/https://www.amazon.com/gp/product/B07K9ZB7M5/ref=ppx_yo_dt_b_asin_image_o07_s01?ie=UTF8&psc=1

    1. Hi Jim,

      I think you need to measure the Vref between the screw(driver) on the potentiometer and the signal ground (the same as Arduino ground), NOT VMOT ground.

      Hope that helps,

      Michael

  7. Thank you for this incredibly well done tutorial. I am trying to do this with a stepper motor that I got from a small DVD player. There is no spec sheet so I put the current limit down to almost the lowest setting on the potentiometer to be safe. I got a 5v 1a power supply and using your code the motor steps at full stepping without a problem. But if I try microstepping to half or quarter, I start to lose steps very consistently. Is this because the current limit needs to be higher to support microstepping? Or the voltage of the power supply needs to be higher? I think I’m not understanding how the voltage and current limits need to be adjusted as you transition between micro step modes. Thanks!

  8. Thank you so much for sharing!
    Is there a world where powering the motor through the arduino barrel plug with a 12v supply is possible? What would that wiring look like?
    Thanks!

    1. Hi Emma,

      Unfortunately, this is not really possible. The 12V from the barrel plug is only accessible from the Vin pin, but this pin is only rated for a few milliamps. Stepper motors typically draw 1-2 amps, so you need an external power supply.

      Benne

  9. Hello,
    I think that your point of view on setting current limit with full step mode 40% higher is not right. In full step mode is according to DRV8825 datasheet winding current of both (A a B coil) 0,71%.

    With this information I would say that I could set the current limit little bit below than the current of used motor. For example if I had 1A motor, I would use 0.7A current limit for full step mode…. am I right or not?

    Thanks.
    Best regards,
    Petr Holý

    1. Hi Petr,

      Thank you for your comment! When looking at table 2 in the datasheet, the winding current in full-step mode only reaches a maximum of 71% of the current limit setting. From my understanding, this means that when you set the current limit to 1 A and use full-step mode, the current through the coils is limited to 0.71 A.

      If you have a 1 A stepper motor and are using full-step mode, you would therefore need to set the current limit to 1.4 A. This is also how it is explained on the pololu website. It would be interesting to test this in practice. You could simply set the driver in full-step mode, set the current limit to 1 A, send a HIGH signal to the step pin and measure the current through one of the coils (in full-step mode, both coils are always 100% on). The measured current should be below 0.7 A.

      Note that you need to be careful when switching to microstepping, as then the winding current is 100 % of the set current.

      Kind regards,

      Benne

  10. Thank you for this detailed tutorial.
    Tou mention 5V as logual inputs, but can I use an Arduino Due with its 3.3V output for the DRV8825?
    Thank you.

    1. Hi Frank,

      The DRV8825 works with a logic voltage of 2.5 V to 5.25 V, so the Arduino Due at 3.3 V should work just fine.

      Benne

  11. Thank you for the tutorial

    I got a QSH4218-41-10-035 step motor and he makes no revolutions with both codes…. I hear only a little bit of sound and feel the resistance when i turn the pin arround

    Where ‘s the problem?

    1. It is always difficult to troubleshoot a problem over the internet, but you could check the following:

      – It sounds like the motor is getting power, but still double-check your connections. It looks like that stepper motor type has pretty standard wiring, so coil 1 is the black and green wire and coil two is the red and blue wire.

      – See if you have adjusted the current limit correctly. The datasheet shows a current rating of 1 A for this particular motor.

      – Play around with the speed in the code. If you try to let it spin too fast, the motor could stall. So lower the speed used in the code to test.

      Without any other information, it is difficult to give you a better answer. I hope you can find the problem soon! I have tested the code and wiring many times, so that shouldn’t be the issue.

  12. Hello, I have a nema 11 steppermotor that I would like to use but the voltage is 3.8 rating. Would I still be able to use 5v to power it thru the L298N?

    1. I think this shouldn’t be a problem, but your stepper motor could get hot. Since the L298N has no easy way to limit the current, you might want to switch to a chopping driver like the A4988 or DRV8825.

  13. Hello,

    I was playing with the “2. Example code to control number of steps or revolutions” and found that I could easily block the stepper. When blocked it still reached the end position in software, but not in reality. So you cannot trust the position this way, right? So if the position is important, I need an external sensor (eg quadrature encoder). Do you agree?

    Or is there a way to control a stepper in such a way that you have position feedback that you can really trust?

    1. Hi,

      If your stepper motor easily ‘loses steps’, I would increase the current limit slightly. The maximum speed you can reach (without losing steps or stalling the motor) also depends on the power supply and current limit that you are using.

      You could look into a closed-loop stepper motor system (with an encoder) or even servomotors, but this would be much more expensive. In most cases, it is best to make sure that your motor can provide enough torque and speed so it doesn’t lose steps and also incorporate a homing procedure in your setup. This allows you to reset/recalibrate the motor automatically.

      Benne

  14. This tutorial was very helpful! Thank you so much.

    I’m trying to make a rodent maze with automated doors. Everything works great except I’m unable to make the motor go faster than the 1000microsecond code (if that makes sense). As soon as I change the speed to below 1000microseconds, my motor won’t move unless I force it. Any suggestions?

    1. Hi Lorne,

      If your motor is stalling, I would try to increase the current limit slightly. You can also try to use a higher voltage power supply, which should also allow you to achieve higher speeds. What microstepping settings are you using?

      Benne

  15. Hi Mike,
    This information is very helpful and useful. I want to enable and disable the stepper motor, how should i go about it?
    Thank you.
    Regards,
    Gad

    1. Hi Gad,

      You can connect the enable pin of the driver to one of the digital outputs of the Arduino. If you set this pin HIGH, the stepper motor is disabled. By default, it is pulled low (also if you don’t connect it to anything), which enables the driver/stepper motor.

      Check the pinout at the beginning of the article for the location of the enable pin (EN).

      Benne

  16. hello, VERY helpful example / tutorial. Thank you. I do have a question on acceleration usage. I am using 2 stepper motors and with your help it is working great. I also use “multistepper” to run them at the same time.
    Now I want to add “acceleration” to each one. Is this possible, your comment about blocking confuses me. Do you have a suggestion on 2 steppers using acceleration and multi stepper. I am trying to make a pan / tilt fixture.

  17. Hello, thank you for the excellent and thorough writeup!

    You say that the DRV8825 can microstep up to 1/32 but under the section entitled, “Microstep Settings”, you only show how to set pins M0, M1, M2 up to 1/16 … and I’m thinking since 1/32 is the highest setting, wouldn’t setting all three pins high bring it to 1/32 mode? You might want to double check that table for accuracy.

    Thank you again!

    Mike Sims

    1. Benne de Bakker

      Hi Mike,

      Thanks for the feedback! I think I accidentally copied the shortcodes for the A4988 microstepping table when updating this post, so the 1/16 and 1/32 microstep settings were indeed not correct. The post should now be showing the correct table.

      Thanks again!

      Benne

    1. Benne de Bakker

      Hi,

      The DRV8825 can only drive one stepper motor, but you can add multiple DRV8825 drivers to the Arduino. You will need to pick a different step and direction pin for the second driver.

      In the code you can create a second stepper motor object with a different name, like stepper2. AccelStepper stepper2(1,stepPin2,dirPin2); See also the code explanation under the first AccelStepper example. In the rest of the code you can control the second stepper motor by using the new name in the rest of the functions: stepper2.setSpeed(200); and stepper2.runSpeed(); for example.

      In this way you can control both motors separately.

      Benne

      1. is it okay to use A4998 driver instead of DRV8825? is it the same schematic driagram and add just add driver and stepper motor ? thanks for the reply .

  18. Hi,
    I’m currently researching for an automated blinds project using this driver and some stepper motors. I want to use an RTC to have the blinds open and close at certain times and also have an IR remote to manually operate them. I’m currently simulating it using a simple circuit with a pushbutton but I’m having a hard time with the code. I basically press the button, I want it to move a certain number of rotations (predetermined to the closed position.) and if I press again, move the other way back to the open position. Do you have any input on how I should set the code up?
    Thank you, this is an amazing ressource.
    Olivier

    1. Benne de Bakker

      Hi Olivier,

      Thank you for your comment. I wrote a simple addition to one of the example sketches above. You could use the following sketch in combination with a momentary push button. The push button is connected between GND and digital pin 4. When you press the button, the motor moves from the 0 position to the open position (400). And when you press it again it moves back to the 0 position. Hopefully this gives you some inspiration for the rest of your code. Good luck with the rest of your project!

      Benne

      Code:

      https://www.makerguides.com/wp-content/uploads/2019/05/DRV8825-example-sketch-with-AccelStepper-library-and-push-button.pdf

Comments are closed.