Skip to content

Convert rgb-matrix.sh to Python (with Pi 5 support)#400

Merged
makermelissa merged 4 commits into
adafruit:mainfrom
makermelissa-piclaw:convert-rgb-matrix
Jun 16, 2026
Merged

Convert rgb-matrix.sh to Python (with Pi 5 support)#400
makermelissa merged 4 commits into
adafruit:mainfrom
makermelissa-piclaw:convert-rgb-matrix

Conversation

@makermelissa-piclaw

Copy link
Copy Markdown
Contributor

Converts rgb-matrix.sh to rgb-matrix.py, modernized for current hardware/OS (Pi 3/4/5, Bookworm/Trixie).

What changed

  • 1:1 logic port of the installer flow: quality-vs-convenience menu, optional RTC, sound blacklist (quality), CPU isolation (isolcpus) handling, repo download, prompt-reboot.
  • Pin bump for Pi 5 support. The previous upstream commit builds a register-poke driver that cannot drive a matrix on the Pi 5. Bumped hzeller/rpi-rgb-led-matrix to the first commit with Pi 5 (RP1) support.
  • Build via pip install . The new upstream is a scikit-build-core / Cython package; the old make build-python target is gone. Added cmake to apt prerequisites (required by scikit-build-core). Bindings install into the active environment so from rgbmatrix import RGBMatrix works for the user's project.
  • Hardware mapping is now runtime (--led-gpio-mapping=adafruit-hat-pwm for quality / adafruit-hat otherwise) rather than the old -DDISABLE_HARDWARE_PULSES compile define. The script prints the correct mapping for the chosen build.
  • Modernized: dropped Python 2; uses get_boot_config(), select_n, reconfig, run_raspi_config, prompt_reboot; isolcpus cmdline edit done in idempotent pure Python.
  • Added guidance recommending --led-slowdown-gpio=5 to avoid flicker on solid white on Pi 3/4 (harmless on the Pi 5 RP1 backend).

Testing

Hardware-tested with an Adafruit RGB Matrix HAT + two chained 16x32 panels:

  • Pi 5 (Trixie, RP1 backend): full install EXIT=0, reboot, RGBMatrix init OK: 64x16, cycled R/G/B/W/clear with no errors. isolcpus active, snd_bcm2835 blacklisted, RTC bound.
  • Pi 4 Model B (Trixie): same HAT/panels, same pip install . build, adafruit-hat-pwm, gpio_slowdown path. RGBMatrix init OK, R/G/B/W/clear, no errors.
  • A subtle flicker on solid white at gpio_slowdown=4 (Pi 4) cleared completely at gpio_slowdown=5 — hence the printed guidance.

Both test rigs reverted to baseline after testing. ruff format + ruff check clean.

Modernized 1:1 port of rgb-matrix.sh:
- Drop Python 2 handling (py2 is EOL)
- Use adafruit_shell helpers (select_n/prompt/reconfig/run_raspi_config/
  prompt_reboot) and shell.get_boot_config() for the boot config path
- Idempotent isolcpus cmdline editing in pure Python

Also bumps the pinned hzeller/rpi-rgb-led-matrix commit from
7a503494 (May 2025) to 4e326c1b (Jun 2026), the first commit with
Raspberry Pi 5 (RP1) support. The previous pin builds a register-poke
driver that cannot drive the matrix on a Pi 5.

Not yet hardware-tested.
The pinned upstream commit replaced 'make build-python' with a
scikit-build-core/Cython package, so build the bindings with
'pip install .' into the active environment. Add cmake to the apt
prerequisites (required by scikit-build-core).

Print the runtime --led-gpio-mapping matching the build choice and a
note recommending --led-slowdown-gpio=5 to avoid flicker on solid
white (worst case) on Pi 3/4; harmless on the Pi 5 RP1 backend.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds a Python-based installer (rgb-matrix.py) to replace/modernize the prior rgb-matrix.sh flow for installing and configuring hzeller/rpi-rgb-led-matrix, including Raspberry Pi 5 (RP1) support and Bookworm/Trixie-era boot/config handling.

Changes:

  • Introduces a new rgb-matrix.py installer that ports the interactive flow (quality vs convenience, optional RTC, optional CPU isolation).
  • Pins hzeller/rpi-rgb-led-matrix to a newer commit intended to support Pi 5 (RP1).
  • Switches the build/install step to pip install . (scikit-build-core/Cython-style build) and prints runtime mapping guidance.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread rgb-matrix.py
