Repository navigation
Light a HUB75 panel's last row as long as every other - #211
Conversation
Two chained 64x64 panels showed a line along the seam between the halves and along the bottom edge: brighter than its neighbors below half gray, nearly dark just above it, invisible on white. Each half-panel's last row now holds its color the way every other row does. **Light domain** - Hub75Slots.h: row 0's words light the last row of the plane before, still in the latch, so they take that plane's lit window, and plane 0's take the top plane's, the one the buffer wraps from. They took the window of the plane being clocked in, so the last row of each half weighed its lower bits double and its top bit at the shortest window. The `@technical` section says why the window follows the latched data. **Tests** - unit_Hub75Slots: every row of a value is lit as long as every other, the last row of each half included, read as the panel sees it (a row lights what the row before it latched); it fails against the old window. litWords and the output-enable test measure the row that lights a plane's data rather than the row that clocks it in. - moonlive_ir_golden.inc: ramp.mle's IR hash, captured with MM_PRINT_IR_GOLDEN=1. - test_desktop --module Hub75Driver: 21 passed. --module MoonLive: 394 passed. **Docs/CI** - moonlive/effects/basics/ramp.mle: a gray ramp, the same on every row, the test pattern that shows a row driven wrong; script_catalog.h regenerated with its entry. - docs/work/present/atlas/example-hub75-seam-row.md: how the cause was found from the report, with the session's transcript to the test pattern.
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the
|
There was a problem hiding this comment.
🟢 Approval recommended
No active review issues remain to block approval.
No open issues 🎉
What changed in this PR
Corrects HUB75 output-enable timing so the last scan row receives the same bit-plane weighting as other rows, addressing seam and bottom-edge brightness artifacts on directly driven panels.
Changes:
- Uses the latched plane’s lighting window at row and frame boundaries.
- Adds a row-brightness regression test and a registered grayscale ramp effect.
- Documents the diagnosis, bench results, and MoonAtlas investigation.
| File | Description |
|---|---|
test/unit/light/unit_Hub75Slots.cpp |
Tests equal row lighting and updates timing helpers. |
test/unit/light/moonlive_ir_golden.inc |
Adds the ramp effect’s compiler golden hash. |
src/light/drivers/Hub75Slots.h |
Aligns lighting duration with the latched bit plane. |
src/core/moonlive/script_catalog.h |
Registers the ramp effect and updates catalog counts. |
moonlive/effects/basics/ramp.mle |
Adds a grayscale ramp identical on every row. |
docs/work/present/atlas/example-hub75-seam-row.md |
Records the investigation and hardware verification. |
Review effort: Balanced
check_docgen failed MoonModules#211: the new test's two-line comment is a hard wrap, and three lines ran past the length limits. **Light domain** - Hub75Slots.h: the paragraph on the lit window splits in two, each within a doc line's 250 characters, and the encoder's brief keeps its earlier wording. **Tests** - unit_Hub75Slots: the new test's comments, one line each, within a comment line's 250 characters. - check_docgen: 0 errors, every count at or below the committed one.
The example cites the encoder and its test by line, and the fix moved those lines: the page now says its line numbers are the code before the fix. **Docs/CI** - docs/work/present/atlas/example-hub75-seam-row.md: one clause in the intro.
…r's comment says what is **Light domain** - Hub75Slots.h: the paragraph on the lit window's earlier behavior goes; git holds it. **Docs/CI** - docs/work/present/atlas/example-hub75-seam-row.md removed: it needs the MoonAtlas branch, which is not upstream. - docgen.json: warnings 2050 → 2038. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Thanks James, merged. This is a clean find. The encoder had the right idea, that the latch lags the data by one row, but gave row 0 the wrong plane's timing, and white hid it. The test that reads the frame the way the panel does now pins it for every value, not only 255. I added one commit on your branch before merging:
Looking forward to more! |
What it changes, and why
Two chained 64x64 HUB75 panels on a MatrixPortal S3 showed a line along the seam between the panel halves and along the bottom edge: brighter than its neighbors below half gray, nearly dark just above it, invisible on white. It may be the "line across HUB75 panels" mentioned on Discord, for panels driven straight from the board's pins.
The cause is in
hub75Encode(Hub75Slots.h). A panel lights what the previous row latched, so row 0's words light the last row of the plane before. Those words took the lit window of the plane being clocked in, so the last scan row of each half weighed its lower bits double and its top bit at the shortest window. The fix gives row 0's words the window of the plane its latched data came from, and the top plane's for plane 0, where the buffer wraps.On a directly driven panel the affected rows were the last row of every scan block: 31 and 63 at 1/32 scan, 15, 31, 47 and 63 on a 64-row 1/16 panel. Panels behind a ColorLight receiving card are unaffected; the card does its own scanning.
Also in this PR:
moonlive/effects/basics/ramp.mle: a gray ramp, the same on every row. Any row that differs from its neighbors is a drive fault, so it is a quick test pattern for any panel, loaded as a script with no firmware build.docs/work/present/atlas/example-hub75-seam-row.md: how the cause was found from the report, the bench results, and the session's transcript. It shows the MoonAtlas query tool from my fork'smoonatlasbranch, which is not upstream yet; I am happy to drop the file here if you would rather see it with that branch.What an agent wrote
Claude (Opus) traced the cause from the report, wrote the fix, the test, the ramp script and the doc, and I reviewed each line. The diagnosis and the fix were confirmed on my panels before committing.
What you tested, and on which hardware
test_desktop --module Hub75Driver, 21 passed, including a new test that reads the encoded frame as the panel does and requires every row of a value to be lit equally. It fails against the old encoder: rows 31 and 63 light 123 words where every other row lights 62.test_desktop --module MoonLive, 394 passed, withramp.mle's IR golden hash added.ramp.mlerunning: a dark segment on the seam row, and with the camera out of sync with the panel, bright lines on rows 31 and 63. After the fix, flashed over the air through MoonBase: no line at the seam or the bottom edge across the whole ramp.