Close Menu
  • Articles
    • Learn Electronics
    • Product Review
    • Tech Articles
  • Electronics Circuits
    • 555 Timer Projects
    • Op-Amp Circuits
    • Power Electronics
  • Microcontrollers
    • Arduino Projects
    • STM32 Projects
    • AMB82-Mini IoT AI Camera
    • BLE Projects
  • IoT Projects
    • ESP8266 Projects
    • ESP32 Projects
    • ESP32 MicroPython
    • ESP32-CAM Projects
    • LoRa/LoRaWAN Projects
  • Raspberry Pi
    • Raspberry Pi Projects
    • Raspberry Pi Pico Projects
    • Raspberry Pi Pico W Projects
  • Electronics Calculator
Facebook X (Twitter) Instagram
  • About Us
  • Disclaimer
  • Privacy Policy
  • Contact Us
  • Advertise With Us
Facebook X (Twitter) Instagram Pinterest YouTube LinkedIn
How To Electronics
  • Articles
    • Learn Electronics
    • Product Review
    • Tech Articles
  • Electronics Circuits
    • 555 Timer Projects
    • Op-Amp Circuits
    • Power Electronics
  • Microcontrollers
    • Arduino Projects
    • STM32 Projects
    • AMB82-Mini IoT AI Camera
    • BLE Projects
  • IoT Projects
    • ESP8266 Projects
    • ESP32 Projects
    • ESP32 MicroPython
    • ESP32-CAM Projects
    • LoRa/LoRaWAN Projects
  • Raspberry Pi
    • Raspberry Pi Projects
    • Raspberry Pi Pico Projects
    • Raspberry Pi Pico W Projects
  • Electronics Calculator
How To Electronics
Home » Control Stepper Motor with A4988 Driver & Raspberry Pi Pico
Raspberry Pi Raspberry Pi Pico Projects

Control Stepper Motor with A4988 Driver & Raspberry Pi Pico

Mamtaz AlamBy Mamtaz AlamUpdated:January 24, 202511 Mins Read
Share Facebook Twitter LinkedIn Telegram Reddit WhatsApp
Control Stepper Motor with A4988 Driver & Raspberry Pi Pico
Share
Facebook Twitter LinkedIn Pinterest Email Reddit Telegram WhatsApp

Overview

In robotics and 3D printing, the NEMA17 stepper motor is often used because it’s small but powerful. To make it work well, you need to know how to control it. This article will explain how to control this motor using the A4988 driver and Raspberry Pi Pico with MicroPython.

The A4988 driver is a device that helps the NEMA17 motor work in different ways. The Raspberry Pi Pico is a small computer board that, with MicroPython Code, lets you control the motor easily.

This guide will tell you how to connect these parts with the NEMA17 motor. It will cover the basics, how to wire them, and how to code in MicroPython. By the end, you should be able to use these parts in different projects like robotics and 3D printing. If you need more power, you can use the DRV8825 driver instead of the A4988.

Once you understand the basics, you can start building and controlling your own motor-powered projects based on A4988 Stepper Driver Module.


Bill of Materials

To follow along with the A4988 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 NameQuantityPurchase Links
1Raspberry Pi Pico Board1Amazon | AliExpress
2A4988 Stepper Motor Driver1Amazon | AliExpress
3. NEMA17 Stepper Motor1Amazon | AliExpress
4Electrolytic Capacitor 10uF1Amazon | AliExpress
5Electrolytic Capacitor 100uF1Amazon | AliExpress
67805 Voltage Regulator IC1Amazon | AliExpress
712V DC Adapter1Amazon | AliExpress
8Connecting Jumper Wires20Amazon | AliExpress
9Breadboard1Amazon | AliExpress




A4988 Stepper Motor Driver Module

The A4988, a comprehensive Microstepping Motor Driver, comes with an integrated translator, simplifying its operation. Manufactured by Allegro, the breakout board is equipped with several notable features including adjustable current limiting, protection against over-current and over-temperature, and the ability to choose between five distinct microstep resolutions.

A4988 Stepper Driver Module

This versatile driver operates within a wide voltage range of 8 V to 35 V. It can deliver around 1 A per phase without the need for a heat sink or forced airflow. However, with appropriate cooling measures in place, its performance can be elevated to handle up to 2A per coil.

Besides, this driver is compact, making it suitable for projects where space is a constraint. It also supports full, half, quarter, eighth, and sixteenth step modes, providing flexibility in controlling stepper motors with different levels of precision. This makes the A4988 a popular choice in projects involving 3D printers, CNC machines, and other automated robotic systems.

Features

  1. Max. Operating Voltage: 35V
  2. Min. Operating Voltage: 8V
  3. Max. Current Per Phase: 2A
  4. Microstep resolution: Full step, ½ step, ¼ step, 1/8 and 1/16 step
  5. Reverse voltage protection: No
  6. Dimensions: 15.5 × 20.5 mm (0.6″ × 0.8″)
  7. Short-to-ground and shorted-load protection
  8. Low RDS(ON) outputs
  9. Thermal shutdown circuitry

A4988 Motor Driver Pinout

The A4988 driver has total of 16 pins which are as follows:

1. Power Supply Pins: The pin include VDD & VMOT & Pair of GND pins. VDD is employed for driving the interior logic circuitry which may be 3V to 5V whereas VMOT supplies power for the motor which may be 8V to 35 V.

2. Microstep Selection Pins: The A4988 driver has three-step resolution selector inputs, i.e., MS1, MS2 & MS3. By setting appropriate logic levels to those pins we will set the motors to at least one of the five-step resolutions.

3. Control Input Pins: STEP & DIR are the 2 control input pins. STEP input controls the micro-steps of the motor whereas DIR input controls the spinning direction of the motor.

4. Power States Control Pin: The A4988 has three different inputs for controlling its power states, i.e EN, RST, and SLP. The EN pin is active low input, when pulled LOW the A4988 driver is enabled. 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 2B, 2A, 1B, 1A. We can connect any bipolar stepper motor having voltages between 8V to 35 V to those pins.


Heat Sink Requirement

It is safe to use the A4988 Driver without a heat sink if the current rating is up to 1A. For achieving more than 1A per coil, a heat sink or other cooling method is required.

Because of the excessive power dissipation of the A4988 driver, there is a rise of 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.5

For example, if the Stepper Motor is rated for 350mA, we need to adjust the reference voltage to 0.14V. Take a small screwdriver and adjust the current limit with a potentiometer until you reach the rated current.

A4988 Current Limit Setting


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.”

Nema17 Motor Wiring

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:

  1. Black and Green wires: often correspond to one coil, which can be referred to as Coil A or Phase 1.
  2. Red and Blue wires: often correspond to the other coil, which can be referred to as Coil B or Phase 2.




Interfacing NEMA17 Stepper Motor with Raspberry Pi Pico & A4988

To control a NEMA17 stepper motor using the A4988 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.

Control Stepper Motor with A4988 Driver & Raspberry Pi Pico

For power, connect the VMOT pin on the A4988 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.

NEMA17 Stepper Motor A4988 Raspberry Pi Pico MicroPython

The NEMA17 stepper motor is then connected to the A4988 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 A4988 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 A4988 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 A4988 & Potentiometer

The NEMA17 stepper motor with A4988 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.

NEMA17 Raspberry Pi Pico A4988

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, widely used in robotics and 3D printing, can be efficiently controlled using the A4988 driver and Raspberry Pi Pico with MicroPython. This article has guided you through the essential steps to connect and program these components.

With the foundational knowledge gained, you can now adapt this to various projects in robotics and 3D printing. Ultimately, understanding these basics will empower you to design and manage your own motor-based projects using the A4988 Stepper Driver Module & Raspberry Pi Pico using MicroPython Code.

Share. Facebook Twitter Pinterest LinkedIn Tumblr Email Reddit Telegram WhatsApp
Previous ArticleHow to Control Stepper Motor with DRV8825 Driver & ESP8266
Next Article JSN-SR04T Waterproof Ultrasonic Sensor with Arduino Guide

Related Posts

ADXL375 Accelerometer with Raspberry Pi Pico & MicroPython

ADXL375 Accelerometer with Raspberry Pi Pico & MicroPython

Updated:July 24, 2025
Interface BMI160 with Raspberry Pi Pico & MicroPython

Interface BMI160 with Raspberry Pi Pico & MicroPython

Updated:February 2, 20253K
Shift Register 74HC595 with Raspberry Pi Pico & MicroPython

Shift Register 74HC595 with Raspberry Pi Pico & MicroPython

Updated:February 2, 202513K
Interfacing XBee Module with Raspberry Pi Pico & MicroPython

Interfacing XBee Module with Raspberry Pi Pico & MicroPython

