Skip to main content

Web-based remote control panel for debugging PCA9685 servo drivers on robots.

Project description

PCA9685 Debug Panel

Web-based remote control panel for debugging PCA9685 servo drivers on robots.

⚠️ Security Notice: This tool exposes a web server with no authentication. Only run it on a trusted local network (e.g., your robot's Wi‑Fi). Do not expose it to the public internet.

Python FastAPI

中文文档

Description

A lightweight web panel (similar to FTC Dashboard) that runs on your robot and lets you control PCA9685-driven servos from any browser over Wi‑Fi. Supports per-channel angle control with calibration, live device status monitoring, and workspace save/load — so you can tune and debug servos without touching code.

Why? Adjusting servo angles on a robot usually means SSH + manual scripts. This panel gives you a visual UI in the browser with sliders, real-time feedback, and configuration persistence across restarts.

Installing / Getting started

Prerequisites

  • Python 3.10+
  • A Raspberry Pi (or similar) with I²C enabled and connected to PCA9685, or any machine for UI-only development (mock mode)

Quick setup

Using Pip

# Install from PyPI
pip install pca9685-debugging-panel

# Start the server
pca9685-panel --host 0.0.0.0 --port 8080

Then open http://<robot-ip>:8080 in your browser.

From source

git clone https://github.com/xiaokai-lyk/PCA9685-debugging-panel.git
cd PCA9685-debugging-panel
uv sync
python main.py

On first launch a config.json file is created automatically with default values (I²C address 0x40, 50 Hz, 600–2400 µs pulse range).

Running on a desktop (no hardware)

Use the --mock flag to skip hardware initialisation entirely — all APIs work, the UI is fully interactive, and no real hardware is required for frontend development:

pca9685-panel --mock

Developing

Project structure

PCA9685-debugging-panel/
├── backend/
│   ├── app.py              # FastAPI entry point (REST + SSE)
│   ├── pca9685.py          # PCA9685 driver (real hardware + optional mock mode)
│   ├── config_store.py     # JSON configuration persistence
│   └── schemas.py          # Pydantic request/response models
├── frontend/
│   ├── index.html          # Single-page UI
│   ├── app.js              # SSE connection, REST calls, state management
│   └── styles.css          # Dark theme, responsive grid
├── config.json             # Auto-generated runtime configuration
├── main.py                 # Convenience launcher
├── plan.md                 # Architecture & design decisions
└── pyproject.toml          # Project metadata & dependencies

API overview

Method Path Description
GET /api/status Device status, frequency, I²C address
GET /api/servo/channels All 16 channel states
POST /api/servo/set Set angle ({channel, angle}) or duty ({channel, duty})
POST /api/servo/name Rename a channel {channel, name}
POST /api/servo/calibrate Set angle ↔ pulse calibration
POST /api/pca9685/frequency Set PWM frequency {frequency_hz}
POST /api/pca9685/pulse_range Set default pulse range
GET /api/workspace/export Download full configuration as JSON
POST /api/workspace/import Upload & apply a workspace JSON
GET /api/events SSE stream for device status pushes

Interactive docs available at http://<host>:8080/docs (Swagger UI).

Features

  • 16-channel servo grid — angle slider / duty-cycle slider per channel, with live pulse-width display
  • Per-channel calibration — map your own angle‑to‑pulse ranges for each servo
  • Real-time status — device online/offline indicator with heartbeat via SSE
  • Frequency control — adjustable 40–400 Hz PWM frequency
  • Workspace save/load — export the full configuration (calibration, names, settings) as a JSON file; import it later or on a different robot
  • Restart persistenceconfig.json survives reboots so your last setup is restored automatically
  • Mock mode — run with --mock flag for UI development & testing without hardware
  • Dark theme — responsive layout, works on desktop and mobile browsers

Configuration

config.json (auto-managed)

Key Type Default Description
i2c_address int 64 (0x40) I²C address of the PCA9685
frequency_hz float 50.0 PWM frequency (40–400 Hz)
min_pulse_us float 600.0 Default minimum pulse width in µs
max_pulse_us float 2400.0 Default maximum pulse width in µs
channels object {} Per-channel calibration, name, and last output

This file is written automatically when settings change — no manual editing needed.

Workspace file (user-managed)

Exported via the UI or GET /api/workspace/export. Contains the same fields plus full per-channel data (calibration, names, current positions). Can be imported on another machine to replicate a setup.

Troubleshooting

Device stays offline — "Hardware init failed: No module named 'RPi'"

This may happen when you are NOT using Raspberry Pi OS.

The Adafruit Blinka library cannot find the GPIO driver for your Raspberry Pi.

# Recommended
pip install rpi-lgpio

# For older OS (not recommended, may involve the compilation of C extensions)
pip install RPi.GPIO

Offline — Hardware init faile2d: No I2C device at address: 0x40

Your PCA9685 might be at a different address. Scan the bus:

sudo apt-get install i2c-tools
i2cdetect -y 1

If it's all -- in the result, please check if the device connection is correct. Make sure the connection is correct and then re-scan.

Then update the address in config.json or via the Settings modal in the UI.

Contributing

If you'd like to contribute, please fork the repository and use a feature branch. Pull requests are welcome.

For major changes, open an issue first to discuss what you would like to change.

Links

Licensing

The code in this project is licensed under the Apache License, Version 2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pca9685_debugging_panel-0.1.0.tar.gz (83.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pca9685_debugging_panel-0.1.0-py3-none-any.whl (29.7 kB view details)

Uploaded Python 3

File details

Details for the file pca9685_debugging_panel-0.1.0.tar.gz.

File metadata

  • Download URL: pca9685_debugging_panel-0.1.0.tar.gz
  • Upload date:
  • Size: 83.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.18 {"installer":{"name":"uv","version":"0.11.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pca9685_debugging_panel-0.1.0.tar.gz
Algorithm Hash digest
SHA256 593c000664921467ce82926031f9efac7e0fd6daac3ea2c6601db978f6b89437
MD5 b3c9edc87bebcc41bc6e050b64165f5f
BLAKE2b-256 5a2a22b93327f1d426d6d80dbdbaad9510fa8ba291cd355df00a3e8e050b31ab

See more details on using hashes here.

File details

Details for the file pca9685_debugging_panel-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: pca9685_debugging_panel-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 29.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.18 {"installer":{"name":"uv","version":"0.11.18","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for pca9685_debugging_panel-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 50ce26b18c61e3736ee109506c9737fe5d9ae2e7dc3c81fddc328dc734de9247
MD5 c2277fa29091ae32f553d2e7f502a20f
BLAKE2b-256 ed79e6b2c18ca032a8b4e57624471d51e083919203d2285172ebd8e11ddb065e

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page