Tutorial: How to drive the 28BYJ-48 stepper motor with a ULN2003A driver board and an Arduino Uno

A 28BYJ-48 stepper motor connected to a ULN2003A driver board.

A 28BYJ-48 stepper motor connected to a ULN2003A driver board.

A stepper motor divides a full rotation in multiple steps. As a result, a stepper motor can be driven much more precisely than a conventional dc motor. In particular, stepper motors are driven step by step. After having a quick look into the data sheet of a stepper, we know exactly how many degrees correspond to a single step of our motor. With this information, we can precisely turn the rotor of our stepper motor, since we then know how many degrees correspond to a single step.

The 28BYJ-48 is a very cheap stepper motor that often comes with a ULN2003A driver board. Luckily, the Arduino platform has already a built-in stepper library that allows us to control the 28BYJ-48 stepper motor with the ULN2003A driver board. In this tutorial, it is shown how to control the 28BYJ-48 with an Arduino Uno.

List of materials:
– Arduino Nano [Search on Aliexpress | Amazon]
– Jumper wires [Search on Aliexpress | Amazon]
– 28BYJ-48 stepper motor [Search on Aliexpress | Amazon]
– ULN2003A driver board [Search on Aliexpress | Amazon]

Pin layout:

Pin layout that shows how to connect a 28BYJ-48 stepper motor to a ULN2003A driver board and an Arduino Uno.

Pin layout that shows how to connect a 28BYJ-48 stepper motor to a ULN2003A driver board and an Arduino Uno.

Typically, the 28BYJ-48 motor comes with a 5-pin connector that fits to driver board’s connector. The driver board has two pins for the power supply which are labeled GND and VCC. The board’s GND pin must be wired to the Arduino’s GND pin. Accordingly, the board’s VCC pin must be connected to the Arduino’s 5V pin.
Important remark: With this setup, we are powering the motor directly from the Arduino. The advantage is that this is the possible easiest solution for providing power to the motor. However, if the motor consumes too much power, the Arduino can be permanently damaged. If you use a different setup (driver, motor, source code, etc.), make sure that you do not draw more than about 300mA out of the Arduino. If you need more power, just use an external voltage supply for your driver board.
Lastly, the driver board’s IN1, IN2, IN3 and IN4 pins must be connected to the Arduino. In this tutorial, pins 8 to 11 of the Arduino are used (IN1<->8, IN2 <-> 9, IN3 <-> 10, IN4 <-> 11).

Example source code:
In the beginning, we include the header file of the Arduino plattform’s built-in stepper library. Then, we define the number of steps that the motor needs for one revolution. Stepper motors can turn out very complicated, therefore, it is not that easy to look up this number.

For example, you can typically drive stepper motors in different modes and, moreover, they have a specific gear ration. Both have an influence on the number of steps per revolution. Since we drive the motor in the so-called full step mode (control sequence with four steps), each step corresponds to a rotation of 11.25 degrees according to the data sheet. This corresponds to 32 steps per revolution (360° / 11.25° = 32). In addition, the manufacturer specified a gear ratio of 64:1 for this type of motor. Normally, this gear ratio must be multiplied by the 32 steps. If you examine the 28BYJ-48 in more detail, it turns out that the actual gear ratio is approximately 63.68395:1. Therefore we set the final number of steps to 2038 (32 * 63.68395=2037.8864).

Next, we initialize the stepper. The first parameter of the Stepper constructor is the number of steps. The other parameters correspond to the Arduino’s pins that we used to connect the ULN2003A driver board.

In the loop function, we start to drive the motor. First, we set the speed to one revolutions per minute . Next, we tell the stepper motor to do 2038 steps. As one revolution corresponds to 2038 steps, the motor’s shaft should move a full revolution in approximately one minute. Next, we set a delay of one second. Then, we do the same thing again. But this time, we set the speed to 6 rounds per minute and move the shaft in the other direction (by setting a negative number of steps). As the the shaft moves six times faster now, the motor should finish a full revolution in about 10 seconds (60s/6=10s).

// (c) Michael Schoeffler 2017, http://www.mschoeffler.de

#include <Stepper.h>

#define STEPS 2038 // the number of steps in one revolution of your motor (28BYJ-48)

Stepper stepper(STEPS, 8, 10, 9, 11);

void setup() {
  // nothing to do

void loop() {
  stepper.setSpeed(1); // 1 rpm
  stepper.step(2038); // do 2038 steps -- corresponds to one revolution in one minute
  delay(1000); // wait for one second
  stepper.setSpeed(6); // 6 rpm
  stepper.step(-2038); // do 2038 steps in the other direction with faster speed -- corresponds to one revolution in 10 seconds
The stepper motor is driven by the ULN2003A driver board. The board's LEDs show the current control sequence state.

The stepper motor is driven by the ULN2003A driver board. The board’s LEDs show the current control sequence state.

Video Tutorial:

5 thoughts on “Tutorial: How to drive the 28BYJ-48 stepper motor with a ULN2003A driver board and an Arduino Uno

  1. Ben Messaoud Wael

    Dear Michael,

    Thank you for this very clear tutorial and for the video.
    My problem is how to initialize the initial angle of the stepper motor.
    I understand when testing the device, that the system begin from the actual position of the servo to do the required angle, but is it possible to initialize the first position to 0 for example ?

    I would like to know also if it is possible to run another program in parallel with the motion of the motor ?
    My last question is: by using the library Stepper.h, is it possible to use more functions apart from the functions that you use in your program ? stepper.setSpeed(10); stepper.step(-2038/4); ?

    Thank you

    1. mschoeffler Post author

      Hi Ben,
      (1) a stepper motor and a servo motor are two different types of motors. While a typical servo motor “knows” its position by utilizing an in-built potentiometer, a typical stepper motor is not capable of “knowing” its current position. Therefore, it is not possible to initialize a stepper motor –
      such as the 28BYJ-48 – to a given absolute position :(
      (2) It is possible to run another program while controlling the motor. In this case, I recommend to get rid of the “delay” calls. Alternatively, timer interrupts can be used to control a motor at given times.
      (3) Unfortunately, the Stepper library does not offer any more functions (Reference: https://www.arduino.cc/en/Reference/Stepper)
      I hope my answers are helpful to you. Let me know, if I can help you any further!
      Best, Michael

  2. Kerry Cassella

    Nice tutorial. I modified the above program by changing the delay time to 5 seconds and commented out reversing the stepper. Increased the speed from 1 to 6 rpm. The stepper will rotate clockwise to one full rotation and pause for 5 seconds. After about five turns, the stepper seems to be loosing steps. It doesn’t reach its original starting position. It progressively gets worst.
    Why would the stepper not return to the starting position every time?

    Thank you,


Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.