Files
LEDMatrix/docs
ChuckBuildsandClaude Opus 5 d56ec2ab3a feat(bench): measure a rig against the refresh it actually holds
There was no way to answer "does this hardware present every frame on
time?" other than watching the panel. `scripts/render_bench.py` drives the
production path -- a real DisplayManager and ScrollHelper, configured
through the same `scroll_config` resolver every ticker uses -- and grades
the run with a new `src.common.frame_pacing`, exiting non-zero when more
than 0.1% of frames slipped a refresh. Exit 2 when the run could not be set
up at all, so a rig that was never measured cannot pass by accident.

A missed frame is defined exactly: an interval that rounds up to at least
one more refresh than its frame hold asked for. The half-refresh rounding
boundary keeps a frame that ran 1ms long on a 10ms refresh out of the
count, because it still presented on the refresh it was meant to.

The verdict that matters more is NOT LOCKED. A loop that never blocked on
vsync reports a perfect zero misses while presenting nothing -- 8ms frames
on a 100Hz panel all land in the one-refresh bucket while running 25% too
fast -- so the report also checks the typical frame is not shorter than the
panel could physically present. That is what caught the first version of
this benchmark announcing its scrolling state once instead of per frame:
the state expires on an inactivity threshold, the dirty-tracking skip then
fires mid-scroll, and the loop free-ran at 827fps.

And the refresh is read back out of the frames rather than taken from an
idle measurement. Driving the matrix is bit-banging on the same machine, so
pushing frames slows the refresh: a Pi 4 on 512x64 measures 100.4Hz idle
and holds 96.3Hz while scrolling. Both are real, and grading against the
idle figure reports a locked loop as 4% slow -- or, once the gap passes
half a refresh, as missing every frame. The gap between the two is itself
worth watching: a rise in it is a render-cost regression even when nothing
is missed.

Measured on hdpi (Pi 4, 512x64, pwm_bits 8), two minutes each:

  plain      95.44 fps, 8 missed of 11,449 (0.070%)  PASS
  --busy 2   95.41 fps, 3 missed of 11,445 (0.026%)  PASS

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014RRtqXDCnvnY6EQwhT5CV9
2026-09-24 11:08:43 -04:00
..

LEDMatrix Documentation

This directory contains guides, references, and architectural notes for the LEDMatrix project. If you are setting up a Pi for the first time, start with the project root README — it covers hardware, OS imaging, and the one-shot installer. The pages here go deeper.

I'm a new user

  1. GETTING_STARTED.md — first-time setup walkthrough
  2. WEB_INTERFACE_GUIDE.md — using the web UI
  3. PLUGIN_STORE_GUIDE.md — installing and managing plugins
  4. WIFI_NETWORK_SETUP.md — WiFi and AP-mode setup
  5. TROUBLESHOOTING.md — common issues and fixes
  6. SSH_UNAVAILABLE_AFTER_INSTALL.md — recovering SSH after install
  7. CONFIG_DEBUGGING.md — diagnosing config problems
  8. LOW_MEMORY_BOARDS.md — Pi Zero 2 W / 3B+ / 1GB Pi 4 memory limits

I want to write a plugin

Start here:

  1. PLUGIN_DEVELOPMENT_GUIDE.md — end-to-end workflow
  2. PLUGIN_QUICK_REFERENCE.md — cheat sheet
  3. PLUGIN_API_REFERENCE.md — display, cache, and plugin-manager APIs
  4. PLUGIN_ERROR_HANDLING.md — error-handling patterns
  5. DEV_PREVIEW.md — preview plugins on your dev machine without a Pi
  6. EMULATOR_SETUP_GUIDE.md — running the matrix emulator

Going deeper:

Configuring plugins

Advanced features

Reference

Contributing to LEDMatrix itself

Audits

Contributing to the docs

  • Markdown only, professional tone, minimal emoji.
  • Prefer adding to an existing page over creating a new one. If you add a new page, link it from this index in the section it belongs to.
  • If a page becomes obsolete, delete it (it stays in the repository history) and fix the links to it; test/test_doc_links.py fails on broken relative links.
  • Keep examples runnable — paths, commands, and config keys here should match what's actually in the repo.