Stepper + ULN2003
A stepper motor does not spin when powered; it turns one precise notch each time the coils are energised in the right order. That is what makes it the motor for dials, turntables, camera sliders and anything that must move exactly 90°, not "about 90°". The shop's part is a 28BYJ-48 geared stepper on a ULN2003 driver board for $8: four inputs each sink one coil phase, and the board's built-in transistor array and flyback diodes carry the coil current a GPIO never could.
Pins
| Pin | What it is | Type |
|---|---|---|
| IN1 | Phase A (blue coil) | io |
| IN2 | Phase B (pink coil) | io |
| IN3 | Phase C (yellow coil) | io |
| IN4 | Phase D (orange coil) | io |
| + | Motor supply 5 V | power |
| - | Ground (join it to the Pi's ground) | ground |
Stepper()— Stepper + ULN2003 — $8- Pins: 6
+ is the 5 V feed for the coils' common connection, − the ground, and IN1–IN4 are the four phase inputs; pulling one high energises its coil. The colours on the motor's five-wire plug are blue, pink, yellow and orange for IN1–IN4 and red for +.
Wiring it in circuit.py
from wiring import *
pi = Pi()
stepper = Stepper()
stepper.plus >> pi.V5
stepper.minus >> pi.GND
for coil, gpio in zip((stepper.in1, stepper.in2, stepper.in3, stepper.in4), (pi.GPIO17, pi.GPIO18, pi.GPIO27, pi.GPIO22)):
coil >> gpioFour GPIOs, in any order you like — the order only decides which way counts as forward. The run is GPIO17, 18, 27, 22 everywhere in the docs, which matches the objectives.
Driving it in main.py
Write the half-step pattern and let it cook. One step every 2 ms keeps it inside its start rate:
from gpiozero import OutputDevice
from time import sleep
COILS = [OutputDevice(gpio) for gpio in (17, 18, 27, 22)]
SEQ = [(1, 0, 0, 0), (1, 1, 0, 0), (0, 1, 0, 0), (0, 1, 1, 0), (0, 0, 1, 0), (0, 0, 1, 1), (0, 0, 0, 1), (1, 0, 0, 1)]
while True:
for step in range(512): # 512 half-steps = 1/8 of an output turn
for coil, level in zip(COILS, SEQ[step % 8]):
coil.value = level
sleep(0.002)
sleep(1)RPi.GPIO works just as well (GPIO.output(pin, level)); OutputDevice is the gpiozero way and cleans up at exit. Each change of the pattern is one commanded step, so count your steps from a known start: 4076 half-steps is one output-shaft turn (64 half-steps per rotor turn through a 63.68:1 gearbox), so 90° is 1019 steps.
Electrical notes
- Coils are about 50 Ω, so each energised phase draws ~100 mA at 5 V — three or four at once is a few hundred mA, which is why the ULN2003 sits between the Pi and the motor.
- Supply range is 4.5–6 V. Below about 4 V the torque collapses and the rotor slips; the simulator warns.
- The inputs are 2.7 kΩ to ground and read high from 2.0 V, so 3.3 V GPIOs are fine.
- Timing: 64 half-steps per rotor turn, gear ratio 63.68395 → 4075.77 half-steps per output turn, not the 4096 most tutorials use. Start below 600 half-steps/s from rest, 1000/s once moving.
- Energised coils hold the shaft but draw their current the whole time; after a move, set all four inputs low to let the coils cool (the rotor stays put on its detent).
- Never drive a coil from a GPIO directly: 100 mA per phase would damage the pin, and the coil's kickback would finish the job.
Simulator vs real hardware
- Every change of the
IN1–IN4pattern is treated as one commanded half-step. If it is one or two positions away, the rotor follows it; an odd pattern (not in the sequence) leaves the rotor on its detent. - The speed limits are average-rate based: a burst of fast steps is lost rather than accumulated, exactly how a real stepper buzzes and stalls when pushed past its pull-in frequency. Lost steps raise a
missedwarning. - Below about 4 V of supply the rotor still steps but slips; the behaviour counts those as missed steps too.
- The coils are modelled as 50 Ω when energised and open when off, so the current and the ULN2003's heat are faithful; the canvas' four phase LEDs show the pattern live.
- A real 28BYJ-48's gearbox is not exactly 1:64 — hence the fractional 4075.77 steps; long moves drift a little differently on every unit.
Going deeper
- Sibling motion parts: servo (closed-loop angles) and DC motor + L298N (continuous speed and direction).
- The driver's inputs are just GPIOs: RPi.GPIO and gpiozero both drive them.
- Primer: voltage, current and Ohm's law for what the coils draw.
Further reading
- Kiatronics 28BYJ-48 stepper motor data sheet (Mouser) — coil resistance, step angle and the gearbox.
- TI: ULN2003A darlington array datasheet — the driver chip on the board.
- Adafruit: Raspberry Pi Lesson 10 — Stepper Motors — stepping a geared motor from a Pi.