Raspberry Pi DC Motor

Driving a DC motor from a Raspberry Pi requires a separate motor driver such as an H-bridge, since GPIO pins cannot supply anywhere near the current a motor needs, and gpiozero's Motor class is built around exactly that arrangement.

Why a Motor Cannot Wire Straight to a GPIO Pin

GPIO pins are designed to carry small logic-level signals, not to power anything. A single pin can safely source only a few tens of milliamps, and the Pi's datasheet limits the total current drawn across all GPIO pins combined to well under an amp. Even a small hobby DC motor can draw several hundred milliamps in normal use and a burst of several amps the instant it starts spinning or if its shaft is blocked - enough to instantly damage the Pi. On top of the current problem, a GPIO pin only ever provides one polarity, so it could never reverse a motor's direction on its own.

The Job of an H-Bridge Driver

A motor driver sits between the Pi and the motor and solves both problems at once. An H-bridge - the arrangement inside common driver chips like the L298N, DRV8833 or TB6612FNG - is essentially four switches arranged so that current can be sent through the motor in either direction depending on which pair of switches is closed. Crucially, those switches are controlled by small logic-level signals from the Pi's GPIO pins, while the actual current that spins the motor comes from a separate, independently supplied motor power input on the driver board - so the Pi never touches the motor's real current at all.

  • A GPIO 'forward' pin to the driver's first direction input (e.g. IN1).
  • A GPIO 'backward' pin to the driver's second direction input (e.g. IN2).
  • The driver's motor outputs (e.g. OUT1/OUT2) to the motor's two terminals.
  • The driver's motor power input to an external supply sized for the motor - a battery pack, not the Pi.
  • The driver's ground shared in common with the Pi's ground, even though their power supplies are separate.
  • Optionally, a GPIO 'enable' pin to the driver's PWM enable input (e.g. ENA) for adjustable speed rather than simple full-speed on/off.

Example

from gpiozero import Motor
from time import sleep

# forward/backward connect to the driver board's input pins, never straight to the motor
motor = Motor(forward=4, backward=14)

motor.forward()
sleep(2)
motor.backward()
sleep(2)
motor.stop()

Example

from gpiozero import Motor
from time import sleep

# 'enable' is the driver's PWM speed pin (e.g. L298N's ENA), separate from direction pins
motor = Motor(forward=4, backward=14, enable=17)

motor.forward(0.3)  # gentle speed, 30%
sleep(2)
motor.forward(1.0)  # full speed
sleep(2)
motor.stop()
Note: The Pi and the motor's external power supply must share a common ground connection even though they are powered separately. Without it, the driver has no shared voltage reference for the Pi's logic signals, and the motor typically behaves erratically or does not respond at all.
Motor typeHow motion is controlledTypical driver needed
DC motorContinuous spin; speed via PWM, direction via polarityH-bridge driver, e.g. L298N or DRV8833
Hobby servoAbsolute angle via pulse widthNone - the driver circuit is already built into the servo
Stepper motorDiscrete fixed-size steps via a sequenced pulse patternDedicated stepper driver, e.g. ULN2003 or A4988
Note: gpiozero's Motor accepts an optional third enable pin specifically for driver boards like the L298N that expose a separate PWM-capable enable line - forward and backward stay purely digital direction pins in that case, and the speed you pass to .forward(speed) or .backward(speed) is applied to the enable pin instead.
Note: For a two-motor rig such as a simple wheeled robot, gpiozero's Robot class combines two Motor-style pin pairs into one object whose .value takes a (left_speed, right_speed) tuple, so driving straight, turning and reversing become single assignments rather than four separate Motor calls.