A simple interface to GPIO devices with Raspberry Pi
—
GPIO output devices for LEDs, motors, servos, buzzers, and other output components. All output devices support source chaining and can be controlled manually or automatically through event-driven programming.
Base class for all GPIO output devices.
class OutputDevice(SourceMixin, GPIODevice):
def __init__(self, pin=None, *, active_high=True, initial_value=False, pin_factory=None):
"""
Generic GPIO output device.
Parameters:
- pin: int or str - GPIO pin number or name
- active_high: bool - True if on() sets pin HIGH, False if on() sets pin LOW
- initial_value: bool or None - Initial state (False=off, True=on, None=current)
- pin_factory: Factory or None - Pin factory for advanced usage
"""
def on(self):
"""Turn the device on."""
def off(self):
"""Turn the device off."""
def toggle(self):
"""Reverse the current state of the device."""
@property
def value(self) -> float:
"""Current device value (0.0 for off, 1.0 for on)."""
@value.setter
def value(self, value: float): ...
@property
def active_high(self) -> bool:
"""True if on() sets pin HIGH, False if on() sets pin LOW."""
@active_high.setter
def active_high(self, value: bool): ...
@property
def is_active(self) -> bool:
"""Returns True if device is currently active (on)."""Base class for simple on/off output devices.
class DigitalOutputDevice(OutputDevice):
def __init__(self, pin=None, *, active_high=True, initial_value=False, pin_factory=None):
"""
Digital output device with simple on/off control.
Parameters:
- pin: int or str - GPIO pin number or name
- active_high: bool - True if on() sets pin HIGH, False if on() sets pin LOW
- initial_value: bool or None - Initial state
- pin_factory: Factory or None - Pin factory for advanced usage
"""
def blink(self, on_time: float = 1, off_time: float = 1, n: int = None, background: bool = True):
"""
Blink the device on and off repeatedly.
Parameters:
- on_time: float - Time in seconds to stay on
- off_time: float - Time in seconds to stay off
- n: int or None - Number of blinks (None for infinite)
- background: bool - If True, blink in background thread
"""Base class for devices that support PWM (pulse-width modulation).
class PWMOutputDevice(OutputDevice):
def __init__(self, pin=None, *, active_high=True, initial_value=0, frequency=1000, pin_factory=None):
"""
PWM output device with variable intensity control.
Parameters:
- pin: int or str - GPIO pin number or name
- active_high: bool - True if higher values mean more active
- initial_value: float - Initial PWM value (0.0-1.0)
- frequency: float - PWM frequency in Hz
- pin_factory: Factory or None - Pin factory for advanced usage
"""
def pulse(self, fade_in_time: float = 1, fade_out_time: float = 1, n: int = None, background: bool = True):
"""
Pulse the device by fading in and out repeatedly.
Parameters:
- fade_in_time: float - Time in seconds to fade in
- fade_out_time: float - Time in seconds to fade out
- n: int or None - Number of pulses (None for infinite)
- background: bool - If True, pulse in background thread
"""
@property
def frequency(self) -> float:
"""PWM frequency in Hz."""
@frequency.setter
def frequency(self, value: float): ...
@property
def is_active(self) -> bool:
"""Returns True if PWM value > 0."""Simple on/off LED control.
class LED(DigitalOutputDevice):
def __init__(self, pin=None, *, active_high=True, initial_value=False, pin_factory=None):
"""
Light Emitting Diode.
Parameters:
- pin: int or str - GPIO pin number or name
- active_high: bool - True if LED is on when pin is HIGH
- initial_value: bool - Initial state (False=off, True=on)
- pin_factory: Factory or None - Pin factory for advanced usage
"""LED with brightness control via PWM.
class PWMLED(PWMOutputDevice):
def __init__(self, pin=None, *, active_high=True, initial_value=0, frequency=1000, pin_factory=None):
"""
PWM-controlled LED with brightness control.
Parameters:
- pin: int or str - GPIO pin number or name
- active_high: bool - True if brighter values mean higher voltage
- initial_value: float - Initial brightness (0.0-1.0)
- frequency: float - PWM frequency in Hz
- pin_factory: Factory or None - Pin factory for advanced usage
"""
@property
def brightness(self) -> float:
"""Current brightness level (0.0-1.0)."""
@brightness.setter
def brightness(self, value: float): ...RGB LED with individual red, green, and blue control.
class RGBLED(SourceMixin, CompositeDevice):
def __init__(self, red=None, green=None, blue=None, *, active_high=True, initial_value=(0, 0, 0), pwm=True, pin_factory=None):
"""
RGB LED with color control.
Parameters:
- red: int or str - Red component pin number or name
- green: int or str - Green component pin number or name
- blue: int or str - Blue component pin number or name
- active_high: bool - True if higher values mean brighter colors
- initial_value: tuple - Initial (red, green, blue) values (0.0-1.0 each)
- pwm: bool - True for PWM control, False for digital on/off
- pin_factory: Factory or None - Pin factory for advanced usage
"""
@property
def color(self) -> tuple:
"""Current color as (red, green, blue) tuple (0.0-1.0 each)."""
@color.setter
def color(self, value: tuple): ...
@property
def red(self) -> float:
"""Red component intensity (0.0-1.0)."""
@red.setter
def red(self, value: float): ...
@property
def green(self) -> float:
"""Green component intensity (0.0-1.0)."""
@green.setter
def green(self, value: float): ...
@property
def blue(self) -> float:
"""Blue component intensity (0.0-1.0)."""
@blue.setter
def blue(self, value: float): ...
def on(self):
"""Turn on all color components."""
def off(self):
"""Turn off all color components."""
def toggle(self):
"""Toggle all color components."""
def pulse(self, fade_in_time: float = 1, fade_out_time: float = 1, n: int = None, background: bool = True):
"""Pulse all color components."""
def blink(self, on_time: float = 1, off_time: float = 1, fade_in_time: float = 0, fade_out_time: float = 0, n: int = None, background: bool = True):
"""Blink all color components with optional fading."""DC motor with forward and reverse control.
class Motor(SourceMixin, CompositeDevice):
def __init__(self, forward=None, backward=None, *, enable=None, pwm=True, pin_factory=None):
"""
DC motor with directional control.
Parameters:
- forward: int or str - Forward control pin number or name
- backward: int or str - Backward control pin number or name
- enable: int or str or None - Enable pin number or name (for 3-pin control)
- pwm: bool - True for PWM speed control, False for on/off only
- pin_factory: Factory or None - Pin factory for advanced usage
"""
def forward(self, speed: float = 1):
"""Move motor forward at specified speed (0.0-1.0)."""
def backward(self, speed: float = 1):
"""Move motor backward at specified speed (0.0-1.0)."""
def reverse(self):
"""Reverse current motor direction."""
def stop(self):
"""Stop the motor."""
@property
def value(self) -> float:
"""Current motor speed (-1.0 to 1.0, negative for backward)."""
@value.setter
def value(self, speed: float): ...
@property
def is_active(self) -> bool:
"""Returns True if motor is currently running."""Motor with phase/enable control (single direction pin + enable).
class PhaseEnableMotor(SourceMixin, CompositeDevice):
def __init__(self, phase=None, enable=None, *, pwm=True, pin_factory=None):
"""
Phase/enable motor controller.
Parameters:
- phase: int or str - Phase (direction) pin number or name
- enable: int or str - Enable (speed) pin number or name
- pwm: bool - True for PWM speed control on enable pin
- pin_factory: Factory or None - Pin factory for advanced usage
"""
def forward(self, speed: float = 1):
"""Move motor forward at specified speed."""
def backward(self, speed: float = 1):
"""Move motor backward at specified speed."""
def reverse(self):
"""Reverse current motor direction."""
def stop(self):
"""Stop the motor."""
@property
def value(self) -> float:
"""Current motor speed (-1.0 to 1.0)."""
@value.setter
def value(self, speed: float): ...Standard servo motor with position control.
class Servo(PWMOutputDevice):
def __init__(self, pin=None, *, initial_value=0, min_pulse_width=1/1000, max_pulse_width=2/1000, frame_width=20/1000, pin_factory=None):
"""
Servo motor with position control.
Parameters:
- pin: int or str - GPIO pin number or name (PWM capable)
- initial_value: float - Initial position (-1.0 to 1.0)
- min_pulse_width: float - Minimum pulse width in seconds
- max_pulse_width: float - Maximum pulse width in seconds
- frame_width: float - Pulse frame width in seconds
- pin_factory: Factory or None - Pin factory for advanced usage
"""
def min(self):
"""Move servo to minimum position."""
def mid(self):
"""Move servo to middle position."""
def max(self):
"""Move servo to maximum position."""
@property
def min_pulse_width(self) -> float:
"""Minimum pulse width in seconds."""
@property
def max_pulse_width(self) -> float:
"""Maximum pulse width in seconds."""
@property
def frame_width(self) -> float:
"""Pulse frame width in seconds."""
@property
def pulse_width(self) -> float:
"""Current pulse width in seconds."""
@pulse_width.setter
def pulse_width(self, value: float): ...Servo with angular position measurement.
class AngularServo(Servo):
def __init__(self, pin=None, *, initial_angle=0, min_angle=-90, max_angle=90, min_pulse_width=1/1000, max_pulse_width=2/1000, frame_width=20/1000, pin_factory=None):
"""
Servo with angular position control.
Parameters:
- pin: int or str - GPIO pin number or name
- initial_angle: float - Initial angle in degrees
- min_angle: float - Minimum angle in degrees
- max_angle: float - Maximum angle in degrees
- min_pulse_width: float - Minimum pulse width in seconds
- max_pulse_width: float - Maximum pulse width in seconds
- frame_width: float - Pulse frame width in seconds
- pin_factory: Factory or None - Pin factory for advanced usage
"""
@property
def angle(self) -> float:
"""Current angle in degrees."""
@angle.setter
def angle(self, value: float): ...
@property
def min_angle(self) -> float:
"""Minimum angle in degrees."""
@property
def max_angle(self) -> float:
"""Maximum angle in degrees."""Simple on/off buzzer.
class Buzzer(DigitalOutputDevice):
def __init__(self, pin=None, *, active_high=True, initial_value=False, pin_factory=None):
"""
Simple buzzer or beeper.
Parameters:
- pin: int or str - GPIO pin number or name
- active_high: bool - True if buzzer sounds when pin is HIGH
- initial_value: bool - Initial state
- pin_factory: Factory or None - Pin factory for advanced usage
"""
def beep(self, on_time: float = 1, off_time: float = 1, n: int = None, background: bool = True):
"""
Beep the buzzer on and off repeatedly.
Parameters:
- on_time: float - Time in seconds to stay on
- off_time: float - Time in seconds to stay off
- n: int or None - Number of beeps (None for infinite)
- background: bool - If True, beep in background thread
"""Buzzer with tone generation capabilities.
class TonalBuzzer(PWMOutputDevice):
def __init__(self, pin=None, *, initial_value=None, mid_tone=Tone(440.0), octaves=1, pin_factory=None):
"""
Buzzer with tone generation.
Parameters:
- pin: int or str - GPIO pin number or name (PWM capable)
- initial_value: Tone or None - Initial tone to play
- mid_tone: Tone - Middle tone for value calculations
- octaves: int - Number of octaves above and below mid_tone
- pin_factory: Factory or None - Pin factory for advanced usage
"""
def play(self, tone: 'Tone'):
"""Play a specific tone."""
def stop(self):
"""Stop playing the current tone."""
@property
def tone(self) -> 'Tone':
"""Currently playing tone."""
@tone.setter
def tone(self, value: 'Tone'): ...
@property
def mid_tone(self) -> 'Tone':
"""Middle tone for value calculations."""
@property
def octaves(self) -> int:
"""Number of octaves above and below mid_tone."""
@property
def is_active(self) -> bool:
"""Returns True if currently playing a tone."""Musical tone representation for use with TonalBuzzer.
class Tone(float):
def __init__(self, value=None, *, frequency=None, midi=None, note=None):
"""
Musical tone representation supporting multiple formats.
Parameters:
- value: float or int - Frequency in Hz or MIDI note number (auto-detected)
- frequency: float - Explicit frequency in Hz
- midi: int - MIDI note number (0-127)
- note: str - Musical note string (e.g., 'A4', 'C#3', 'Bb2')
"""
@classmethod
def from_frequency(cls, frequency: float) -> 'Tone':
"""Create tone from frequency in Hz."""
@classmethod
def from_midi(cls, midi: int) -> 'Tone':
"""Create tone from MIDI note number (0-127)."""
@classmethod
def from_note(cls, note: str) -> 'Tone':
"""Create tone from musical note string (e.g., 'A4', 'C#3')."""
@property
def frequency(self) -> float:
"""Frequency in Hz."""
@property
def midi(self) -> int:
"""MIDI note number."""
@property
def note(self) -> str:
"""Musical note string representation."""
def up(self, semitones: int = 1) -> 'Tone':
"""Return tone stepped up by specified semitones."""
def down(self, semitones: int = 1) -> 'Tone':
"""Return tone stepped down by specified semitones."""from gpiozero import LED
from time import sleep
led = LED(17)
# Simple on/off
led.on()
sleep(1)
led.off()
# Blinking
led.blink() # Blink forever in background
sleep(10)
led.off()
# Custom blink pattern
led.blink(on_time=0.1, off_time=0.5, n=5)from gpiozero import PWMLED
from time import sleep
led = PWMLED(17)
# Fade in and out
for brightness in range(100):
led.brightness = brightness / 100.0
sleep(0.01)
for brightness in range(100, 0, -1):
led.brightness = brightness / 100.0
sleep(0.01)
# Pulse automatically
led.pulse()
sleep(10)
led.off()from gpiozero import RGBLED
from time import sleep
rgb = RGBLED(red=2, green=3, blue=4)
# Set colors
rgb.color = (1, 0, 0) # Red
sleep(1)
rgb.color = (0, 1, 0) # Green
sleep(1)
rgb.color = (0, 0, 1) # Blue
sleep(1)
rgb.color = (1, 1, 1) # White
sleep(1)
# Individual components
rgb.red = 0.5
rgb.green = 0.3
rgb.blue = 0.8
# Color cycling
rgb.pulse()
sleep(10)
rgb.off()from gpiozero import Motor
from time import sleep
motor = Motor(forward=2, backward=3)
# Basic movement
motor.forward()
sleep(2)
motor.backward()
sleep(2)
motor.stop()
# Speed control (if PWM enabled)
motor.forward(0.5) # Half speed forward
sleep(2)
motor.backward(0.7) # 70% speed backward
sleep(2)
motor.stop()
# Using value property
motor.value = 0.8 # 80% forward
sleep(2)
motor.value = -0.6 # 60% backward
sleep(2)
motor.value = 0 # Stopfrom gpiozero import Servo, AngularServo
from time import sleep
# Standard servo (-1 to 1)
servo = Servo(17)
servo.min()
sleep(1)
servo.mid()
sleep(1)
servo.max()
sleep(1)
# Angular servo with degrees
angular_servo = AngularServo(18, min_angle=-90, max_angle=90)
angular_servo.angle = -90
sleep(1)
angular_servo.angle = 0
sleep(1)
angular_servo.angle = 90
sleep(1)from gpiozero import Buzzer, TonalBuzzer
from gpiozero.tones import Tone
from time import sleep
# Simple buzzer
buzzer = Buzzer(17)
buzzer.beep(on_time=0.1, off_time=0.1, n=3)
sleep(2)
# Tonal buzzer with melodies
tonal_buzzer = TonalBuzzer(18)
notes = [Tone(261.63), Tone(293.66), Tone(329.63), Tone(349.23)] # C, D, E, F
for note in notes:
tonal_buzzer.play(note)
sleep(0.5)
tonal_buzzer.stop()
# Different ways to create tones
middle_c = Tone(frequency=261.63) # Explicit frequency
concert_a = Tone(midi=69) # MIDI note number
g_sharp = Tone(note='G#4') # Musical note string
# Scale and melody examples
c_major_scale = [
Tone('C4'), Tone('D4'), Tone('E4'), Tone('F4'),
Tone('G4'), Tone('A4'), Tone('B4'), Tone('C5')
]
for tone in c_major_scale:
tonal_buzzer.play(tone)
sleep(0.3)
print(f"Playing {tone.note} ({tone.frequency:.1f}Hz, MIDI#{tone.midi})")
tonal_buzzer.stop()Install with Tessl CLI
npx tessl i tessl/pypi-gpiozero