Updated:February 2, 20253K
Modbus RTU with Raspberry Pi Pico & Micropython

Modbus RTU with Raspberry Pi Pico & MicroPython

Updated:February 2, 20258K
Fever Detector with MLX90640 & OpenCV Raspberry Pi

Thermal Fever Detector with MLX90640 & OpenCV Raspberry Pi

Updated:February 2, 20256K
Add A Comment

CommentsCancel reply

Latest Posts
IoT Based PM & Air Quality Monitoring System using ESP32

IoT Based PM & Air Quality Monitoring System using ESP32

May 31, 2026
DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

DIY ESP32 MLX90640 IR Thermal Camera with Live Web Display

May 10, 2026
IoT Activity Tracker with ESP32 & Accelerometer Gyroscope

IoT Activity Tracker with ESP32 & Accelerometer/Gyroscope

May 2, 2026
A Guide to Sourcing Obsolete ICs for Vintage Projects

Beyond AliExpress: A Guide to Sourcing Obsolete ICs for Vintage Projects

April 21, 2026

ESP32 IoT Vehicle Motion Analyzer with MPU6050 & LIS3MDL

April 27, 2026
Building a Smart Sensor Node with a BLE Microcontroller

Building a Smart Sensor Node with a BLE Microcontroller

February 26, 2026
High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

High-Accuracy Pitch, Roll, Yaw with ESP32 & BNO08x IMU

April 27, 2026
DIY Colorimeter using AS7265x Spectroscopy Sensor & ESP32

DIY Colorimeter using AS7265x Spectroscopy Sensor & ESP32

February 1, 2026
Top Posts & Pages
  • How to use INA219 DC Current Sensor Module with Arduino
    How to use INA219 DC Current Sensor Module with Arduino
  • 12V DC to 220V AC Inverter Circuit & PCB
    12V DC to 220V AC Inverter Circuit & PCB
  • ECG Graph Monitoring with AD8232 ECG Sensor & Arduino
    ECG Graph Monitoring with AD8232 ECG Sensor & Arduino
  • Designing of MPPT Solar Charge Controller using Arduino
    Designing of MPPT Solar Charge Controller using Arduino
  • How to use INA226 DC Current Sensor with Arduino
    How to use INA226 DC Current Sensor with Arduino
  • Buck Converter: Basics, Working, Design & Application
    Buck Converter: Basics, Working, Design & Application
  • How to use Modbus RTU with ESP32 to read Sensor Data
    How to use Modbus RTU with ESP32 to read Sensor Data
  • IoT AC Energy Meter with PZEM-004T & ESP32 WebServer
    IoT AC Energy Meter with PZEM-004T & ESP32 WebServer
Categories
  • Arduino Projects (197)
  • Articles (60)
    • Learn Electronics (19)
    • Product Review (15)
    • Tech Articles (28)
  • Electronics Circuits (46)
    • 555 Timer Projects (21)
    • Op-Amp Circuits (7)
    • Power Electronics (13)
  • IoT Projects (204)
    • ESP32 MicroPython (7)
    • ESP32 Projects (81)
    • ESP32-CAM Projects (15)
    • ESP8266 Projects (76)
    • LoRa/LoRaWAN Projects (22)
  • Microcontrollers (38)
    • AMB82-Mini IoT AI Camera (4)
    • BLE Projects (18)
    • STM32 Projects (19)
  • Raspberry Pi (93)
    • Raspberry Pi Pico Projects (57)
    • Raspberry Pi Pico W Projects (12)
    • Raspberry Pi Projects (24)
Follow Us
  • Facebook
  • Twitter
  • Pinterest
  • Instagram
  • YouTube
About Us

“‘How to Electronics’ is a vibrant community for electronics enthusiasts and professionals. We deliver latest insights in areas such as Embedded Systems, Power Electronics, AI, IoT, and Robotics. Our goal is to stimulate innovation and provide practical solutions for students, organizations, and industries. Join us to transform learning into a joyful journey of discovery and innovation.

Copyright © How To Electronics. All rights reserved.
  • About Us
  • Disclaimer
  • Privacy Policy
  • Contact Us
  • Advertise With Us

Type above and press Enter to search. Press Esc to cancel.

Ad Blocker Enabled!
Ad Blocker Enabled!
Looks like you're using an ad blocker. Please allow ads on our site. We rely on advertising to help fund our site.