ESP32 - 28BYJ-48 Stepper Motor ULN2003 Driver

In this tutorial, we will cover the following topics:

ESP32 ULN2003 28BYJ-48 stepper motor

Stepper motors excel in precision position control, as they break down a complete revolution into discrete "steps." These motors find applications in a wide range of devices, including printers, 3D printers, CNC machines, and industrial automation systems.

An affordable method for gaining insight into stepper motors is by experimenting with 28BYJ-48 stepper motors. Typically, these motors are bundled with driver boards based on the ULN2003, simplifying their utilization to a great extent.

Hardware Used In This Tutorial

1×ESP-WROOM-32 Dev Module
1×USB Cable Type-C
1×28BYJ-48 stepper motor + ULN2003 Driver Module
1×5V Power Adapter
1×DC Power Jack
1×Jumper Wires
1×(Recommended) Screw Terminal Expansion Board for ESP32
1×(Recommended) Power Splitter For ESP32

Or you can buy the following sensor kits:

1×DIYables Sensor Kit (30 sensors/displays)
1×DIYables Sensor Kit (18 sensors/displays)
Disclosure: Some of the links in this section are Amazon affiliate links, meaning we may earn a commission at no additional cost to you if you make a purchase through them. Additionally, some links direct you to products from our own brand, DIYables.

Introduction to 28BYJ-48 Stepper Motor

As per the data sheet, the 28BYJ-48 motor, when operating in full-step mode, moves in 11.25-degree increments, resulting in 32 steps per complete revolution (as calculated: 360°/11.25° = 32).

Furthermore, the motor incorporates a 1/64 reduction gear set, effectively increasing its step count to 32 x 64, resulting in 2048 steps per revolution. Each of these 2048 steps corresponds to a rotation of 360°/2048, which is approximately 0.1758 degrees per step.

Conclusion: if motor do 2048 steps (in full-step mode), the motor rotate one revolution

Pinout

28BYJ-48 stepper motor includes 5 pins. We do not need to care detail about these pins. We just need to plug it to the connector of ULN2003 motor driver.

28BYJ-48 stepper motor

Introduction to ULN2003 Stepper Motor Driver Module

The ULN2003 stands out as a widely used motor driver module for stepper motors. Key features of the module include:

  • Four LEDs that illuminate to indicate the activity of the four control input lines, effectively reflecting the current stepping state of the motor. These LEDs not only serve a practical purpose but also add a visual element to the stepping process.
  • An ON/OFF jumper is integrated into the module, enabling the isolation of power to the connected stepper motor. This feature offers a convenient means to control the motor's power supply, allowing for efficient power management.

ULN2003 Pinout

ULN2003 Stepper Motor Driver Pinout

ULN2003 module includes 6 pins and one female connector:

  • IN1 pin: is used to drive the motor. Connect it to an output pin on ESP32.
  • IN2 pin: is used to drive the motor. Connect it to an output pin on ESP32.
  • IN3 pin: is used to drive the motor. Connect it to an output pin on ESP32.
  • IN4 pin: is used to drive the motor. Connect it to an output pin on ESP32.
  • GND pin: is a common ground pin. It MUST connect to both GNDs of ESP32 and the external power supply.
  • VDD pin: supplies power for the motor. Connect it to the external power supply.
  • Motor Connector: this is where the motor plugs into.

※ NOTE THAT:

When it comes to powering stepper motors, it's important to follow these guidelines:

  • Ensure that the voltage of the external power supply matches the voltage requirements of the stepper motor. For example, if your stepper motor operates on 12V DC, it's crucial to use a 12V power supply. In the case of the 28BYJ-48 stepper motor, which functions on 5V DC, it's imperative to employ a 5V power supply.
  • It's important to note that even if a stepper motor is designed to run on a 5V power supply, do NOT connect the VDD pin to the 5V pin on the ESP32. Instead, link the VDD pin to an external 5V power source. This precautionary measure is essential because stepper motors can draw a significant amount of power, which might exceed the capabilities of the ESP32's power supply, potentially causing issues or damage.

Wiring Diagram

ESP32 stepper motor ULN2003 driver Wiring Diagram

This image is created using Fritzing. Click to enlarge image

Please note that, we do not need to care about wire color of stepper motor. We just need to plug male connector ( in 28BYJ-48 stepper motor) to female connector (on ULN2003 driver)

If you're unfamiliar with how to supply power to the ESP32 and other components, you can find guidance in the following tutorial: How to Power ESP32.

How To Program to control a stepper motor

When it comes to controlling a stepper motor, there are three primary methods:

  • Full-Step
  • Half-Step
  • Micro-Step

For basic applications, the full-step method is often sufficient. However, detailed explanations of all three methods will be provided in the final part of this tutorial. It's worth noting that programming for these methods can be complex. The good news is that there are many libraries available that handle this complexity for us. All we need to do is make use of the appropriate library, simplifying the control of stepper motors in our projects.

The Arduino IDE includes a built-in Stepper library, but we advise against using it for the following reasons:

  • Blocking Nature: This library operates in a blocking manner, which means it monopolizes the ESP32's resources, preventing it from performing other tasks while controlling the stepper motor.
  • Limited Functionality: The built-in Stepper library may not provide all the functions and features you need for your project.

Instead, we recommend utilizing the AccelStepper library. This library offers several advantages, including:

  • Acceleration and Deceleration: It supports smooth acceleration and deceleration, allowing for more precise control.
  • Full-Step and Half-Step Driving: You can choose between full-step and half-step driving modes for your stepper motor.
  • Multiple Simultaneous Steppers: AccelStepper permits the control of multiple steppers simultaneously, with each stepper moving independently and concurrently.

However, it's important to note that the library has one disadvantage: it does not support micro-step driving.

ESP32 Code

/* * This ESP32 code is created by esp32io.com * * This ESP32 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-28byj-48-stepper-motor-uln2003-driver */ // Include the AccelStepper Library #include <AccelStepper.h> // define step constant #define FULLSTEP 4 #define STEP_PER_REVOLUTION 2048 // this value is from datasheet // Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence AccelStepper stepper(FULLSTEP, 19, 18, 17, 16); // ESP32 pin: GPIO19, GPIO18, GPIO17, GPIO16 void setup() { Serial.begin(9600); stepper.setMaxSpeed(1000.0); // set the maximum speed stepper.setAcceleration(50.0); // set acceleration stepper.setSpeed(200); // set initial speed stepper.setCurrentPosition(0); // set position stepper.moveTo(STEP_PER_REVOLUTION); // set target position: 64 steps <=> one revolution } void loop() { // change direction once the motor reaches target position if (stepper.distanceToGo() == 0) stepper.moveTo(-stepper.currentPosition()); stepper.run(); // MUST be called in loop() function Serial.print(F("Current Position: ")); Serial.println(stepper.currentPosition()); }

Quick Instructions

  • If this is the first time you use ESP32, see how to setup environment for ESP32 on Arduino IDE.
  • Do the wiring as above image.
  • Connect the ESP32 board to your PC via a micro USB cable
  • Open Arduino IDE on your PC.
  • Select the right ESP32 board (e.g. ESP32 Dev Module) and COM port.
  • Click to the Libraries icon on the left bar of the Arduino IDE.
  • Search “AccelStepper”, then find the AccelStepper library by Mike McCauley
  • Click Install button to install AccelStepper library.
ESP32 AccelStepper library
  • Copy the above code and open with Arduino IDE
  • Click Upload button on Arduino IDE to upload code to ESP32
  • See motor rotating. It should:
    • Rotate one revolution in clockwire direction, and then
    • Rotate two revolution in anti-clockwire direction, and then
    • Rotate two revolution in clockwire direction.

    That preccess is repeated infinitely.

    • See the result in Serial Monitor

How to control a multiple 28BYJ-48 stepper motors

Let's learn how to control two stepper motor independently at the same time.

Wiring Diagram for two 28BYJ-48 stepper motors

ESP32 two stepper motor ULN2003 driver Wiring Diagram

This image is created using Fritzing. Click to enlarge image

ESP32 Code for two 28BYJ-48 stepper motors

/* * This ESP32 code is created by esp32io.com * * This ESP32 code is released in the public domain * * For more detail (instruction and wiring diagram), visit https://esp32io.com/tutorials/esp32-28byj-48-stepper-motor-uln2003-driver */ // Include the AccelStepper Library #include <AccelStepper.h> // define step constant #define FULLSTEP 4 #define STEP_PER_REVOLUTION 2048 // this value is from datasheet // Pins entered in sequence IN1-IN3-IN2-IN4 for proper step sequence AccelStepper stepper_1(FULLSTEP, 23, 22, 21, 19); AccelStepper stepper_2(FULLSTEP, 18, 5, 17, 16); void setup() { Serial.begin(9600); stepper_1.setMaxSpeed(1000.0); // set the maximum speed stepper_1.setAcceleration(50.0); // set acceleration stepper_1.setSpeed(200); // set initial speed stepper_1.setCurrentPosition(0); // set position stepper_1.moveTo(STEP_PER_REVOLUTION); // set target position: 64 steps <=> one revolution stepper_2.setMaxSpeed(1000.0); // set the maximum speed stepper_2.setAcceleration(50.0); // set acceleration stepper_2.setSpeed(200); // set initial speed stepper_2.setCurrentPosition(0); // set position stepper_2.moveTo(STEP_PER_REVOLUTION); // set target position: 64 steps <=> one revolution } void loop() { // change direction once the motor reaches target position if (stepper_1.distanceToGo() == 0) stepper_1.moveTo(-stepper_1.currentPosition()); if (stepper_2.distanceToGo() == 0) stepper_2.moveTo(-stepper_2.currentPosition()); stepper_1.run(); // MUST be called in loop() function stepper_2.run(); // MUST be called in loop() function Serial.print(F("stepper_1# current position: ")); Serial.println(stepper_1.currentPosition()); Serial.print(F("stepper_2# current position: ")); Serial.println(stepper_2.currentPosition()); }

※ OUR MESSAGES