Control Stepper Motor with A4988 Driver Module and ESP32

In this getting started tutorial, we will learn to interface the A4988 stepper motor driver module with ESP32. This A4988 driver module which is used to control a stepper motor in a relatively simple manner. Using only two pins of ESP32 and A4988 driver module, we can control the speed of the rotation as well as the direction of rotation of a stepper motor. We will learn all about this driver module and how to use it with Arduino to control a bipolar NEMA 17 stepper motor. This guide also includes two Arduino sketches that provide a good basic understanding of how to easily control the speed, direction as well as acceleration/deceleration of the stepper motor using this stepper motor driver module.

We have similar guides with Arduino and ESP8266 NodeMCU:

We will require the following components for this user guide:

Required Components

  • ESP32 development board
  • A4988 Driver Module
  • NEMA 17 Stepper Motor
  • External 12V power supply
  • Connecting Wires

Stepper Motors

Stepper motors are DC brushless and synchronous motors. They rotate in discrete steps of predefined values and are able to rotate both clockwise and anticlockwise. Unlike other DC motors, they provide a precise position control according to the number of steps per revolution for which the motor is designed. That means a complete revolution of a stepper motor is divided into a discrete number of steps. They are commonly used in CNC machines, Robotics, 2D and 3D printers.

For this guide, we will use a NEMA 17 stepper motor and control it through A4988 Driver Module.

NEMA 17 Stepper Motor

It is suitable for 3d printers, CNC Machines, Engraving Machines, Robot Arms, etc. In low-speed devices which require smart rotatory movement at a specific speed without missing any single step can use the NEMA 17. NEMA 17 torque-speed is changeable by applying the different operating speeds. Actually, the torque depends on multiple factors, which are applying current, voltages, and the third factor is the induction of coil within the motor. The rotation of the motor requires the magnetic field to make a single step. The time required to make the coil fully magnetic depends on the induction of the coil.

In NEMA 17 all pins are connected internally with the coil. To make the movement we need to magnetize the coil. Internally to control the stepper motor we will have to use the green and black pair. The second pair will be of red and blue.

NEMA 23 Stepper motor pinout

Specifications

  • Its rated voltage is 12V
  • Phase current is 2.2A
  • The Holding torque is equal to 40N.cm
  • One step angle will be of 1.8 Deg.
  • Total steps for each resolution will be 200.
  • 4-wire and 8-inch lead
  • Number of phases are 4
  • Total inductance by each phase will be 2.8 mH
  • The resistance of the coil is 1.5 Ohm per coil.

For more information about NEMA 17 refer to its datasheet here.

A4988 Driver Module

A4988 Driver Module
A4988 Driver Module

The A4988 Driver Module is used to control the speed and direction of stepper motors mainly used in robotics, toys, 3D printers for motion control. It is capable of operating bipolar stepper motors in full step, half step, quarter step, eighth step, and sixteenth step modes. There is a built in translator which allows only two pins from the ESP32 board to be used to control the speed and direction of the stepper motor.

A4988 stepper motor Driver Module

This compact and small sized driver module has the following specifications:

  • Maximum Operating Voltage: 35V
  • Minimum Operating Voltage: 8V
  • Maximum Current per phase is 2A so it can easily control NEMA17 that has an output current of 2A per phase.
  • Dimensions: 15.5 × 20.5 mm (0.6″ × 0.8″)
  • Capable of operating bipolar stepper motors in full step, half step, quarter step, eighth step, and sixteenth step modes
  • In full step, the driver has 200 steps per revolution which is 1.8 degrees per step.
  • Has thermal shutdown circuitry

The A4988 Driver Module as comes with a heat sink to cool the inner circuity in case of higher power dissipation. It allows the IC to cool down if temperatures go higher than safe ones.

A4988 Driver Module heat sink
A4988 Driver Module with Heatsink

We can easily attach the heatsink on top of the A4988 IC as shown in the diagram above. This will protect the IC in case the temperature exceeds to a higher value. Thus, if you not attaching the heat sink then the driver module will allow 1A current per phase. However, with cooling feature the maximum allowed current per phase will be 2A instead. So it is always advisable to use the heatsink.

Pinout

The figure below shows the 16 pins that are present on the A4988 Driver Module:

A4988 Driver Module Pinout

The module has a total of 16 pins which can be divided in four categories: the output pins in blue which will be connected with the motor, the control pins in green, the step size selection pins in brown and the power pins in red.

Let us discuss them one by one.

Motor Pins

These are the motor coil pins connected to each of the four coils of the motor. These pins will be connected with bipolar stepper motors (8V-35V) where output maximum current is 2A per coil. Hence each pin will be able to supply max 2A to each of the coil of the stepper motor.

  • 2B: This is connected with motor coil 2 second pin.
  • 2A: This is connected with motor coil 1 second pin.
  • 1A: This is connected with motor coil 1 first pin.
  • 1B: This is connected with motor coil 2 first pin.

Control Pins

These are the control pins which are used to control the where EN, SLP and RST control the power states and DIR and STEP control the input.

  • STEP: This is the pin which controls the rotation steps (microsteps) of the motor. It will be connected with a GPIO pin of ESP32. When a high signal will be passed to this pin, the motor will move by one step. The speed of the motor rotation will change according to how soon the signal of the pin goes high.
  • DIR: This is the pin which controls the direction of the rotation of the motor. This will also be connected to a GPIO pin of ESP32. When a high signal is passed to this pin, the motor will rotate clockwise whereas if a low signal is provided instead, the motor will rotate in an anti-clockwise direction.
  • EN: This is the enable pin. It is used turn the outputs of the module on or off. A high signal will disable the outputs. By default the pin is at a low state.
  • RST: This is the reset pin. It sets the internal translator to a predefined Home state which is the position where the motor starts initially. This position will vary depending upon the microstep resolution. This is an active low input where a HIGH signal will enable the driver.
  • SLP: This is also an active low input pin which is used to reduce power consumption by setting the module to sleep mode when the motors are not in use. This is achieved by supplying a low signal to this pin.

Step Size Selection Pins

These three pins MS1, MS2 and MS3 are used to select the microstep resolution from the given five options which this driver module supports. The table below shows the states required for each of these three pins to enable the appropriate microstep resolution.

MS1MS2MS3Microstep Resolution
LOWLOWLOWFull Step
HIGHLOWLOW1/2 Step
LOWHIGHLOW1/4 Step
HIGHHIGHLOW1/8 Step
HIGHHIGHHIGH1/16 Step

Moreover, these three pins are connected internally with pull-down resistors so by default when un connected the microstep resolution will be set as full step.

Power Pins

Lastly, we will talk about the power pins that include VMOT,GND and VCC and GND. As you may notice there are two power connections required for this driver. One for the stepper motor power and the other to power the A4988 driver module.

  • VMOT, GND: This is the stepper motor power supply pins. Connect 8-35V external power supply with VMOT and common ground.
  • VCC, GND: This is the A4988 driver module power supply pins. Connect 3-5.5V from microcontroller with VCC and common ground with microcontroller.

Interfacing A4988 with stepper motor and ESP32

To connect the ESP32 board with the stepper motor and driver we will use all the pins of the driver except for the enable pin and the micro step resolution selection pins.

Follow the schematic diagram below to properly connect all the devices together.

A4988 Driver Module and stepper motor with ESP32 connection diagram
ESP32 with A4988 and stepper motor connection diagram