Comment on lines +170 to +175
print("Downloading prerequisites...")
# cmake is required by scikit-build-core, the build backend the upstream
# repo now uses for its Python bindings.
shell.run_command(
"apt-get install -y python3-dev python3-pillow cython3 python3-setuptools cmake"
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — added build-essential, python3-pip, and unzip to the apt prerequisites so the Cython/scikit-build pip install . and archive extraction work on a minimal image. Fixed in 854e0e1.

Comment thread rgb-matrix.py Outdated
Comment on lines +195 to +199
# Change ownership to the user who called sudo.
sudo_user = os.environ.get("SUDO_USER")
if sudo_user:
shell.run_command(f"chown -R {sudo_user}:{sudo_user} {os.getcwd()}")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — now uses the caller's actual primary GID via SUDO_GID (chown -R user:GID), falling back to just the username if it's unset, instead of assuming the group name matches the username. Fixed in 854e0e1.

Comment thread rgb-matrix.py Outdated
Comment on lines +243 to +246
print("The 'rgbmatrix' Python package is installed in:")
print(f" {sys.executable}")
print("Run your programs with that interpreter so 'import rgbmatrix' works.")
print("")

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — reworded to 'installed for this interpreter' to avoid implying sys.executable is an install directory. Fixed in 854e0e1.

Comment thread rgb-matrix.py
Comment on lines +52 to +57
"""Idempotently set the isolcpus=N token in cmdline.txt.

cmdline.txt is a single line; strip any previously-added isolcpus token
first (re-running the installer, or moving the SD card to a Pi with a
different core count), then append the new one if a core is reserved.
"""

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — updated the docstring to match the implementation: the installer manages the isolcpus= token and strips any existing entry (including user-managed ranges) before appending its own, keeping re-runs idempotent. Fixed in 854e0e1.

Comment thread rgb-matrix.py
Comment on lines +178 to +180
shell.run_command(
f"curl -L {GITUSER}/{REPO}/archive/{COMMIT}.zip -o {REPO}-{COMMIT}.zip"
)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — switched to curl -fL so a bad commit hash / GitHub 404 fails fast with a non-zero exit instead of saving an HTML page that breaks unzip downstream. Fixed in 854e0e1.

- Add build-essential, python3-pip, and unzip to apt prereqs so the
  Cython/scikit-build pip build and zip extraction work on a minimal image.
- chown with the caller's actual primary GID (SUDO_GID) instead of
  assuming the group name matches the username.
- curl -fL so a bad commit hash / 404 fails fast instead of saving an
  HTML page that later breaks unzip.
- Reword 'rgbmatrix installed in <sys.executable>' to 'installed for this
  interpreter' (it's the interpreter path, not an install dir).
- Update set_isolcpus docstring to match the actual behavior (strips any
  existing isolcpus= token, including user-managed ranges).
On Bookworm/Trixie the system python is externally managed, so
'pip install .' of the rgbmatrix bindings fails mid-install. Detect a
non-venv externally-managed interpreter up front and bail with guidance
to create/activate a venv first, instead of failing after apt + download.
Older (non-PEP-668) systems and venvs are unaffected.

Verified on test-pi (Pi 4/Trixie): system python -> bail, venv -> pass.
@makermelissa-piclaw

Copy link
Copy Markdown
Contributor Author

Independent hardware retest — test-pi (Pi 4 Model B, Debian Trixie, Adafruit RGB Matrix + RTC HAT, 64×32 panel).

Ran the full installer from this branch: HAT interface, RTC=no, Quality path, Reserve a core (isolcpus) — exercising the riskiest edits plus the review fixes.

Results — all green:

  • Build prereqs (build-essential/cmake/unzip) present, so the scikit-build/Cython build completed: Successfully installed rgbmatrix-0.0.1+20260125.
  • RGBMatrix init OK: 64x32, full R/G/B/W/clear cycle on the panel, no errors, adafruit-hat-pwm mapping at --led-slowdown-gpio=5.
  • isolcpus=3 appended cleanly to cmdline.txt (highest of 4 cores); nothing else disturbed.
  • Quality blacklist written (blacklist snd_bcm2835); pre-existing i2c-rtc overlay left untouched.
  • Rig reverted to baseline afterward.

One finding addressed in 35fa2e6: Trixie enforces PEP 668, so running the installer against the system interpreter (sudo python3 rgb-matrix.py) would make pip install . fail with externally-managed-environment mid-install. The installer now detects a non-venv externally-managed interpreter up front and bails with guidance to create/activate a venv first (older non-PEP-668 systems and venvs are unaffected). Verified on test-pi: system python → bails early, venv → proceeds.

@makermelissa makermelissa merged commit ba6af3a into adafruit:main Jun 16, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants