The ULN2003 stepper driver is a 7-channel Darlington transistor array designed to switch low-voltage, low-current unipolar stepper motors using microcontroller GPIO pins. It maxes out at 500mA per channel and is strictly for unipolar (center-tapped) coils. If you are driving a standard 5V 28BYJ-48 motor from an Arduino or ESP32, this is your default, low-cost interface. If you need high torque, high speed, or are using a bipolar NEMA 17, the ULN2003 is the wrong tool for the job.

Motor Type Comparison: Where the ULN2003 Fits

Before wiring up your breadboard, you must match the motor type to the load profile. Steppers and servos are not interchangeable; servos rely on closed-loop PWM feedback for absolute positioning, while steppers use open-loop pulse counting. The ULN2003 only supports open-loop unipolar steppers.

Motor & Driver Selection Matrix for Embedded Projects
Motor Type Torque Curve & Profile Control Needs Typical Driver Cost (2026)
Unipolar Stepper (28BYJ-48) Low starting torque, holds position well at zero speed. Drops off sharply above 500 RPM. 4x digital GPIO pins, sequenced high/low. No current chopping needed. ULN2003A $2 - $4 (kit)
Bipolar Stepper (NEMA 17) High torque across a wider RPM band. Requires current limiting to prevent coil burnout. Step/Dir pulses. Requires microstepping and active current regulation (chopping). A4988, TMC2209, DRV8825 $12 - $25
DC Gearmotor High speed, low holding torque. Continuous rotation, no native positional feedback. PWM for speed, H-bridge for direction. Requires external encoder for positioning. L298N, TB6612FNG $5 - $10

The Verdict: Choose the unipolar stepper and ULN2003 when your load profile demands precise, low-speed, open-loop positioning (like a motorized camera slider or a small automated blind) on a strict budget. Choose a bipolar stepper with a TMC2209 when you need high torque, fast traversal, and quiet operation (like 3D printer axes).

Wiring, Terminal Identification, and Sizing

The most common mistake makers make with the ULN2003 is treating it like a simple pass-through switch. It is a Darlington pair, which introduces a significant voltage drop and requires careful power routing.

Terminal Identification and Pinout

When using the standard red ULN2003A breakout board with a 28BYJ-48 motor:

  • IN1 to IN4: Logic inputs. Connect to Arduino/ESP32 digital GPIO pins (e.g., D8, D9, D10, D11). These accept 3.3V or 5V logic, though 5V ensures cleaner switching margins.
  • VCC / GND: Motor power. Do not connect this to your Arduino's 5V pin. Connect to an external 5V/2A power supply. The motor draws spikes that will brownout your microcontroller.
  • Motor Socket: The white JST connector. The 28BYJ-48 has a 5-pin plug. Pin 1 is usually the center tap (Red wire), which connects to VCC internally on the board. The board's silkscreen sometimes mislabels the red wire position; always align the red wire with the '+' or 'VCC' marking on the breakout.
Callout Tip: The Darlington Voltage Drop
According to the Texas Instruments ULN2003A datasheet, the collector-emitter saturation voltage ($V_{CE(sat)}$) at 350mA is typically 1.0V to 1.5V. If you supply 5V to the board, your motor coils only see ~3.5V to 4.0V. This reduces your available torque by roughly 20-30%. If your project is torque-starved, supply 6V or 7V to the ULN2003 VCC (the 28BYJ-48 can tolerate brief overvoltage), but keep your logic levels at 5V/3.3V.

Sizing Rule of Thumb and Worked Load Example

The Rule: Your driver's continuous current rating per channel must be at least 1.5x the motor's rated stall current per phase. Stepper motors draw maximum current when stalled or holding, and the driver must survive this thermal load without degrading.

Worked Example: 5V 28BYJ-48

  • Motor coil resistance: ~50Ω per phase.
  • Rated current per phase (Ohm's Law): $I = V / R = 5V / 50\Omega = 100mA$ (nominal), but stall current spikes to ~160mA depending on the exact winding variant.
  • Sizing requirement: $160mA \times 1.5 = 240mA$.
  • ULN2003 capacity: 500mA per channel.
  • Result: 500mA > 240mA. The ULN2003 is correctly sized for this motor.

Worked Example: 12V NEMA 17 Unipolar (Hypothetical)

  • Motor rated current: 800mA per phase.
  • Sizing requirement: $800mA \times 1.5 = 1200mA$.
  • ULN2003 capacity: 500mA.
  • Result: Failure. The Darlington junctions will overheat and destroy the IC. You must use a dedicated MOSFET-based chopper driver for this load.

Failure Signatures: Hum, Overheat, and Stall

When a stepper system fails, it rarely does so silently. The physical symptoms tell you exactly where the electrical or mechanical breakdown is occurring.

  • The Symptom: Loud Humming Without Rotation
    The Cause: The GPIO sequencing is wrong, or the mechanical load exceeds the motor's breakdown torque. If the Arduino is stepping faster than the rotor's physical inertia allows, the magnetic field rotates but the rotor stays locked, vibrating at the step frequency.
    The Fix: Reduce the RPM in your code. For the 28BYJ-48, keep speeds below 15 RPM at the output shaft. If using the Arduino Stepper library, lower the `setSpeed()` parameter. Verify your IN1-IN4 sequence matches the motor's internal winding order (usually IN1-IN3-IN2-IN4 for full step).
  • The Symptom: Driver IC Overheating (Too Hot to Touch)
    The Cause: Power dissipation in the Darlington array. Power = $V_{CE(sat)} \times I$. At 300mA, the chip dissipates ~0.45W per active channel. In full-step mode, two channels are active, dumping nearly 1W into a plastic DIP-16 package with no heatsink. Alternatively, you are accidentally driving a bipolar motor with the center taps tied wrong, causing a dead short through the transistors.
    The Fix: Switch your code to half-stepping or wave-drive (energizing only one coil at a time) when holding position to cut heat in half. Ensure you are actually using a 5-wire unipolar motor.
  • The Symptom: Stalling Under Light Load
    The Cause: Voltage drop across the ULN2003, compounded by a weak power supply. If your 5V wall adapter sags to 4.5V under load, and the ULN2003 drops another 1.2V, the motor coils are receiving only 3.3V. Torque drops with the square of the voltage in this regime.
    The Fix: Measure the VCC terminal on the breakout board with a multimeter while the motor is running. If it drops below 4.8V, upgrade to a higher-amperage power supply and use thicker jumper wires.

Frequently Asked Questions

Can I use a ULN2003 stepper driver for a bipolar NEMA 17 motor?

No. The ULN2003 is an array of NPN Darlington transistors designed to sink current from the center-tapped coils of a unipolar motor. A bipolar motor (like a standard 4-wire NEMA 17) lacks center taps and requires an H-bridge to reverse the current polarity through the coils. Attempting to wire a bipolar motor to a ULN2003 will result in the motor simply locking up, vibrating, or shorting out the driver IC. For a NEMA 17, use a dedicated chopper driver like the TMC2209 or A4988.

Why is my ULN2003 stepper driver getting hot with a 28BYJ-48?

The ULN2003A is inherently inefficient due to the $V_{CE(sat)}$ voltage drop across its Darlington pairs, which turns wasted electrical energy into heat. If it is getting dangerously hot (over 60°C), check two things: First, ensure your code is not leaving all coils energized at full current while the motor is stationary (implement a sleep or power-down state in your logic when movement stops). Second, verify you are not powering the motor from the Arduino's onboard 5V regulator, which can cause ground bounce and erratic current draws that stress the driver.

How do I wire a ULN2003 stepper driver to an ESP32 for 3D printer extruders?

You should not use this combination. While the ESP32's 3.3V GPIO pins can technically trigger the ULN2003 (the logic high threshold $V_{IH}$ is typically 2.4V), the 28BYJ-48 motor driven by the ULN2003 lacks the torque, speed, and thermal stability required to push filament through a 3D printer hotend. Furthermore, 3D printer firmware (like Klipper or Marlin) expects Step/Dir pulse interfaces, not the 4-pin sequential logic used by the ULN2003. For an ESP32-based 3D printer build, use TMC2209 drivers paired with high-torque bipolar NEMA 17 motors.

What is the actual gear ratio of the 28BYJ-48 motor used with the ULN2003?

While commonly listed as 1:64 in basic tutorials, the actual physical gear reduction of the 28BYJ-48 is 1:63.68395. This means it takes exactly 4075.77 steps to complete one full 360-degree rotation of the output shaft in half-step mode, rather than the 4096 steps a perfect 1:64 ratio would require. If your project involves rotating a dial or a wheel and you notice a cumulative positional drift over time, update your Arduino steps-per-revolution constant to 4076 to correct the math.