Overview
In robotics and 3D printing applications, the NEMA17 stepper motor has gained popularity due to its compact size and impressive power. Effectively harnessing the capabilities of this motor requires a reliable control mechanism. This article aims to provide an introduction to controlling the NEMA17 stepper motor using the DRV8825 driver in conjunction with the Raspberry Pi Pico and MicroPython.
The DRV8825 driver serves as a crucial component in enabling versatile operation of the NEMA17 motor. When combined with the Raspberry Pi Pico, a small yet capable computer board running MicroPython, the process of motor control becomes incredibly accessible.
This comprehensive guide will walk you through the process of connecting these components to the NEMA17 motor. It covers essential aspects such as wiring configurations and coding techniques in MicroPython. By the time you reach the end of this guide, you will possess the knowledge required to integrate these components into various projects, including robotics and 3D printing. Should you require greater power and performance, the DRV8825 driver can serve as a suitable alternative to the A4988 driver.
Once you understand the basics, you can start building and controlling your own motor-powered projects based on DRV8825 Stepper Driver Module & Raspberry Pi Pico Board.
Bill of Materials
To follow along with the DRV8825 and Raspberry Pi Pico tutorial, you will require certain components. All of these items can be conveniently bought from Amazon. We have also included the purchase links for your ease.
| S.N. | Components Name | Quantity | Purchase Links |
|---|---|---|---|
| 1 | Raspberry Pi Pico Board | 1 | Amazon | AliExpress |
| 2 | DRV8255 Stepper Motor Driver | 1 | Amazon | AliExpress |
| 3. | NEMA17 Stepper Motor | 1 | Amazon | AliExpress |
| 4 | Electrolytic Capacitor 10uF | 1 | Amazon | AliExpress |
| 5 | Electrolytic Capacitor 100uF | 1 | Amazon | AliExpress |
| 6 | 7805 Voltage Regulator IC | 1 | Amazon | AliExpress |
| 7 | 12V DC Adapter | 1 | Amazon | AliExpress |
| 8 | Connecting Jumper Wires | 20 | Amazon | AliExpress |
| 9 | Breadboard | 1 | Amazon | AliExpress |
DRV8825 Stepper Motor Driver Module
The DRV8825 is a complete Microstepping Motor Driver with a built-in translator for easy operation. The breakout board from Texas Instruments features adjustable current limiting, over-current and over-temperature protection, and six different microstep resolutions.
It operates from 8.2 V to 45 V and can deliver up to approximately 1.5 A Current per phase without a heat sink or forced airflow. It is rated for 2.2 A Current per coil with sufficient additional cooling.
Additionally, the DRV8825 is compatible with many popular microcontrollers, such as the Arduino, ESP8266, ESP32, making it easy to integrate into your existing projects. With its robust features and powerful performance, the DRV8825 stepper motor driver is an excellent tool for controlling your NEMA17 or other bipolar stepper motors.
Features
- Max. Operating Voltage: 45V
- Min. Operating Voltage: 8.2V
- Max. Current Per Phase: 2.5A
- Microstep resolution: Full step, 1/2 step, 1/4 step, 1/8 step, 1/16 step 1/32 step
- Over temperature shutdown circuit
- Under-voltage lock out
- Over current shutdown
- Dimensions: 20.5 x 15.5 mm (0.8″ × 0.6″)
- Short-to-ground and shorted-load protection
- Low RDS(ON) outputs
DRV8825 Motor Driver Pinout
The DRV8825 driver has total of 16 pins which are as follows:
1. Power Supply Pins: The pin includes VMOT, GND MOT & GND Logic. The DRV8825 module does not have any logic supply pin as it gets its power from the internal 3V3 voltage regulator. The VMOT supplies power for the motor which may be 8.2V to 45 V.
2. Microstep Selection Pins: The DRV8825 driver has three-step resolution selector inputs, i.e., M0, M1 & M2. By setting appropriate logic levels to those pins we will set the motors to at least one of the six-step resolutions.
3. Control Input Pins: STEP & DIR are the 2 control input pins. STEP input controls the micro-steps of the motor. The faster the pulses, the faster the motor will rotate. The DIR input controls the spinning direction of the motor. Pulling it HIGH drives the motor clockwise and pulling it LOW drives the motor anti-clockwise
4. Power States Control Pin: The DRV8825 has three different inputs for controlling its power states, i.e EN, RST, and SLP. The EN pin is always active low input by default which enables the driver. SLP Pin is active low input. Pulling this pin LOW puts the driver in sleep mode, minimizing the facility consumption. The RST is a lively low input which when pulled LOW, all STEP inputs are ignored. It also resets the driver by setting the internal translator to a motor initial stage.
5. Output Pins: There are 4 output pins as B2, B1, A2, A1. We can connect any bipolar stepper motor having voltages between 8.2V to 45 V to those pins. Each output pin on the module can deliver up to 2.2A to the motor
6. Fault Detection Pin: The DRV8825 features a FAULT output that drives LOW whenever the H-bridge FETs are disabled due to over-current protection or thermal shutdown. The Fault pin is shorted to the SLEEP pin & when it is driven LOW, the whole chip is disabled.
Heat Sink Requirement
It is safe to use the DRV8825 Driver without a heat sink if the current rating is up to 1.5A. For achieving more than 1.5A per coil, i.e. 2.2A, a heat sink or other cooling method is required.
Because of the excessive power dissipation of the DRV8825 driver, there is a rise in temperature that can go beyond the capacity of IC, probably damaging it.
Setting Up Current Limit
Before we connect the motor we should adjust the current limiting of the driver so that the current is within the limit of the motor. We can do that by adjusting the reference voltage using the potentiometer on the board and considering this equation below.
|
1 |
Current Limit = VRef x 2 |
For example, if the Stepper Motor is rated for 350mA, we need to adjust the reference voltage to 0.17V. Take a small screwdriver and adjust the current limit with a potentiometer until you reach the rated current.
NEMA17 Stepper Motor
NEMA 17 is a hybrid stepping motor with a 1.8° step angle (200 steps/revolution). The term “NEMA 17” refers to the National Electrical Manufacturers Association’s specification for stepper motors. Specifically, the ’17’ refers to the faceplate dimensions of the motor, which in this case is approximately 1.7 inches by 1.7 inches. Check out Stepper Motor Calculator to calculate various stepper motor parameters.
NEMA 17 stepper motors are widely used in devices like 3D printers, CNC machines, and small robotic applications due to their compact size, good torque, and precise control. Note that to properly control a stepper motor, you’ll usually need a stepper motor driver, which can precisely control the current in the motor windings to move the rotor in precise “steps.”
NEMA 17 stepper motors typically have four wires, each connected to one end of two separate coils inside the motor. These four wires are often color-coded to help identify them. The color coding is not standardized across all manufacturers, but a common scheme is:
- Black and Green wires: often correspond to one coil, which can be referred to as Coil A or Phase 1.
- Red and Blue wires: often correspond to the other coil, which can be referred to as Coil B or Phase 2.
Interface NEMA17 Stepper Motor with Raspberry Pi Pico & DRV8825
To control a NEMA17 stepper motor using the DRV8825 stepper motor driver and the Raspberry Pi Pico board, the connections are very simple. We can use the GPIO16 and GPIO17 pins on the Raspberry Pi Pico Board to control the motor direction and stepping. The complete wiring diagram is provided below.
For power, connect the VMOT pin on the DRV8825 driver to a 12V power supply, and the VDD pin to a 5V supply. It’s important to install a 100µF decoupling electrolytic capacitor across the motor power supply pins near the board to stabilize the power supply and reduce noise. Additionally, a 10µF electrolytic capacitor should be installed at the 5V supply pin for further stabilization.
The NEMA17 stepper motor is then connected to the DRV8825 driver using the four available motor pins as shown in circuit above.
MicroPython Code for Basic Stepper Motor Control
Now that you have wired up the DRV8825 driver and set the current limit, it is time to connect the Raspberry Pi Board to the computer and upload some code. This sketch controls NEMA17 Stepper motor in a single direction.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
from machine import Pin, Timer import utime dir_pin = Pin(16, Pin.OUT) step_pin = Pin(17, Pin.OUT) steps_per_revolution = 200 # Initialize timer tim = Timer() def step(t): global step_pin step_pin.value(not step_pin.value()) def rotate_motor(delay): # Set up timer for stepping tim.init(freq=1000000//delay, mode=Timer.PERIODIC, callback=step) def loop(): while True: # Set motor direction clockwise dir_pin.value(1) # Spin motor slowly rotate_motor(2000) utime.sleep_ms(steps_per_revolution) tim.deinit() # stop the timer utime.sleep(1) # Set motor direction counterclockwise dir_pin.value(0) # Spin motor quickly rotate_motor(1000) utime.sleep_ms(steps_per_revolution) tim.deinit() # stop the timer utime.sleep(1) if __name__ == '__main__': loop() |
Code Explanation
Let us learn about the MicroPython Code used to control NEMA17 Stepper Motor using DRV8825 Driver and Raspberry Pi Pico. This script is used to control a stepper motor using MicroPython. Here’s a breakdown of the script:
|
1 2 |
from machine import Pin, Timer import utime |
The machine module contains classes for handling hardware-specific functions, such as GPIO pins and timers. The utime module provides functions for time-related tasks.
|
1 2 3 |
dir_pin = Pin(16, Pin.OUT) step_pin = Pin(17, Pin.OUT) steps_per_revolution = 200 |
These lines define two output pins on the microcontroller. The dir_pin is used to set the direction of the stepper motor, while the step_pin is used to control the stepping of the motor. steps_per_revolution is a variable that defines the number of steps the motor should take for a full revolution.
|
1 |
tim = Timer() |
This initializes a timer object, tim, that will be used to control the rate of stepping.
|
1 2 3 |
def step(t): global step_pin step_pin.value(not step_pin.value()) |
This function toggles the value of step_pin, effectively sending a pulse to the stepper motor to make a step. This function will be used as a callback for the timer.
|
1 2 |
def rotate_motor(delay): tim.init(freq=1000000//delay, mode=Timer.PERIODIC, callback=step) |
This function initializes the timer with a frequency calculated from the input delay, and sets it to the PERIODIC mode, meaning it will trigger at fixed intervals. The step function is passed as a callback, so it will be executed each time the timer triggers.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 |
def loop(): while True: dir_pin.value(1) rotate_motor(2000) utime.sleep_ms(steps_per_revolution) tim.deinit() utime.sleep(1) dir_pin.value(0) rotate_motor(1000) utime.sleep_ms(steps_per_revolution) tim.deinit() utime.sleep(1) |
This function contains the main loop of the script. It continuously rotates the motor in one direction at a slower speed, then in the other direction at a faster speed. It does this by first setting the direction pin, then starting the motor rotation with the rotate_motor function. It then waits for a time equal to the number of milliseconds it takes for the motor to complete a full revolution, stops the timer, waits for another second, and then repeats the process in the opposite direction.
|
1 2 |
if __name__ == '__main__': loop() |
This is the entry point of the script. If the script is being run directly (not imported as a module), it will call the loop function, starting the motor control loop.
MicroPython Code Equivalent to AccelStepper Library
In MicroPython, there’s no direct equivalent to the AccelStepper library. However, we can write a simple class to mimic some of the functionality of the AccelStepper. Here’s an example:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 |
from machine import Pin import utime class Stepper: def __init__(self, step_pin, dir_pin): self.step_pin = Pin(step_pin, Pin.OUT) self.dir_pin = Pin(dir_pin, Pin.OUT) self.position = 0 def set_speed(self, speed): self.delay = 1 / abs(speed) # delay in seconds def set_direction(self, direction): self.dir_pin.value(direction) def move_to(self, position): self.set_direction(1 if position > self.position else 0) while self.position != position: self.step_pin.value(1) utime.sleep(self.delay) self.step_pin.value(0) self.position += 1 if position > self.position else -1 # Define the pins step_pin = 17 # GPIO number where step pin is connected dir_pin = 16 # GPIO number where dir pin is connected # Initialize stepper stepper = Stepper(step_pin, dir_pin) def loop(): while True: # Move forward 2 revolutions (400 steps) at 200 steps/sec stepper.set_speed(200) stepper.move_to(400) utime.sleep(1) # Move backward 1 revolution (200 steps) at 600 steps/sec stepper.set_speed(600) stepper.move_to(200) utime.sleep(1) # Move forward 3 revolutions (600 steps) at 400 steps/sec stepper.set_speed(400) stepper.move_to(600) utime.sleep(3) if __name__ == '__main__': loop() |
This code provides some of the same basic functionality as the AccelStepper library, but it’s a bit simplified. It only supports moving at a constant speed, and doesn’t provide acceleration or deceleration functionality. Also, please note the delay in the set_speed function is in seconds, so it’s the reciprocal of the speed (steps per second).
Stepper Motor Acceleration & Deceleration Code
Here’s how you can achieve similar functionality in MicroPython. Since there’s no built-in support for acceleration and deceleration in MicroPython, we’ll have to implement it manually. The logic behind it involves increasing the speed over time, which means decreasing the delay between each step.
Please note, the following code is a simple representation and might not give you the exact same performance as the AccelStepper library. It doesn’t implement a proper acceleration curve, but it does gradually increase and decrease the speed of the motor.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
from machine import Pin, Timer import utime class Stepper: def __init__(self, dir_pin, step_pin): self.dir_pin = Pin(dir_pin, Pin.OUT) self.step_pin = Pin(step_pin, Pin.OUT) self.position = 0 def move(self, steps, delay, accel): self.dir_pin.value(0 if steps > 0 else 1) steps = abs(steps) for i in range(steps): self.step_pin.value(1) utime.sleep_us(delay) self.step_pin.value(0) utime.sleep_us(delay) if i < steps // 2 and delay > 100: delay -= accel elif i >= steps // 2 and delay < 2000: delay += accel self.position += steps if steps > 0 else -steps step_pin = 17 dir_pin = 16 stepper = Stepper(dir_pin, step_pin) def loop(): while True: stepper.move(600, 2000, 5) # 2 revolutions forward utime.sleep(1) stepper.move(-600, 2000, 5) # 2 revolutions backward utime.sleep(1) if __name__ == '__main__': loop() |
In this example, the move method of the Stepper class takes three arguments: steps, delay, and accel. steps is the number of steps to move, delay is the initial delay in microseconds between each step, and accel is the amount to decrease the delay by for each step (until half of the steps have been executed, after which it increases the delay again).
Control NEMA17 Stepper Motor with DRV8825 & Potentiometer
The NEMA17 stepper motor with DRV8825 Driver & Raspberry Pi Pico can be controlled using Potentiometer as well. I used a 10K Potentiometer and connected it to the A0, analog pin of the Raspberry Pi Pico Board.
The voltage fed to the Analog pin of ESP8266 can be used as a reference voltage to control the speed of the Stepper Motor. The breadboard connection diagram is given below.
Copy the following code to Raspberry Pi Pico and Run. You can rotate the potentiometer to control the speed.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
from machine import Pin, ADC import utime # Define pin numbers step_pin = Pin(17, Pin.OUT) dir_pin = Pin(16, Pin.OUT) pot = ADC(26) # A0 is on GP26 on Pico # Set motor direction dir_pin.high() def map_val(value, in_min, in_max, out_min, out_max): return (value - in_min) * (out_max - out_min) / (in_max - in_min) + out_min def loop(): while True: # Read potentiometer value and map it to desired range custom_delay = pot.read_u16() # read 16 bit value custom_delay_mapped = map_val(custom_delay, 0, 65535, 300, 4000) # map 16 bit value to desired range # Pulse the stepper motor step_pin.high() utime.sleep_us(int(custom_delay_mapped)) step_pin.low() utime.sleep_us(int(custom_delay_mapped)) # Start the loop loop() |
Note that the Raspberry Pi Pico’s ADC returns a 16-bit value, so we’re reading with read_u16() and mapping from 0 to 65535 instead of 0 to 1023 as in the Arduino code. Also, the potentiometer is connected to GP26 (A0) on Pico. Please adjust the pin numbers as per your specific hardware setup.
Conclusion
In conclusion, the NEMA17 stepper motor’s combination with the DRV8825 driver and the Raspberry Pi Pico opens up a realm of possibilities in robotics and 3D printing applications. The compact size and robust power of the NEMA17 motor, when manipulated using the DRV8825 driver, present an efficient and versatile system.
With the Raspberry Pi Pico operating on MicroPython, this system becomes even more accessible, offering the advantage of simplified coding techniques.

















