Files
apress/deploy/uno-q/skills/led-matrix/SKILL.md
T
Omar SobhandClaude Opus 4.8 06f2342892 feat(uno-q): resident-responder fast-path for the LED matrix (instant, no flash)
The agent now drives the matrix in <1s via the resident responder instead of
compiling+flashing a sketch (~95s). Pieces:

- matrix-relay/: a tiny container (python-apps-base) running relay.py — a
  TCP:9999 → RouterBridge relay. The ZeroClaw daemon runs on the host for
  hardware access, but the RouterBridge python binding (arduino.app_utils)
  only ships in the App Lab image, so JUST the relay runs containerized,
  mounting the router socket + publishing :9999 to loopback.
- config.template.toml: add matrix_pattern + matrix_text to the default risk
  profile's allowed_tools/auto_approve (the capability filter hides tools not
  listed — this was why matrix_text wasn't exposed to the agent).
- skills/led-matrix: lead with "use matrix_text / matrix_pattern first"; only
  flash for custom frames (flashing overwrites the responder). NOTE skills load
  from each agent's workspace copy, not shared/skills — push to all workspaces.
- provision-host-daemon.sh: flash the responder once + start the relay.

Proven on-hardware: "show a heart" and "scroll GO CLAWS" both instant via the
agent, no flash.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-22 09:10:34 -07:00

108 lines
4.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: led-matrix
description: Drive the Arduino Uno Q's built-in 13x8 blue LED matrix — draw frames with the always-bundled Arduino_LED_Matrix frame API, or scroll text with ArduinoGraphics when it's installed. Load this whenever the user mentions the LED matrix, drawing pixels, or displaying words on the board.
---
# Uno Q Built-in LED Matrix
The Uno Q has a built-in **13 columns × 8 rows** (104-pixel) **blue** LED matrix,
driven by the STM32U585 MCU. (It is NOT an LCD, and NOT red.)
## Instant runtime control — USE THIS FIRST (no flashing)
The board runs a **resident responder sketch** that already drives the matrix, so
you can change what it shows **instantly** with these tools — no sketch, no
compile, no flash:
- **`matrix_text`** — scroll a short message. Use for ANY "scroll / show / display
/ print `<text>`" request (e.g. `text="GO CLAWS"`).
- **`matrix_pattern`** — switch to a preset animation: `off, rain, heart, wave,
sparkle, checker, solid, blink`.
**Always reach for these tools first** for text or a preset animation. They take
effect in under a second. Do **NOT** write and flash a sketch for these — flashing
takes ~90s **and overwrites the resident responder, breaking `matrix_text` /
`matrix_pattern` until it's re-flashed.** Only write + flash a sketch (below) for a
**custom** frame pattern the tools can't produce, and know it replaces the
responder.
## Prefer the frame API (always available)
`Arduino_LED_Matrix` is bundled with the `arduino:zephyr` core — **no lib install**.
The **frame API** works on every core version and is the safe default. A frame is
**four `uint32_t` words** (128 bits; the first 104 map to the pixels). `loadFrame`
displays one:
```cpp
#include "Arduino_LED_Matrix.h"
Arduino_LED_Matrix matrix;
const uint32_t FULL[4] = {0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; // all on
const uint32_t BLANK[4] = {0, 0, 0, 0}; // all off
void setup() {
matrix.begin(); // REQUIRED — without it the matrix stays dark
}
void loop() {
matrix.loadFrame(FULL);
delay(500);
matrix.loadFrame(BLANK);
delay(500);
}
```
- `matrix.loadFrame(const uint32_t[4])` — show a raw frame.
- `matrix.renderBitmap(bitmap, rows, cols)` — show an 8×13 `uint8_t` bitmap (1 = on).
- The matrix is **charlieplexed**: the MCU must keep running to refresh it. If the
sketch halts or stops driving it, the display freezes/goes dark — a *static*
pattern that never changes usually means the sketch isn't running (see `flashing`).
## Scrolling text (needs `ArduinoGraphics` — install it first)
Text scrolling needs `ArduinoGraphics`. On core 0.51.0 the matrix lib includes it
**conditionally** (`__has_include`), so it is NOT present by default — a scroll
sketch fails with `'endText'/'SCROLL_LEFT' not declared`. Install it once (needs
network), then it stays available offline:
```
arduino-cli lib install ArduinoGraphics # run with TMPDIR=/tmp on the Uno Q
```
Verified working sketch on core 0.51.0 with [email protected] (compiles to ~7.6 KB):
```cpp
#include "ArduinoGraphics.h" // MUST come before Arduino_LED_Matrix.h (defines SCROLL_LEFT)
#include "Arduino_LED_Matrix.h"
ArduinoLEDMatrix matrix; // ArduinoLEDMatrix and Arduino_LED_Matrix are aliases
void setup() {
matrix.begin();
matrix.textFont(Font_5x7); // fits the 8-row height
matrix.textScrollSpeed(80); // ms per step; lower = faster
}
void loop() {
matrix.beginText(0, 1, 0xFF, 0xFF, 0xFF); // x, y, R, G, B — the 5-arg form
matrix.print(" HELLO UNO Q "); // pad with spaces so it scrolls in and out
matrix.endText(SCROLL_LEFT);
delay(200);
}
```
If installing a library isn't an option (fully offline, no network ever), scroll a
hand-rendered font with the frame API instead: build an 8×N `uint8_t` bitmap of the
message and `renderBitmap(window, 8, 13)` a sliding 13-column window each step.
## Pitfalls
- **`ArduinoGraphics` may be absent** (core 0.51.0) — prefer the frame API; only use
the text API when the sketch is known to compile against a core that bundles it.
- Always call `matrix.begin()` in `setup()`, or the matrix stays dark.
- Include order for the text path: `ArduinoGraphics.h` **before** `Arduino_LED_Matrix.h`.
- Use the **5-argument** `beginText(x, y, R, G, B)` form; the 3-arg form is a
training-data artifact.
- It's a monochrome **blue** matrix — RGB args only set on/off, not hue.