Python bindings for libgpiod
gpiod provides official Python bindings for `libgpiod`, a library designed for interacting with the modern Linux GPIO character device interface. This package bundles `libgpiod` for convenience, making it independent of the system's `libgpiod` installation. It replaces the older, obsolete sysfs interface by offering a robust way to control GPIO pins, read input values, set outputs, and monitor events with advanced features like event polling and setting multiple values. The current version is 2.4.2, and it is actively maintained.
Warnings
- breaking The `gpiod` library underwent a major breaking change with version 2.0.2. This version replaced an older, unofficial pure-Python implementation (versions 1.5.4 and prior) with official C-bindings to `libgpiod`. The APIs are not backwards compatible.
- gotcha Building `gpiod` from source (which is often required as binary wheels are not provided) necessitates the `python3-dev` package (or equivalent development headers for Python). Without it, installation will fail.
- gotcha The path to the GPIO character device (`/dev/gpiochipX`) varies between different hardware platforms. Specifically, Raspberry Pi 5 typically uses `/dev/gpiochip4` for external GPIOs, while older Raspberry Pi models (e.g., Pi 4, Pi 3, Pi Zero) commonly use `/dev/gpiochip0`.
- gotcha GPIO line objects (`gpiod.Chip` and `gpiod.LineRequest`) manage system resources (file descriptors). Failure to close these resources can lead to resource leaks and prevent other processes from accessing the GPIOs.
- gotcha Permissions issues are common when accessing `/dev/gpiochipX` devices, especially when running Python scripts as a regular user.
Install
-
pip install gpiod -
sudo apt install python3-dev pip install gpiod -
LINK_SYSTEM_LIBGPIOD=1 pip install gpiod
Imports
- gpiod
import gpiod
- Chip
import gpiod.chip
from gpiod import Chip
- LineSettings
from gpiod.line import LineSettings
- Direction
from gpiod.line import Direction
- Value
from gpiod.line import Value
Quickstart
import time
import os
from gpiod import Chip
from gpiod.line import Direction, Value, LineSettings
# NOTE: For Raspberry Pi 5, use '/dev/gpiochip4'. For Pi 4 and older, use '/dev/gpiochip0'.
GPIO_CHIP_PATH = os.environ.get('GPIO_CHIP_PATH', '/dev/gpiochip0')
GPIO_LINE_OFFSET = int(os.environ.get('GPIO_LINE_OFFSET', '17')) # Example offset, replace with your actual GPIO pin number
def blink_gpio(chip_path: str, line_offset: int, num_blinks: int = 5, delay: float = 0.5):
try:
with Chip(chip_path) as chip:
print(f"Accessing GPIO chip: {chip.name} [{chip.label}] ({chip.num_lines} lines)")
# Request the line for output
line_settings = LineSettings(direction=Direction.OUTPUT)
# Use a dictionary for request_lines config
config = {line_offset: line_settings}
# Using request_lines to get a LineRequest object
with chip.request_lines(consumer="quickstart_blinker", config=config) as request:
print(f"Blinking GPIO line {line_offset}...")
for i in range(num_blinks):
request.set_value(line_offset, Value.ACTIVE)
print(f"[{i+1}/{num_blinks}] Line {line_offset} HIGH")
time.sleep(delay)
request.set_value(line_offset, Value.INACTIVE)
print(f"[{i+1}/{num_blinks}] Line {line_offset} LOW")
time.sleep(delay)
print("Blinking complete.")
except FileNotFoundError:
print(f"Error: GPIO chip '{chip_path}' not found. Ensure it exists and you have permissions.")
except PermissionError:
print(f"Error: Permission denied to access '{chip_path}'. Try running with 'sudo'.")
except Exception as e:
print(f"An error occurred: {e}")
if __name__ == '__main__':
blink_gpio(GPIO_CHIP_PATH, GPIO_LINE_OFFSET)