Connect the output pins of the driver with the respective motor pins. Connect the STEP pin and the DIR pin with any appropriate GPIO pin of ESP32 board. We have used GPIO12 to connect with DIR and GPIO14 to connect with STEP. As we want to operate our stepper mode in full mode hence we will leave the MS1, MS2 and MS3 pins as they are. The RST pin will be connected with SLP so that the driver is enabled. Moreover, the VCC and GND pins will be connected with Vin and GND pin from ESP32 respectively. The VMOT will be connected with an external power supply ranging between 8-35V. We are using 12V external power supply. Make sure the GND pins are connected with the respective common grounds.

Additionally, we can also add a capacitor(minimum 47uF) with the external power supply connected with the stepper motor power supply pins to avoid voltage spike issues.

A4988 Driver Module and stepper motor with ESP32

Current Limit

Before connecting the stepper motor with the driver module we have to make sure that the current running through the motor coils does not exceed the maximum rated current of the motor. To do that we will use the current limiting potentiometer featured on the A4988 motor driver as seen below:

A4988 Driver Module Potentiometer

We will require a multimeter. Connect the positive terminal of the multimeter with the potentiometer and the negative end of the mutimeter with the GND of the driver module. The voltage measured at this point will be known as Vref. Adjust the potentiometer by turning it and the values for Vref will vary.

To set a current limit the following formula is used:

Current Limit = Vref x 2.5

Now set the Vref according to your motor’s rated current in order to ensure that the current is within the current limits of the motor.

Arduino Sketch Controlling NEMA 17 Stepper Motor with A9488 driver

Open your Arduino IDE and go to File > New. A new file will open. Copy the code given below in that file and save it.

This code will help us control the stepper motor using the A9488 driver’s DIR and STEP pins. We will show you how to rotate the motor in both directions at different speeds.

const int DIR = 12;
const int STEP = 14;
const int  steps_per_rev = 200;

void setup()
{
  Serial.begin(115200);
  pinMode(STEP, OUTPUT);
  pinMode(DIR, OUTPUT);
}
void loop()
{
  digitalWrite(DIR, HIGH);
  Serial.println("Spinning Clockwise...");
  
  for(int i = 0; i<steps_per_rev; i++)
  {
    digitalWrite(STEP, HIGH);
    delayMicroseconds(2000);
    digitalWrite(STEP, LOW);
    delayMicroseconds(2000);
  }
  delay(1000); 
  
  digitalWrite(DIR, LOW);
  Serial.println("Spinning Anti-Clockwise...");

  for(int i = 0; i<steps_per_rev; i++)
  {
    digitalWrite(STEP, HIGH);
    delayMicroseconds(1000);
    digitalWrite(STEP, LOW);
    delayMicroseconds(1000);
  }
  delay(1000);
}

How the Code Works?

The first step is to define the GPIO pins of ESP32 we have connected with the DIR and STEP pins of the driver. As you can see we have used GPIO12 and GPIO14 to connect with DIR and STEP respectively. However, you can use any other suitable ESP32 GPIO pins as well.

const int DIR = 12;
const int STEP = 14;

The next step is to define the steps per revolution. This is the number of steps our motor requires to move one complete revolution.

const int  steps_per_rev = 200;

Inside the setup() function, Serial.begin() is used to establish the serial connection between the development board at a baud rate of 115200. We will use the pinMode() function to configure the digital pins connected with STEP and DIR as output pins.

void setup()
{
  Serial.begin(115200);
  pinMode(STEP, OUTPUT);
  pinMode(DIR, OUTPUT);
}

loop()

Inside the loop() function we will first rotate the stepper motor in clockwise direction at a faster speed and then rotate it in the opposite direction at a slower speed. This will occur with a delay of 1 second.

To control the direction of the motor we will use the digitalWrite() function and pass the DIR pin as the first parameter and the state of the pin as the second parameter. To move the motor in the clockwise direction a high signal is passed to the DIR pin. Likewise, to move the motor in the anti-clockwise direction, a low signal is passed to the DIR pin. Additionally, the serial monitor will display the direction of the motion of the motor.

 digitalWrite(DIR, HIGH);
  Serial.println("Spinning Clockwise...");

