A simple interface to GPIO devices with Raspberry Pi
—
GPIO input devices for sensors, buttons, and analog input components. All input devices support event-driven programming and can be used as sources for other devices through the source/values chaining system.
Base class for all GPIO input devices with pull-up/pull-down configuration.
class InputDevice(GPIODevice):
def __init__(self, pin=None, *, pull_up=False, active_state=None, pin_factory=None):
"""
Generic GPIO input device.
Parameters:
- pin: int or str - GPIO pin number or name
- pull_up: bool or None - True for pull-up, False for pull-down, None for floating
- active_state: bool or None - True if HIGH is active, False if LOW is active (required when pull_up=None)
- pin_factory: Factory or None - Pin factory for advanced usage
"""
@property
def pull_up(self) -> bool | None:
"""Returns True if using pull-up resistor, False for pull-down, None for floating."""
@property
def is_active(self) -> bool:
"""Returns True if device is currently active."""
@property
def value(self) -> float:
"""Returns current value (0.0 for inactive, 1.0 for active)."""Base class for digital input devices with event handling and debouncing.
class DigitalInputDevice(EventsMixin, InputDevice):
def __init__(self, pin=None, *, pull_up=False, active_state=None, bounce_time=None, pin_factory=None):
"""
Digital input device with event handling.
Parameters:
- pin: int or str - GPIO pin number or name
- pull_up: bool or None - Pull resistor configuration
- active_state: bool or None - Active state definition
- bounce_time: float or None - Debounce time in seconds
- pin_factory: Factory or None - Pin factory for advanced usage
"""
@property
def when_activated(self) -> callable:
"""Callback function called when device becomes active."""
@when_activated.setter
def when_activated(self, value: callable): ...
@property
def when_deactivated(self) -> callable:
"""Callback function called when device becomes inactive."""
@when_deactivated.setter
def when_deactivated(self, value: callable): ...
def wait_for_active(self, timeout: float = None) -> bool:
"""Wait for device to become active. Returns True if activated, False if timeout."""
def wait_for_inactive(self, timeout: float = None) -> bool:
"""Wait for device to become inactive. Returns True if deactivated, False if timeout."""Base class for input devices requiring smoothed readings (analog sensors).
class SmoothedInputDevice(InputDevice):
def __init__(self, pin=None, *, pull_up=False, active_state=None, threshold=0.5, queue_len=5, sample_rate=100, partial=False, pin_factory=None):
"""
Input device with value smoothing.
Parameters:
- pin: int or str - GPIO pin number or name
- pull_up: bool or None - Pull resistor configuration
- active_state: bool or None - Active state definition
- threshold: float - Activation threshold (0.0-1.0)
- queue_len: int - Number of samples for smoothing
- sample_rate: float - Sampling frequency in Hz
- partial: bool - If True, return values before queue is full
- pin_factory: Factory or None - Pin factory for advanced usage
"""
@property
def threshold(self) -> float:
"""Activation threshold value (0.0-1.0)."""
@threshold.setter
def threshold(self, value: float): ...
@property
def partial(self) -> bool:
"""If True, returns values before queue is full."""Push button with hold detection and event handling.
class Button(DigitalInputDevice, HoldMixin):
def __init__(self, pin=None, *, pull_up=True, bounce_time=None, hold_time=1, hold_repeat=False, pin_factory=None):
"""
Push button input device.
Parameters:
- pin: int or str - GPIO pin number or name
- pull_up: bool - True for pull-up (default), False for pull-down
- bounce_time: float or None - Debounce time in seconds
- hold_time: float - Time in seconds before button is considered held
- hold_repeat: bool - If True, when_held fires repeatedly while held
- pin_factory: Factory or None - Pin factory for advanced usage
"""
@property
def is_pressed(self) -> bool:
"""Returns True if button is currently pressed."""
@property
def is_held(self) -> bool:
"""Returns True if button is currently held."""
@property
def when_pressed(self) -> callable:
"""Callback function called when button is pressed."""
@when_pressed.setter
def when_pressed(self, value: callable): ...
@property
def when_released(self) -> callable:
"""Callback function called when button is released."""
@when_released.setter
def when_released(self, value: callable): ...
@property
def when_held(self) -> callable:
"""Callback function called when button is held."""
@when_held.setter
def when_held(self, value: callable): ...
@property
def hold_time(self) -> float:
"""Time in seconds before button is considered held."""
@hold_time.setter
def hold_time(self, value: float): ...
@property
def hold_repeat(self) -> bool:
"""If True, when_held fires repeatedly while held."""
@hold_repeat.setter
def hold_repeat(self, value: bool): ...
def wait_for_press(self, timeout: float = None) -> bool:
"""Wait for button to be pressed."""
def wait_for_release(self, timeout: float = None) -> bool:
"""Wait for button to be released."""Passive infrared (PIR) motion sensor.
class MotionSensor(SmoothedInputDevice):
def __init__(self, pin=None, *, queue_len=1, sample_rate=10, threshold=0.5, partial=False, pin_factory=None):
"""
PIR motion sensor.
Parameters:
- pin: int or str - GPIO pin number or name
- queue_len: int - Number of samples for motion detection
- sample_rate: float - Sampling frequency in Hz
- threshold: float - Motion detection threshold (0.0-1.0)
- partial: bool - If True, return values before queue is full
- pin_factory: Factory or None - Pin factory for advanced usage
"""
@property
def motion_detected(self) -> bool:
"""Returns True if motion is currently detected."""
@property
def when_motion(self) -> callable:
"""Callback function called when motion is detected."""
@when_motion.setter
def when_motion(self, value: callable): ...
@property
def when_no_motion(self) -> callable:
"""Callback function called when motion stops."""
@when_no_motion.setter
def when_no_motion(self, value: callable): ...
def wait_for_motion(self, timeout: float = None) -> bool:
"""Wait for motion to be detected."""
def wait_for_no_motion(self, timeout: float = None) -> bool:
"""Wait for motion to stop."""Light dependent resistor (LDR) sensor.
class LightSensor(SmoothedInputDevice):
def __init__(self, pin=None, *, queue_len=5, charge_time_limit=0.01, threshold=0.1, partial=False, pin_factory=None):
"""
Light dependent resistor sensor.
Parameters:
- pin: int or str - GPIO pin number or name
- queue_len: int - Number of samples for smoothing
- charge_time_limit: float - Maximum time to wait for capacitor charge
- threshold: float - Light detection threshold (0.0-1.0)
- partial: bool - If True, return values before queue is full
- pin_factory: Factory or None - Pin factory for advanced usage
"""
@property
def light_detected(self) -> bool:
"""Returns True if light level is above threshold."""
@property
def when_light(self) -> callable:
"""Callback function called when light is detected."""
@when_light.setter
def when_light(self, value: callable): ...
@property
def when_dark(self) -> callable:
"""Callback function called when it gets dark."""
@when_dark.setter
def when_dark(self, value: callable): ...
def wait_for_light(self, timeout: float = None) -> bool:
"""Wait for light to be detected."""
def wait_for_dark(self, timeout: float = None) -> bool:
"""Wait for darkness."""Line detection sensor (typically infrared).
class LineSensor(SmoothedInputDevice):
def __init__(self, pin=None, *, queue_len=5, charge_time_limit=0.01, threshold=0.1, partial=False, pin_factory=None):
"""
Line detection sensor.
Parameters:
- pin: int or str - GPIO pin number or name
- queue_len: int - Number of samples for smoothing
- charge_time_limit: float - Maximum time to wait for capacitor charge
- threshold: float - Line detection threshold (0.0-1.0)
- partial: bool - If True, return values before queue is full
- pin_factory: Factory or None - Pin factory for advanced usage
"""
@property
def line_detected(self) -> bool:
"""Returns True if line is detected."""
@property
def when_line(self) -> callable:
"""Callback function called when line is detected."""
@when_line.setter
def when_line(self, value: callable): ...
@property
def when_no_line(self) -> callable:
"""Callback function called when line is lost."""
@when_no_line.setter
def when_no_line(self, value: callable): ...
def wait_for_line(self, timeout: float = None) -> bool:
"""Wait for line to be detected."""
def wait_for_no_line(self, timeout: float = None) -> bool:
"""Wait for line to be lost."""Ultrasonic distance sensor (HC-SR04 style).
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):
"""
Ultrasonic distance sensor.
Parameters:
- echo: int or str - Echo pin number or name
- trigger: int or str - Trigger pin number or name
- queue_len: int - Number of distance samples for smoothing
- max_distance: float - Maximum measurable distance in meters
- threshold_distance: float - Distance threshold for in_range property
- partial: bool - If True, return values before queue is full
- pin_factory: Factory or None - Pin factory for advanced usage
"""
@property
def distance(self) -> float:
"""Current distance reading in meters."""
@property
def max_distance(self) -> float:
"""Maximum measurable distance in meters."""
@property
def threshold_distance(self) -> float:
"""Distance threshold for in_range property."""
@threshold_distance.setter
def threshold_distance(self, value: float): ...
@property
def in_range(self) -> bool:
"""Returns True if object is within threshold distance."""
@property
def when_in_range(self) -> callable:
"""Callback function called when object enters range."""
@when_in_range.setter
def when_in_range(self, value: callable): ...
@property
def when_out_of_range(self) -> callable:
"""Callback function called when object exits range."""
@when_out_of_range.setter
def when_out_of_range(self, value: callable): ...
def wait_for_in_range(self, timeout: float = None) -> bool:
"""Wait for object to enter range."""
def wait_for_out_of_range(self, timeout: float = None) -> bool:
"""Wait for object to exit range."""Rotary encoder with A and B phases.
class RotaryEncoder(CompositeDevice):
def __init__(self, a=None, b=None, *, wrap=False, max_steps=0, threshold_steps=(0, 0), pin_factory=None):
"""
Rotary encoder with quadrature decoding.
Parameters:
- a: int or str - A phase pin number or name
- b: int or str - B phase pin number or name
- wrap: bool - If True, steps wrap around at max_steps
- max_steps: int - Maximum step count (0 for unlimited)
- threshold_steps: tuple - (min, max) step thresholds for in_range
- pin_factory: Factory or None - Pin factory for advanced usage
"""
@property
def steps(self) -> int:
"""Current step count."""
@property
def value(self) -> float:
"""Normalized value (-1.0 to 1.0 based on steps and max_steps)."""
@property
def max_steps(self) -> int:
"""Maximum step count."""
@property
def wrap(self) -> bool:
"""If True, steps wrap around at max_steps."""
@property
def threshold_steps(self) -> tuple:
"""(min, max) step thresholds for in_range."""
@threshold_steps.setter
def threshold_steps(self, value: tuple): ...
@property
def in_range(self) -> bool:
"""Returns True if steps are within threshold range."""
@property
def when_rotated(self) -> callable:
"""Callback function called when encoder rotates."""
@when_rotated.setter
def when_rotated(self, value: callable): ...
@property
def when_rotated_clockwise(self) -> callable:
"""Callback function called when encoder rotates clockwise."""
@when_rotated_clockwise.setter
def when_rotated_clockwise(self, value: callable): ...
@property
def when_rotated_counter_clockwise(self) -> callable:
"""Callback function called when encoder rotates counter-clockwise."""
@when_rotated_counter_clockwise.setter
def when_rotated_counter_clockwise(self, value: callable): ...from gpiozero import Button, LED
from signal import pause
button = Button(2)
led = LED(17)
button.when_pressed = led.on
button.when_released = led.off
pause()from gpiozero import MotionSensor, LED
from signal import pause
motion1 = MotionSensor(4)
motion2 = MotionSensor(5)
alert_led = LED(17)
def motion_detected():
print("Motion detected!")
alert_led.on()
def no_motion():
print("No motion")
alert_led.off()
motion1.when_motion = motion_detected
motion1.when_no_motion = no_motion
motion2.when_motion = motion_detected
motion2.when_no_motion = no_motion
pause()from gpiozero import DistanceSensor, Buzzer
from signal import pause
sensor = DistanceSensor(echo=24, trigger=23, threshold_distance=0.3)
buzzer = Buzzer(18)
sensor.when_in_range = buzzer.on
sensor.when_out_of_range = buzzer.off
pause()from gpiozero import LightSensor, LED
from signal import pause
light_sensor = LightSensor(7, threshold=0.1)
night_light = LED(17)
# Turn on LED when it gets dark
light_sensor.when_dark = night_light.on
light_sensor.when_light = night_light.off
pause()Install with Tessl CLI
npx tessl i tessl/pypi-gpiozero