0
# GPIO Zero
1
2
A 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.
3
4
## Package Information
5
6
- **Package Name**: gpiozero
7
- **Language**: Python
8
- **Installation**: `pip install gpiozero` (pre-installed on Raspberry Pi OS)
9
10
## Core Imports
11
12
```python
13
import gpiozero
14
```
15
16
Common device imports:
17
18
```python
19
from gpiozero import LED, Button, Motor, Servo
20
from gpiozero import MotionSensor, DistanceSensor, LightSensor
21
from gpiozero import MCP3008, RGBLED, Robot
22
```
23
24
Pin factory and configuration:
25
26
```python
27
from gpiozero import Device
28
from gpiozero.pins.pigpio import PiGPIOFactory
29
Device.pin_factory = PiGPIOFactory()
30
```
31
32
## Basic Usage
33
34
```python
35
from gpiozero import LED, Button
36
from signal import pause
37
38
# Simple LED control
39
led = LED(17)
40
led.on()
41
led.off()
42
led.blink()
43
44
# Button with event handling
45
button = Button(2)
46
button.when_pressed = led.on
47
button.when_released = led.off
48
49
# Keep the program running
50
pause()
51
```
52
53
Advanced declarative programming with source chaining:
54
55
```python
56
from gpiozero import OutputDevice, MotionSensor, LightSensor
57
from gpiozero.tools import booleanized, all_values
58
from signal import pause
59
60
garden_light = OutputDevice(17)
61
motion = MotionSensor(4)
62
light = LightSensor(5)
63
64
# Garden light turns on when motion detected AND it's dark
65
garden_light.source = all_values(booleanized(light, 0, 0.1), motion)
66
67
pause()
68
```
69
70
Source chaining tools for complex device interactions:
71
72
```python
73
from gpiozero.tools import negated, inverted, scaled, all_values, any_values
74
from gpiozero import LED, Button, MCP3008, Motor
75
76
led = LED(17)
77
button = Button(2)
78
79
# LED is on when button is NOT pressed
80
led.source = negated(button)
81
82
# Motor speed controlled by potentiometer (scaled -1 to 1)
83
motor = Motor(20, 21)
84
pot = MCP3008(0)
85
motor.source = scaled(pot, -1, 1)
86
```
87
88
## Architecture
89
90
GPIO Zero follows a hierarchical device architecture:
91
92
- **Device**: Base class for all devices with common functionality (close, context management)
93
- **GPIODevice**: Base for GPIO-connected devices with pin management and state properties
94
- **InputDevice/OutputDevice**: Specialized bases for input and output GPIO devices
95
- **CompositeDevice**: Base for devices composed of multiple sub-devices
96
- **Pin Factory System**: Abstracted pin interface supporting multiple backends (RPi.GPIO, pigpio, lgpio)
97
98
The library uses mixins to provide cross-cutting functionality:
99
- **EventsMixin**: Event-driven programming with callback support and timing
100
- **SourceMixin**: Source/values chaining for complex device interactions
101
- **ValuesMixin**: Infinite value iteration from device readings
102
- **HoldMixin**: Hold detection for timing-sensitive operations
103
- **SharedMixin**: Device sharing across multiple instances with reference counting
104
105
### Core Mixins
106
107
Core mixin classes that provide cross-cutting functionality to GPIO Zero devices. These mixins are automatically included in device classes as needed.
108
109
```python { .api }
110
class ValuesMixin:
111
@property
112
def values(self):
113
"""An infinite iterator of values read from value property."""
114
115
class SourceMixin:
116
@property
117
def source(self):
118
"""The iterable to use as a source of values for value."""
119
120
@property
121
def source_delay(self) -> float:
122
"""The delay (in seconds) in the source reading loop."""
123
124
class EventsMixin:
125
def wait_for_active(self, timeout=None): ...
126
def wait_for_inactive(self, timeout=None): ...
127
128
when_activated: event
129
when_deactivated: event
130
131
@property
132
def active_time(self) -> float | None:
133
"""Length of time device has been active."""
134
135
@property
136
def inactive_time(self) -> float | None:
137
"""Length of time device has been inactive."""
138
139
class HoldMixin(EventsMixin):
140
when_held: event
141
142
@property
143
def hold_time(self) -> float:
144
"""Time to wait before executing when_held handler."""
145
146
@property
147
def hold_repeat(self) -> bool:
148
"""If True, when_held executes repeatedly."""
149
150
@property
151
def is_held(self) -> bool:
152
"""True if device has been active for at least hold_time."""
153
154
@property
155
def held_time(self) -> float | None:
156
"""Length of time device has been held."""
157
158
class SharedMixin:
159
@classmethod
160
def _shared_key(cls, *args, **kwargs):
161
"""Generate unique key for instance sharing."""
162
163
event = event(doc=None)
164
"""Descriptor for callable events on EventsMixin classes."""
165
```
166
167
## Capabilities
168
169
### Input Devices
170
171
GPIO input devices including buttons, sensors, and analog input components. Supports event-driven programming, debouncing, smoothing, and hold detection.
172
173
```python { .api }
174
class Button(DigitalInputDevice, HoldMixin):
175
def __init__(self, pin, *, pull_up=True, bounce_time=None, hold_time=1, hold_repeat=False, pin_factory=None): ...
176
177
class MotionSensor(DigitalInputDevice):
178
def __init__(self, pin, *, queue_len=1, sample_rate=10, threshold=0.5, partial=False, pin_factory=None): ...
179
180
class DistanceSensor(SmoothedInputDevice):
181
def __init__(self, echo=None, trigger=None, *, queue_len=30, max_distance=1, threshold_distance=0.04, partial=False, pin_factory=None): ...
182
```
183
184
[Input Devices](./input-devices.md)
185
186
### Output Devices
187
188
GPIO output devices including LEDs, motors, servos, and buzzers. Supports PWM control, color management, and precise positioning.
189
190
```python { .api }
191
class LED(DigitalOutputDevice):
192
def __init__(self, pin, *, active_high=True, initial_value=False, pin_factory=None): ...
193
194
class PWMLED(PWMOutputDevice):
195
def __init__(self, pin, *, active_high=True, initial_value=0, frequency=1000, pin_factory=None): ...
196
197
class Motor(CompositeDevice):
198
def __init__(self, forward=None, backward=None, *, enable=None, pwm=True, pin_factory=None): ...
199
200
class Servo(PWMOutputDevice):
201
def __init__(self, pin, *, initial_value=0, min_pulse_width=1/1000, max_pulse_width=2/1000, frame_width=20/1000, pin_factory=None): ...
202
```
203
204
[Output Devices](./output-devices.md)
205
206
### SPI Devices
207
208
SPI-connected analog-to-digital converters and related components. Supports multiple MCP3xxx ADC families with different resolutions and channel counts.
209
210
```python { .api }
211
class MCP3008(AnalogInputDevice):
212
def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args): ...
213
214
class MCP3202(AnalogInputDevice):
215
def __init__(self, channel=0, *, differential=False, max_voltage=3.3, **spi_args): ...
216
```
217
218
[SPI Devices](./spi-devices.md)
219
220
### Composite Devices
221
222
Pre-built board configurations, LED collections, and robotic platforms. Includes support for commercial GPIO boards and multi-device assemblies.
223
224
```python { .api }
225
class Robot(CompositeDevice, SourceMixin):
226
def __init__(self, left=None, right=None, *, pwm=True, pin_factory=None): ...
227
228
class LEDBoard(CompositeOutputDevice):
229
def __init__(self, **named_pins): ...
230
231
class TrafficLights(CompositeOutputDevice):
232
def __init__(self, red=None, amber=None, green=None, *, pwm=False, initial_value=False, pin_factory=None): ...
233
```
234
235
[Composite Devices](./composite-devices.md)
236
237
### Pin Factory System
238
239
Pin factory classes for different GPIO backends and board information system. Supports RPi.GPIO, pigpio, lgpio, and mock pin interfaces.
240
241
```python { .api }
242
class Factory:
243
def __init__(self): ...
244
def pin(self, spec): ...
245
def spi(self, **spi_args): ...
246
247
class PiBoardInfo(BoardInfo):
248
def __init__(self, revision=None, **kwargs): ...
249
250
def pi_info(revision=None): ...
251
```
252
253
[Pin Factories](./pin-factories.md)
254
255
### System Monitoring
256
257
Internal system monitoring devices for CPU temperature, disk usage, network connectivity, and system load monitoring.
258
259
```python { .api }
260
class CPUTemperature(InternalDevice):
261
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): ...
262
263
class DiskUsage(InternalDevice):
264
def __init__(self, *, filesystem='/', threshold=0.8, pin_factory=None): ...
265
```
266
267
[System Monitoring](./system-monitoring.md)
268
269
### Utility Tools
270
271
Source chaining utility functions for complex device interactions and value transformations. These functions enable declarative programming patterns and advanced device coordination.
272
273
```python { .api }
274
def negated(values):
275
"""Negate boolean values (True becomes False, False becomes True)."""
276
277
def inverted(values, input_min=0, input_max=1):
278
"""Invert numeric values within specified range."""
279
280
def scaled(values, output_min, output_max, input_min=0, input_max=1):
281
"""Scale values from input range to output range."""
282
283
def all_values(*sources):
284
"""Returns True only when all sources are True."""
285
286
def any_values(*sources):
287
"""Returns True when any source is True."""
288
```
289
290
[Utility Tools](./tools.md)
291
292
### Tone System
293
294
Musical tone representation and manipulation for audio devices. Supports frequency, MIDI note, and musical notation formats with comprehensive conversion capabilities.
295
296
```python { .api }
297
class Tone(float):
298
def __init__(self, value=None, *, frequency=None, midi=None, note=None): ...
299
300
@classmethod
301
def from_frequency(cls, freq: float) -> 'Tone': ...
302
303
@classmethod
304
def from_midi(cls, midi_note: int) -> 'Tone': ...
305
306
@classmethod
307
def from_note(cls, note: str) -> 'Tone': ...
308
309
@property
310
def frequency(self) -> float: ...
311
312
@property
313
def midi(self) -> int: ...
314
315
@property
316
def note(self) -> str: ...
317
318
def up(self, n: int = 1) -> 'Tone': ...
319
320
def down(self, n: int = 1) -> 'Tone': ...
321
```
322
323
[Tone System](./tone-system.md)
324
325
## Exception Handling
326
327
GPIO Zero provides comprehensive exception handling with specific exception types for different error conditions:
328
329
```python { .api }
330
# Base exceptions
331
class GPIOZeroError(Exception):
332
"""Base class for all exceptions in GPIO Zero."""
333
334
class DeviceClosed(GPIOZeroError):
335
"""Error raised when an operation is attempted on a closed device."""
336
337
# Event and timing exceptions
338
class BadEventHandler(GPIOZeroError, ValueError):
339
"""Error raised when an event handler with an incompatible prototype is specified."""
340
341
class BadWaitTime(GPIOZeroError, ValueError):
342
"""Error raised when an invalid wait time is specified."""
343
344
class BadQueueLen(GPIOZeroError, ValueError):
345
"""Error raised when non-positive queue length is specified."""
346
347
class ZombieThread(GPIOZeroError, RuntimeError):
348
"""Error raised when a thread fails to die within a given timeout."""
349
350
# Pin factory exceptions
351
class BadPinFactory(GPIOZeroError, ImportError):
352
"""Error raised when an unknown pin factory name is specified."""
353
354
# GPIO device exceptions
355
class GPIODeviceError(GPIOZeroError):
356
"""Base class for errors specific to the GPIODevice hierarchy."""
357
358
class GPIOPinInUse(GPIODeviceError):
359
"""Error raised when attempting to use a pin already in use by another device."""
360
361
class GPIOPinMissing(GPIODeviceError, ValueError):
362
"""Error raised when a pin specification is not given."""
363
364
class InputDeviceError(GPIODeviceError):
365
"""Base class for errors specific to the InputDevice hierarchy."""
366
367
class OutputDeviceError(GPIODeviceError):
368
"""Base class for errors specified to the OutputDevice hierarchy."""
369
370
class OutputDeviceBadValue(OutputDeviceError, ValueError):
371
"""Error raised when value is set to an invalid value."""
372
373
# Composite device exceptions
374
class CompositeDeviceError(GPIOZeroError):
375
"""Base class for errors specific to the CompositeDevice hierarchy."""
376
377
class CompositeDeviceBadName(CompositeDeviceError, ValueError):
378
"""Error raised when a composite device is constructed with a reserved name."""
379
380
class CompositeDeviceBadOrder(CompositeDeviceError, ValueError):
381
"""Error raised when a composite device is constructed with an incomplete order."""
382
383
class CompositeDeviceBadDevice(CompositeDeviceError, ValueError):
384
"""Error raised when a composite device is constructed with an object that doesn't inherit from Device."""
385
386
class EnergenieSocketMissing(CompositeDeviceError, ValueError):
387
"""Error raised when socket number is not specified."""
388
389
class EnergenieBadSocket(CompositeDeviceError, ValueError):
390
"""Error raised when an invalid socket number is passed to Energenie."""
391
392
# SPI exceptions
393
class SPIError(GPIOZeroError):
394
"""Base class for errors related to the SPI implementation."""
395
396
class SPIBadArgs(SPIError, ValueError):
397
"""Error raised when invalid arguments are given while constructing SPIDevice."""
398
399
class SPIBadChannel(SPIError, ValueError):
400
"""Error raised when an invalid channel is given to an AnalogInputDevice."""
401
402
class SPIFixedClockMode(SPIError, AttributeError):
403
"""Error raised when the SPI clock mode cannot be changed."""
404
405
class SPIInvalidClockMode(SPIError, ValueError):
406
"""Error raised when an invalid clock mode is given to an SPI implementation."""
407
408
class SPIFixedBitOrder(SPIError, AttributeError):
409
"""Error raised when the SPI bit-endianness cannot be changed."""
410
411
class SPIFixedSelect(SPIError, AttributeError):
412
"""Error raised when the SPI select polarity cannot be changed."""
413
414
class SPIFixedWordSize(SPIError, AttributeError):
415
"""Error raised when the number of bits per word cannot be changed."""
416
417
class SPIFixedRate(SPIError, AttributeError):
418
"""Error raised when the baud-rate of the interface cannot be changed."""
419
420
class SPIInvalidWordSize(SPIError, ValueError):
421
"""Error raised when an invalid (out of range) number of bits per word is specified."""
422
423
# Pin exceptions
424
class PinError(GPIOZeroError):
425
"""Base class for errors related to pin implementations."""
426
427
class PinInvalidFunction(PinError, ValueError):
428
"""Error raised when attempting to change the function of a pin to an invalid value."""
429
430
class PinInvalidState(PinError, ValueError):
431
"""Error raised when attempting to assign an invalid state to a pin."""
432
433
class PinInvalidPull(PinError, ValueError):
434
"""Error raised when attempting to assign an invalid pull-up to a pin."""
435
436
class PinInvalidEdges(PinError, ValueError):
437
"""Error raised when attempting to assign an invalid edge detection to a pin."""
438
439
class PinInvalidBounce(PinError, ValueError):
440
"""Error raised when attempting to assign an invalid bounce time to a pin."""
441
442
class PinSetInput(PinError, AttributeError):
443
"""Error raised when attempting to set a read-only pin."""
444
445
class PinFixedPull(PinError, AttributeError):
446
"""Error raised when attempting to set the pull of a pin with fixed pull-up."""
447
448
class PinEdgeDetectUnsupported(PinError, AttributeError):
449
"""Error raised when attempting to use edge detection on unsupported pins."""
450
451
class PinUnsupported(PinError, NotImplementedError):
452
"""Error raised when attempting to obtain a pin interface on unsupported pins."""
453
454
class PinSPIUnsupported(PinError, NotImplementedError):
455
"""Error raised when attempting to obtain an SPI interface on unsupported pins."""
456
457
class PinUnknownPi(PinError, RuntimeError):
458
"""Error raised when gpiozero doesn't recognize a revision of the Pi."""
459
460
class PinMultiplePins(PinError, RuntimeError):
461
"""Error raised when multiple pins support the requested function."""
462
463
class PinNoPins(PinError, RuntimeError):
464
"""Error raised when no pins support the requested function."""
465
466
class PinInvalidPin(PinError, ValueError):
467
"""Error raised when an invalid pin specification is provided."""
468
469
# PWM exceptions
470
class PinPWMError(PinError):
471
"""Base class for errors related to PWM implementations."""
472
473
class PinPWMUnsupported(PinPWMError, AttributeError):
474
"""Error raised when attempting to activate PWM on unsupported pins."""
475
476
class PinPWMFixedValue(PinPWMError, AttributeError):
477
"""Error raised when attempting to initialize PWM on an input pin."""
478
479
# Warning classes
480
class GPIOZeroWarning(Warning):
481
"""Base class for all warnings in GPIO Zero."""
482
483
class DistanceSensorNoEcho(GPIOZeroWarning):
484
"""Warning raised when the distance sensor sees no echo at all."""
485
486
class SPIWarning(GPIOZeroWarning):
487
"""Base class for warnings related to the SPI implementation."""
488
489
class SPISoftwareFallback(SPIWarning):
490
"""Warning raised when falling back to the SPI software implementation."""
491
492
class PWMWarning(GPIOZeroWarning):
493
"""Base class for PWM warnings."""
494
495
class PWMSoftwareFallback(PWMWarning):
496
"""Warning raised when falling back to the PWM software implementation."""
497
498
class PinWarning(GPIOZeroWarning):
499
"""Base class for warnings related to pin implementations."""
500
501
class PinFactoryFallback(PinWarning):
502
"""Warning raised when a default pin factory fails to load and a fallback is tried."""
503
504
class NativePinFactoryFallback(PinWarning):
505
"""Warning raised when all other default pin factories fail to load and NativeFactory is used."""
506
507
class PinNonPhysical(PinWarning):
508
"""Warning raised when a non-physical pin is specified in a constructor."""
509
510
class ThresholdOutOfRange(GPIOZeroWarning):
511
"""Warning raised when a threshold is out of range specified by min and max values."""
512
513
class CallbackSetToNone(GPIOZeroWarning):
514
"""Warning raised when a callback is set to None when its previous value was None."""
515
516
class AmbiguousTone(GPIOZeroWarning):
517
"""Warning raised when a Tone is constructed with an ambiguous number."""
518
```
519
520
### Exception Hierarchy
521
522
**Common exceptions:**
523
- `DeviceClosed`: Raised when operating on closed devices
524
- `GPIOPinInUse`: Pin already in use by another device
525
- `BadEventHandler`: Invalid event handler callback
526
- `OutputDeviceBadValue`: Invalid value assigned to output device
527
528
**Pin-related exceptions:**
529
- `PinError` and subclasses: Invalid pin operations, configurations, or specifications
530
- `PinPWMError` and subclasses: PWM-specific pin errors
531
- `PinUnsupported`: Pin doesn't support requested functionality
532
533
**SPI-related exceptions:**
534
- `SPIError` and subclasses: SPI communication and configuration issues
535
- `SPIBadChannel`: Invalid ADC channel specification
536
537
**Composite device exceptions:**
538
- `CompositeDeviceError` and subclasses: Multi-device configuration issues
539
540
## Common Patterns
541
542
### Event-Driven Programming
543
544
```python
545
button.when_pressed = callback_function
546
button.when_held = held_callback
547
motion_sensor.when_motion = alert_function
548
```
549
550
### Source/Values Chaining
551
552
```python
553
# LED brightness follows light sensor (inverted)
554
led.source = MCP3008(0)
555
led.source_delay = 0.1
556
led.value = 1 - led.source.value
557
558
# Complex logic with multiple inputs
559
from gpiozero.tools import all_values, any_values
560
device.source = all_values(sensor1, sensor2, sensor3)
561
```
562
563
### Context Management
564
565
```python
566
with LED(17) as led:
567
led.blink()
568
sleep(10)
569
# LED automatically closed
570
```
571
572
This API provides both low-level device control and high-level abstractions suitable for education, prototyping, and production use on Raspberry Pi computers.