To control the speed of the motor we will use a for loop till the steps per revolution and change the state of the STEP pin from HIGH to LOW with a delay in between. The faster the state of the STEP pin will be set to HIGH the faster the motor will spin. By increasing/decreasing the delay we are basically changing the frequency of the signal which then alters the speed of the motor.

void loop()
{
  digitalWrite(DIR, HIGH);
  Serial.println("Spinning Clockwise...");
  
  for(int i = 0; i<steps_per_rev; i++)
  {
    digitalWrite(STEP, HIGH);
    delayMicroseconds(2000);
    digitalWrite(STEP, LOW);
    delayMicroseconds(2000);
  }
  delay(1000); 
  
  digitalWrite(DIR, LOW);
  Serial.println("Spinning Anti-Clockwise...");

  for(int i = 0; i<steps_per_rev; i++)
  {
    digitalWrite(STEP, HIGH);
    delayMicroseconds(1000);
    digitalWrite(STEP, LOW);
    delayMicroseconds(1000);
  }
  delay(1000);
}

Demonstration

Make sure you choose the correct board and COM port before uploading your code to the board. Go to Tools > Board and select ESP32 Dev Module. Next, go to Tools > Port and select the appropriate port through which your board is connected.

select esp32 board

Click on the upload button to upload the code into the board.
After you have uploaded your code to the development board, press its ENABLE button.

ESP32 enable reset button

The stepper motor will start rotating clockwise and then anti-clockwise repeatedly.

In your Arduino IDE, open up the serial monitor and you will be able to see the status of the motor rotation as well.

A4988 with ESP32 and stepper motor demo 1
Serial Monitor

Installing AccelStepper Library

We will require the AccelStepper library present in Arduino Library Manager to control more stepper motors as well as include acceleration/deceleration as well. This library will provide us useful functions to set the maximum speed, acceleration and steps per revolution to rotate the motor in both directions.

To install the library, we will use the Arduino Library Manager. Open your Arduino IDE and go to Sketch > Include Libraries > Manage Libraries. Type ‘Accelstepper’ in the search bar and install the latest version.

Installing AccelStepper library

Arduino Sketch Controlling Stepper Motor

Open your Arduino IDE and go to File > New. A new file will open. Copy the code given below in that file and save it.

This code will help us control the stepper motor by setting the maximum speed, acceleration and steps per revolution. We will show you how to rotate the motor in both directions.

#include <AccelStepper.h>

const int DIR = 12;
const int STEP = 14;

#define motorInterfaceType 1
AccelStepper motor(motorInterfaceType, STEP, DIR);

void setup() {
  Serial.begin(115200);
  motor.setMaxSpeed(1000);
  motor.setAcceleration(60);
  motor.setSpeed(200);
  motor.moveTo(200);
}

void loop() {
  if (motor.distanceToGo() == 0) {
    motor.moveTo(-motor.currentPosition());
    Serial.println("Rotating Motor in opposite direction...");
  }
  motor.run();
}

How the Code Works?

Firstly, we will include the AccelStepper.h library. This library provides useful functions that make it easy to control the stepper motor using Arduino.

#include <AccelStepper.h>

The next step is to define the GPIO pins of ESP32 we have connected with the DIR and STEP pins of the driver. As you can see we have used the GPIO12 and GPIO14 to connect with DIR and STEP respectively.

const int DIR = 12;
const int STEP = 14;

Additionally, we will define motor interface type as ‘1’. This means that we are using an external driver that consists of the STEP and DIR pins.

#define motorInterfaceType 1

Now we will create an instance of the AccelStepper library called motor() and pass motorInterfaceType, STEP and DIR as the three parameters inside it.

AccelStepper motor(motorInterfaceType, STEP, DIR);

Inside the setup() function, Serial.begin() is used to establish the serial connection between the development board at a baud rate of 115200. We will use the setMaxSpeed() method on the motor instance and pass the speed of the motor as an argument inside it. In our case we are setting the stepper motor speed to 1000. We will also set the acceleration of the motor using setAcceleration() and pass the acceleration in steps per second per second. The moveTo() method takes in the argument steps per revolution which is 200 as we are using NEMA 17. This will be used to mark our target position.

void setup() {
  Serial.begin(115200);
  motor.setMaxSpeed(1000);
  motor.setAcceleration(60);
  motor.setSpeed(200);
  motor.moveTo(200);
}

loop()

Inside the loop() function, we will rotate the motor in both directions. This will be achieved by keeping track of the target position. If the target position has been reached then another target position will be marked. This will be the same in value as before but with a negative sign. Thus, reversing the direction of the motor. Additionally, we will print when the motor changes direction in the serial monitor as well. The run() method will be responsible to rotate the motor every one step at a time.

void loop() {
  if (motor.distanceToGo() == 0) {
    motor.moveTo(-motor.currentPosition());
    Serial.println("Rotating Motor in opposite direction...");
  }
  motor.run();
}

Demonstration

Make sure you choose the correct board and COM port before uploading your code to the board. Go to Tools > Board and select ESP32 Dev Module. Next, go to Tools > Port and select the appropriate port through which your board is connected.

select esp32 board

Click on the upload button to upload the code into the board.
After you have uploaded your code to the development board, press its ENABLE button.

ESP32 enable reset button

The stepper motor will start rotating clockwise while accelerating until one revolution and then move anti-clockwise while decelerating and then stopping. Then the loop will start again.

In your Arduino IDE, open up the serial monitor and you will be able to see the status of the motor rotation as well.

A4988 with ESP32 and stepper motor demo 2
Serial Monitor

You may also like to read:

5 thoughts on “Control Stepper Motor with A4988 Driver Module and ESP32”

  1. I did every thing you said but I get this error I don’t know what is wrong I tried 2 es32s that I have and still get this error

    Arduino: 1.8.12 (Windows 10), Board: “ESP32 Dev Module, Disabled, Default 4MB with spiffs (1.2MB APP/1.5MB SPIFFS), 240MHz (WiFi/BT), QIO, 80MHz, 4MB (32Mb), 921600, None”

    Sketch uses 207966 bytes (15%) of program storage space. Maximum is 1310720 bytes.
    Global variables use 13512 bytes (4%) of dynamic memory, leaving 314168 bytes for local variables. Maximum is 327680 bytes.
    esptool.py v3.0-dev
    Serial port COM7
    Connecting…….._____….._____….._____….._____….._____….._____….._____

    A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header
    A fatal error occurred: Failed to connect to ESP32: Timed out waiting for packet header

    This report would have more information with
    “Show verbose output during compilation”
    option enabled in File -> Preferences.

    Reply
    • When you get to the ‘Connecting …’ part, press and hold the BOOT button on the ESP32. When it starts to download the sketch release the button.

      Some of the clone ESP32 require the button to be pressed to do a download. I have had some of them require it only sometimes. I don’t understand why, but that’s how to get your sketch to download.

      Reply
  2. I have been trying for a few weeks now. I dont understand what im doing wrong. The firmware is correct , i have set the vref to 0.8 volt (0.79v i guess its doesnt need to be 0.01 v accurate…) and turn on the esp32. the motor makes a ticking sound when its turned on and then doesnt react to anything. i have tried turning the screw to adjust the vref but nothing seems to help. There is a 24 v power supply connected to de vmot which should be sufficient. Any ideas why its not working? Its an old ender 3 stepper motor which im sure is working.

    Reply
  3. So i found the problem why it wasnt working. You need a power supply corresponding to the motor. You cant connect a 24 volt to the vmot when the motor is 12 volt. in the tutorial it says you can use any power supply within the range but that is not correct. you do need a supply that has the same voltage rating as the motor

    Reply

Leave a Comment