{"id":34108557,"url":"https://github.com/stylesuxx/rpi-servo-pwm","last_synced_at":"2026-04-06T06:32:56.618Z","repository":{"id":308429013,"uuid":"1032827519","full_name":"stylesuxx/rpi-servo-pwm","owner":"stylesuxx","description":"Hardware PWM library for precise servo control on Raspberry Pi using Linux sysfs interface","archived":false,"fork":false,"pushed_at":"2026-01-23T01:55:50.000Z","size":27,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-01-23T18:52:00.957Z","etag":null,"topics":["pwm","python","python3","raspberry-pi","raspberry-pi-zero-2-w","rc"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/stylesuxx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-08-05T22:26:23.000Z","updated_at":"2026-01-23T01:55:53.000Z","dependencies_parsed_at":"2025-08-05T23:02:14.747Z","dependency_job_id":"1c0fd146-f5ac-437e-8056-3014c4340599","html_url":"https://github.com/stylesuxx/rpi-servo-pwm","commit_stats":null,"previous_names":["stylesuxx/rpi-servo-pwm"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/stylesuxx/rpi-servo-pwm","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stylesuxx%2Frpi-servo-pwm","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stylesuxx%2Frpi-servo-pwm/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stylesuxx%2Frpi-servo-pwm/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stylesuxx%2Frpi-servo-pwm/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/stylesuxx","download_url":"https://codeload.github.com/stylesuxx/rpi-servo-pwm/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/stylesuxx%2Frpi-servo-pwm/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31463014,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-05T21:22:52.476Z","status":"online","status_checked_at":"2026-04-06T02:00:07.287Z","response_time":112,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["pwm","python","python3","raspberry-pi","raspberry-pi-zero-2-w","rc"],"created_at":"2025-12-14T18:19:19.601Z","updated_at":"2026-04-06T06:32:56.613Z","avatar_url":"https://github.com/stylesuxx.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Tests](https://github.com/stylesuxx/rpi-servo-pwm/workflows/Tests/badge.svg)](https://github.com/stylesuxx/rpi-servo-pwm/actions)\n [![Coverage](https://codecov.io/gh/stylesuxx/rpi-servo-pwm/branch/main/graph/badge.svg)](https://codecov.io/gh/stylesuxx/rpi-servo-pwm) [![Python versions](https://img.shields.io/pypi/pyversions/rpi-servo-pwm.svg)](https://pypi.org/project/rpi-servo-pwm/) [![PyPI version](https://badge.fury.io/py/rpi-servo-pwm.svg)](https://badge.fury.io/py/rpi-servo-pwm) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![PyPI downloads](https://img.shields.io/pypi/dm/rpi-servo-pwm.svg)](https://pypi.org/project/rpi-servo-pwm/) [![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n\n# Raspberry Pi Zero 2 W Servo PWM\n\nA lightweight Python library for controlling RC servos on the Raspberry Pi Zero 2 W using hardware PWM via the Linux kernel.\n\nThis library is specifically designed for **servo PWM control**. The PWM frequency is fixed to 50 Hz by default, and you specify the pulse length in microseconds.\n\nTypical RC servos expect a pulse width between **1000 µs and 2000 µs**, where **1500 µs** is the center position. Some servo models support a wider range, e.g., **900–2100 µs**, but you must verify this in your servo's datasheet or test cautiously. Increase or decrease values gradually; if the servo starts making crackling or buzzing noises, reduce the range.\nExtended pulse width ranges are usually symmetrical – for example, if you can safely reduce the pulse width by 100 µs, you can usually increase it by a similar amount.\n\n## Why this library?\n\nI wanted a deterministic library for one specific use case: **Servo PWM**.\nExisting solutions were often too bloated, included unused features or relied on software-based PWM, which is not timing-accurate.\n\nThis library ensures:\n\n* **Hardware-only PWM** (no bit-banging fallback)\n* **Predictable timing**, as PWM generation is handled by the Raspberry Pi's PWM hardware module\n* A **minimal, low-overhead interface** tailored for servos (frequency fixed at 50Hz, only pulse width adjustable)\n\n## Supported platforms\n\nAll Raspberry Pi platforms with kernel hardware PWM support should work.\n\nIt has been tested on the following platforms:\n\n* Raspberry Pi Zero 2 W (with Raspberry Pi OS Bullseye, Bookworm)\n\n## Setup\n\nThis library uses the kernel PWM driver provided by Raspberry Pi OS. To enable it, configure the Device Tree Overlay and reboot.\n\n\u003e Make sure you are not running any other PWM-related software like `pigpiod` for example.\n\n### Enable PWM in `/boot/config.txt`\n\nAdd the following line:\n\n```ini\ndtoverlay=pwm-2chan\n```\n\nReboot:\n\n```bash\nsudo reboot\n```\n\n### Verify PWM availability\n\nAfter reboot, check that the PWM interface is present:\n\n```bash\nls /sys/class/pwm/pwmchip0\n# Expected output: device  export  npwm  power  subsystem  uevent  unexport\n```\n\nVerify that there are two available channels:\n\n```bash\ncat /sys/class/pwm/pwmchip0/npwm\n# Expected output: 2\n```\n\n### Verify Group membership\n\nMake sure that the invoking user is part of the `gpio` group, if not add them:\n\n```bash\nsudo usermod -aG gpio $USER\n```\n\n### Default GPIO mapping\n\nWith the default overlay configuration, channels are mapped as follows:\n\n| Channel | GPIO Pin |\n|---------|----------|\n| 0       | GPIO 18  |\n| 1       | GPIO 19  |\n\n### Optional: remapping PWM pins\n\nYou can remap PWM channels to other supported GPIO pins using overlay parameters.\nFor example, to map channel 1 to GPIO 13:\n\n```ini\ndtoverlay=pwm-2chan,pin=18,func=2,pin2=13,func2=4\n```\n\nResulting mapping:\n\n| Channel | GPIO Pin |\n|---------|----------|\n| 0       | GPIO 18  |\n| 1       | GPIO 13  |\n\nVerify the mapping:\n\n```bash\nraspi-gpio get 18\n# GPIO 18: level=0 fsel=2 alt=5 func=PWM0\n\nraspi-gpio get 13\n# GPIO 13: level=0 fsel=4 alt=0 func=PWM1\n```\n\n## Installation\n\nInstall via pip:\n\n```bash\npip install rpi-servo-pwm\n```\n\n## Usage\n\nExample using manual resource management:\n\n```python\nfrom rpi_servo_pwm import HardwarePWM\n\n# Initialize PWM on channel 0 (GPIO 18), using 50 Hz\npwm = HardwarePWM(channel=0, frequency_hz=50)\n\n# Start PWM with initial pulse width\npwm.setup(1500)\n\n# Move servo to a new position\npwm.set_pulse_width(2000)\n\n# Disable and close\npwm.disable()\npwm.close()\n```\n\nExample using a context manager:\n\n```python\nfrom rpi_servo_pwm import HardwarePWM\n\nwith HardwarePWM(channel=0) as pwm:\n    pwm.setup(1500)\n    pwm.set_pulse_width(2000)\n    pwm.disable()\n```\n\nOnce you call `setup`, the PWM signal starts outputting on the pin. Calling `disable` stops the PWM output.\n\n## Testing\n\nRun unit tests with:\n\n```bash\npython -m pytest tests\n```\n\nTests are fully mocked and safe to run without hardware access.\n\n## Contributing\n\nPull requests and issue reports are welcome.\n\nBefore contributing:\n\n```bash\npython -m venv ./venv\nsource ./venv/bin/activate\npip install -r requirements.txt\n```\n\nBefore submitting a PR, ensure code is formatted with Black:\n\n```bash\n# Check formatting\nblack --check src/ tests/ main.py\n\n# Apply formatting\nblack src/ tests/ main.py\n```\n\n## Distribution\n\nTo build and upload to PyPI:\n\n1. Update the version in both `src/__init__.py` and `pyproject.toml`\n2. Build and publish:\n\n```bash\nrm -rf dist/*\npython -m build\npython -m twine upload --repository testpypi dist/*\npython -m twine upload dist/*\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstylesuxx%2Frpi-servo-pwm","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstylesuxx%2Frpi-servo-pwm","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstylesuxx%2Frpi-servo-pwm/lists"}