A simple interface to GPIO devices with Raspberry Pi
npx @tessl/cli install tessl/pypi-gpiozero@2.0.0A comprehensive Python library that provides a simple, intuitive interface for controlling GPIO devices on Raspberry Pi computers. GPIO Zero offers high-level component classes for LEDs, buttons, motors, sensors, and other electronic components, with a declarative programming paradigm that allows developers to describe device behavior and interactions using clean, readable code.
pip install gpiozero (pre-installed on Raspberry Pi OS)import gpiozeroCommon device imports:
from gpiozero import LED, Button, Motor, Servo
from gpiozero import MotionSensor, DistanceSensor, LightSensor
from gpiozero import MCP3008, RGBLED, RobotPin factory and configuration:
from gpiozero import Device
from gpiozero.pins.pigpio import PiGPIOFactory
Device.pin_factory = PiGPIOFactory()from gpiozero import LED, Button
from signal import pause
# Simple LED control
led = LED(17)
led.on()
led.off()
led.blink()
# Button with event handling
button = Button(2)
button.when_pressed = led.on
button.when_released = led.off
# Keep the program running
pause()Advanced declarative programming with source chaining:
from gpiozero import OutputDevice, MotionSensor, LightSensor
from gpiozero.tools import booleanized, all_values
from signal import pause
garden_light = OutputDevice(17)
motion = MotionSensor(4)
light = LightSensor(5)
# Garden light turns on when motion detected AND it's dark
garden_light.source = all_values(booleanized(light, 0, 0.1), motion)
pause()Source chaining tools for complex device interactions:
from gpiozero.tools import negated, inverted, scaled, all_values, any_values
from gpiozero import LED, Button, MCP3008, Motor
led = LED(17)
button = Button(2)
# LED is on when button is NOT pressed
led.source = negated(button)
# Motor speed controlled by potentiometer (scaled -1 to 1)
motor = Motor(20, 21)
pot = MCP3008(0)
motor.source = scaled(pot, -1, 1)GPIO Zero follows a hierarchical device architecture:
The library uses mixins to provide cross-cutting functionality:
Core mixin classes that provide cross-cutting functionality to GPIO Zero devices. These mixins are automatically included in device classes as needed.
class ValuesMixin:
@property
def values(self):
"""An infinite iterator of values read from value property."""
class SourceMixin:
@property
def source(self):
"""The iterable to use as a source of values for value."""
@property
def source_delay(self) -> float:
"""The delay (in seconds) in the source reading loop."""
class EventsMixin:
def wait_for_active(self, timeout=None): ...
def wait_for_inactive(self, timeout=None): ...
when_activated: event
when_deactivated: event
@property
def active_time(self) -> float | None:
"""Length of time device has been active."""
@property
def inactive_time(self) -> float | None:
"""Length of time device has been inactive."""
class HoldMixin(EventsMixin):
when_held: event
@property
def hold_time(self) -> float:
"""Time to wait before executing when_held handler."""
@property
def hold_repeat(self) -> bool:
"""If True, when_held executes repeatedly."""
@property
def is_held(self) -> bool:
"""True if device has been active for at least hold_time."""
@property
def held_time(self) -> float | None:
"""Length of time device has been held."""
class SharedMixin:
@classmethod
def _shared_key(cls, *args, **kwargs):
"""Generate unique key for instance sharing."""
event = event(doc=None)
"""Descriptor for callable events on EventsMixin classes."""GPIO input devices including buttons, sensors, and analog input components. Supports event-driven programming, debouncing, smoothing, and hold detection.
class Button(DigitalInputDevice, HoldMixin):
def __init__(self, pin, *, pull_up=True, bounce_time=None, hold_time=1, hold_repeat=False, pin_factory=None): ...
class MotionSensor(DigitalInputDevice):
def __init__(self, pin, *, queue_len=1, sample_rate=10, threshold=0.5, partial=False, pin_factory=None): ...
class DistanceSensor(SmoothedInputDevice):
def __init__(self, echo=None, trigger=None, *, queue_len=30, max_distance=1, threshold_distance=0.04, partial=False, pin_factory=None): ...GPIO output devices including LEDs, motors, servos, and buzzers. Supports PWM control, color management, and precise positioning.
class LED(DigitalOutputDevice):
def __init__(self, pin, *, active_high=True, initial_value=False, pin_factory=None): ...
class PWMLED(PWMOutputDevice):
def __init__(self, pin, *, active_high=True, initial_value=0, frequency=1000, pin_factory=None): ...
class Motor(CompositeDevice):
def __init__(self, forward=None, backward=None, *, enable=None, pwm=True, pin_factory=None): ...
class Servo(PWMOutputDevice):
def __init__(self, pin, *, initial_value=0, min_pulse_width=1/1000, max_pulse_width=2/1000, frame_width=20/1000, pin_factory=None): ...SPI-connected analog-to-digital converters and related components. Supports multiple MCP3xxx ADC families with different resolutions and channel counts.
class MCP3008(AnalogInputDevice):
def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args): ...
class MCP3202(AnalogInputDevice):
def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args): ...Pre-built board configurations, LED collections, and robotic platforms. Includes support for commercial GPIO boards and multi-device assemblies.
class Robot(CompositeDevice, SourceMixin):
def __init__(self, left=None, right=None, *, pwm=True, pin_factory=None): ...
class LEDBoard(CompositeOutputDevice):
def __init__(self, **named_pins): ...
class TrafficLights(CompositeOutputDevice):
def __init__(self, red=None, amber=None, green=None, *, pwm=False, initial_value=False, pin_factory=None): ...Pin factory classes for different GPIO backends and board information system. Supports RPi.GPIO, pigpio, lgpio, and mock pin interfaces.
class Factory:
def __init__(self): ...
def pin(self, spec): ...
def spi(self, **spi_args): ...
class PiBoardInfo(BoardInfo):
def __init__(self, revision=None, **kwargs): ...
def pi_info(revision=None): ...Internal system monitoring devices for CPU temperature, disk usage, network connectivity, and system load monitoring.
class CPUTemperature(InternalDevice):
def __init__(self, *, sensor_file='/sys/class/thermal/thermal_zone0/temp', min_temp=0.0, max_temp=100.0, threshold=80.0, pin_factory=None): ...
class DiskUsage(InternalDevice):
def __init__(self, *, filesystem='/', threshold=0.8, pin_factory=None): ...Source chaining utility functions for complex device interactions and value transformations. These functions enable declarative programming patterns and advanced device coordination.
def negated(values):
"""Negate boolean values (True becomes False, False becomes True)."""
def inverted(values, input_min=0, input_max=1):
"""Invert numeric values within specified range."""
def scaled(values, output_min, output_max, input_min=0, input_max=1):
"""Scale values from input range to output range."""
def all_values(*sources):
"""Returns True only when all sources are True."""
def any_values(*sources):
"""Returns True when any source is True."""Musical tone representation and manipulation for audio devices. Supports frequency, MIDI note, and musical notation formats with comprehensive conversion capabilities.
class Tone(float):
def __init__(self, value=None, *, frequency=None, midi=None, note=None): ...
@classmethod
def from_frequency(cls, freq: float) -> 'Tone': ...
@classmethod
def from_midi(cls, midi_note: int) -> 'Tone': ...
@classmethod
def from_note(cls, note: str) -> 'Tone': ...
@property
def frequency(self) -> float: ...
@property
def midi(self) -> int: ...
@property
def note(self) -> str: ...
def up(self, n: int = 1) -> 'Tone': ...
def down(self, n: int = 1) -> 'Tone': ...GPIO Zero provides comprehensive exception handling with specific exception types for different error conditions:
# Base exceptions
class GPIOZeroError(Exception):
"""Base class for all exceptions in GPIO Zero."""
class DeviceClosed(GPIOZeroError):
"""Error raised when an operation is attempted on a closed device."""
# Event and timing exceptions
class BadEventHandler(GPIOZeroError, ValueError):
"""Error raised when an event handler with an incompatible prototype is specified."""
class BadWaitTime(GPIOZeroError, ValueError):
"""Error raised when an invalid wait time is specified."""
class BadQueueLen(GPIOZeroError, ValueError):
"""Error raised when non-positive queue length is specified."""
class ZombieThread(GPIOZeroError, RuntimeError):
"""Error raised when a thread fails to die within a given timeout."""
# Pin factory exceptions
class BadPinFactory(GPIOZeroError, ImportError):
"""Error raised when an unknown pin factory name is specified."""
# GPIO device exceptions
class GPIODeviceError(GPIOZeroError):
"""Base class for errors specific to the GPIODevice hierarchy."""
class GPIOPinInUse(GPIODeviceError):
"""Error raised when attempting to use a pin already in use by another device."""
class GPIOPinMissing(GPIODeviceError, ValueError):
"""Error raised when a pin specification is not given."""
class InputDeviceError(GPIODeviceError):
"""Base class for errors specific to the InputDevice hierarchy."""
class OutputDeviceError(GPIODeviceError):
"""Base class for errors specified to the OutputDevice hierarchy."""
class OutputDeviceBadValue(OutputDeviceError, ValueError):
"""Error raised when value is set to an invalid value."""
# Composite device exceptions
class CompositeDeviceError(GPIOZeroError):
"""Base class for errors specific to the CompositeDevice hierarchy."""
class CompositeDeviceBadName(CompositeDeviceError, ValueError):
"""Error raised when a composite device is constructed with a reserved name."""
class CompositeDeviceBadOrder(CompositeDeviceError, ValueError):
"""Error raised when a composite device is constructed with an incomplete order."""
class CompositeDeviceBadDevice(CompositeDeviceError, ValueError):
"""Error raised when a composite device is constructed with an object that doesn't inherit from Device."""
class EnergenieSocketMissing(CompositeDeviceError, ValueError):
"""Error raised when socket number is not specified."""
class EnergenieBadSocket(CompositeDeviceError, ValueError):
"""Error raised when an invalid socket number is passed to Energenie."""
# SPI exceptions
class SPIError(GPIOZeroError):
"""Base class for errors related to the SPI implementation."""
class SPIBadArgs(SPIError, ValueError):
"""Error raised when invalid arguments are given while constructing SPIDevice."""
class SPIBadChannel(SPIError, ValueError):
"""Error raised when an invalid channel is given to an AnalogInputDevice."""
class SPIFixedClockMode(SPIError, AttributeError):
"""Error raised when the SPI clock mode cannot be changed."""
class SPIInvalidClockMode(SPIError, ValueError):
"""Error raised when an invalid clock mode is given to an SPI implementation."""
class SPIFixedBitOrder(SPIError, AttributeError):
"""Error raised when the SPI bit-endianness cannot be changed."""
class SPIFixedSelect(SPIError, AttributeError):
"""Error raised when the SPI select polarity cannot be changed."""
class SPIFixedWordSize(SPIError, AttributeError):
"""Error raised when the number of bits per word cannot be changed."""
class SPIFixedRate(SPIError, AttributeError):
"""Error raised when the baud-rate of the interface cannot be changed."""
class SPIInvalidWordSize(SPIError, ValueError):
"""Error raised when an invalid (out of range) number of bits per word is specified."""
# Pin exceptions
class PinError(GPIOZeroError):
"""Base class for errors related to pin implementations."""
class PinInvalidFunction(PinError, ValueError):
"""Error raised when attempting to change the function of a pin to an invalid value."""
class PinInvalidState(PinError, ValueError):
"""Error raised when attempting to assign an invalid state to a pin."""
class PinInvalidPull(PinError, ValueError):
"""Error raised when attempting to assign an invalid pull-up to a pin."""
class PinInvalidEdges(PinError, ValueError):
"""Error raised when attempting to assign an invalid edge detection to a pin."""
class PinInvalidBounce(PinError, ValueError):
"""Error raised when attempting to assign an invalid bounce time to a pin."""
class PinSetInput(PinError, AttributeError):
"""Error raised when attempting to set a read-only pin."""
class PinFixedPull(PinError, AttributeError):
"""Error raised when attempting to set the pull of a pin with fixed pull-up."""
class PinEdgeDetectUnsupported(PinError, AttributeError):
"""Error raised when attempting to use edge detection on unsupported pins."""
class PinUnsupported(PinError, NotImplementedError):
"""Error raised when attempting to obtain a pin interface on unsupported pins."""
class PinSPIUnsupported(PinError, NotImplementedError):
"""Error raised when attempting to obtain an SPI interface on unsupported pins."""
class PinUnknownPi(PinError, RuntimeError):
"""Error raised when gpiozero doesn't recognize a revision of the Pi."""
class PinMultiplePins(PinError, RuntimeError):
"""Error raised when multiple pins support the requested function."""
class PinNoPins(PinError, RuntimeError):
"""Error raised when no pins support the requested function."""
class PinInvalidPin(PinError, ValueError):
"""Error raised when an invalid pin specification is provided."""
# PWM exceptions
class PinPWMError(PinError):
"""Base class for errors related to PWM implementations."""
class PinPWMUnsupported(PinPWMError, AttributeError):
"""Error raised when attempting to activate PWM on unsupported pins."""
class PinPWMFixedValue(PinPWMError, AttributeError):
"""Error raised when attempting to initialize PWM on an input pin."""
# Warning classes
class GPIOZeroWarning(Warning):
"""Base class for all warnings in GPIO Zero."""
class DistanceSensorNoEcho(GPIOZeroWarning):
"""Warning raised when the distance sensor sees no echo at all."""
class SPIWarning(GPIOZeroWarning):
"""Base class for warnings related to the SPI implementation."""
class SPISoftwareFallback(SPIWarning):
"""Warning raised when falling back to the SPI software implementation."""
class PWMWarning(GPIOZeroWarning):
"""Base class for PWM warnings."""
class PWMSoftwareFallback(PWMWarning):
"""Warning raised when falling back to the PWM software implementation."""
class PinWarning(GPIOZeroWarning):
"""Base class for warnings related to pin implementations."""
class PinFactoryFallback(PinWarning):
"""Warning raised when a default pin factory fails to load and a fallback is tried."""
class NativePinFactoryFallback(PinWarning):
"""Warning raised when all other default pin factories fail to load and NativeFactory is used."""
class PinNonPhysical(PinWarning):
"""Warning raised when a non-physical pin is specified in a constructor."""
class ThresholdOutOfRange(GPIOZeroWarning):
"""Warning raised when a threshold is out of range specified by min and max values."""
class CallbackSetToNone(GPIOZeroWarning):
"""Warning raised when a callback is set to None when its previous value was None."""
class AmbiguousTone(GPIOZeroWarning):
"""Warning raised when a Tone is constructed with an ambiguous number."""Common exceptions:
DeviceClosed: Raised when operating on closed devicesGPIOPinInUse: Pin already in use by another deviceBadEventHandler: Invalid event handler callbackOutputDeviceBadValue: Invalid value assigned to output devicePin-related exceptions:
PinError and subclasses: Invalid pin operations, configurations, or specificationsPinPWMError and subclasses: PWM-specific pin errorsPinUnsupported: Pin doesn't support requested functionalitySPI-related exceptions:
SPIError and subclasses: SPI communication and configuration issuesSPIBadChannel: Invalid ADC channel specificationComposite device exceptions:
CompositeDeviceError and subclasses: Multi-device configuration issuesbutton.when_pressed = callback_function
button.when_held = held_callback
motion_sensor.when_motion = alert_function# LED brightness follows light sensor (inverted)
led.source = MCP3008(0)
led.source_delay = 0.1
led.value = 1 - led.source.value
# Complex logic with multiple inputs
from gpiozero.tools import all_values, any_values
device.source = all_values(sensor1, sensor2, sensor3)with LED(17) as led:
led.blink()
sleep(10)
# LED automatically closedThis API provides both low-level device control and high-level abstractions suitable for education, prototyping, and production use on Raspberry Pi computers.