Skip to main content

PCA9685 Debug Panel

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

⚠️ Security Notice: By default, this tool starts with no authentication. For shared networks, use --auth-token <token> to require a shared secret for write operations (POST/DELETE). The token is sent over unencrypted HTTP and has no brute-force protection — use on trusted networks only. Never expose the panel to the public internet.

Python FastAPI

中文文档

Vedio Demonstration

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

From GitHub Releases

Each release includes a pre-built .whl file as an attachment. Download it and install directly:

pip install pca9685_debugging_panel-0.2.0-py3-none-any.whl
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

Protecting write operations

To require a shared secret token for all write operations (POST/DELETE), use the --auth-token flag:

pca9685-panel --auth-token my-secret-token

The browser will show a login overlay; enter the same token to unlock the panel. Read operations (status, channel polling, SSE events) remain public so you can still monitor the device without authentication.

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
POST /api/output/global Master switch: enable/disable all channels {enabled}
POST /api/output/channel Enable/disable a single channel {channel, enabled}
GET /api/workspace/export Download full configuration as JSON
POST /api/workspace/import Upload & apply a workspace JSON
POST /api/config/clear Reset all config to factory defaults
GET /api/actions List all saved action records
POST /api/actions/record Save current positions as a named action {name}
POST /api/actions/{index}/play Replay a saved action (restore all channel positions)
DELETE /api/actions/{index} Delete a saved action
POST /api/actions/{index}/rename Rename a saved action {name}
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.

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.2.1.tar.gz (95.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.2.1-py3-none-any.whl (41.5 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pca9685_debugging_panel-0.2.1.tar.gz
  • Upload date:
  • Size: 95.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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.2.1.tar.gz
Algorithm Hash digest
SHA256 a83967035c9a2b73c36cf58e1b4db6057506ad6097dd4a9e2980d272dd649348
MD5 2deefa37fa791a935a67b9d25b7660e4
BLAKE2b-256 7fb1e8e983cfb77d38df29a4e6030ece38386ef1c78a1fb4df554e745aeb7f27

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pca9685_debugging_panel-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 41.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","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.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 a8873c58d8e3b9742fd8371bd18d8fb38ba35fc1bcdd44a18551be6f5d8fa709
MD5 2f8224817c665be924216a3384e8d322
BLAKE2b-256 49cb595a01eb73cfb61a6d8476d8ab954b10dc04e78fee5ad6652a20f63696c6

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 Sentry Error logging StatusPage Status page