Files
apress/deploy/uno-q/sketches/README.md
T
Omar SobhandClaude Opus 4.8 a2ccf519d4 feat(uno-q): flash-sketch helper + matrix_rain as the board boot default
- flash-sketch.sh: compile + flash a sketch dir onto a board's MCU over adb
  (push → arduino-cli compile with TMPDIR=/tmp → arduino-flash @ 0x80F0000).
  Defaults to sketches/matrix_rain; includes a fleet loop over adb devices.
  DRYs up the recipe and makes "set the board default" one command.
- Designate matrix_rain as the boot animation boards ship with (the flashed
  MCU sketch persists across power cycles). Documented in the sketches README
  + parent Files list.

Flashed matrix_rain to the board via the helper (821 bytes, verified E2E).

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-07-08 15:40:40 -07:00

2.8 KiB
Raw Blame History

Uno Q LED-matrix sketches

Animations for the Arduino Uno Q's built-in 13×8 monochrome blue LED matrix (104 pixels on the STM32U585 MCU). The LEDs are physically blue and on/off only — there is no colour or brightness control in software.

Sketch What it does
matrix_rain/ Digital "rain" — per-column drops (head + short trail) at staggered speeds. The board default (boot animation).
matrix_effects/ Sampler that cycles rain → knight-rider → comet → ripple → bloom → breathe → sparkle → checker → wipe.

The board default (boot animation)

matrix_rain is the designated default a board shows on boot. The flashed sketch lives in MCU flash and runs on every power-up, so setting the default is just flashing it. Attendees overwrite it when they flash their own sketch during the workshop; re-run flash-sketch.sh to restore it afterward.

../flash-sketch.sh <adb-serial>                 # flashes matrix_rain (the default)
../flash-sketch.sh <adb-serial> matrix_effects  # or any sketch dir
# restore the default on every connected board:
for s in $(adb devices | awk 'NR>1 && $2=="device"{print $1}'); do ../flash-sketch.sh "$s"; done

How they work

The matrix API is intentionally tiny: matrix.begin() and matrix.loadFrame(const uint32_t frame[4]). There is no drawFrame, setPixel, clear, etc. — those don't exist on this core and won't compile.

So each frame is built in an 8×13 boolean grid, then packed into the uint32_t[4] (128 bits; 104 used) the driver wants — row-major, MSB-first, so pixel 0 is frame[0] bit 31:

uint16_t bit = 0;
for (uint8_t y = 0; y < 8; y++)
  for (uint8_t x = 0; x < 13; x++) {
    if (grid[y][x]) frame[bit >> 5] |= (1UL << (31 - (bit & 31)));
    bit++;
  }
matrix.loadFrame(frame);

To make a new effect, just fill grid differently each frame and call show().

Compile & flash (on the board, over adb)

S=<adb-serial>
adb -s $S push matrix_effects /home/arduino/sketches/
# TMPDIR override dodges the adb shell's /data/local/tmp (breaks arduino-cli)
adb -s $S shell 'cd /home/arduino/sketches/matrix_effects && \
  TMPDIR=/tmp arduino-cli compile --fqbn arduino:zephyr:unoq --export-binaries .'
adb -s $S shell 'arduino-flash /home/arduino/sketches/matrix_effects/build/arduino.zephyr.unoq/*.elf-zsk.bin'

arduino-flash runs OpenOCD (linuxgpiod SWD) and writes the sketch at 0x80F0000 — the address in the board's boards.txt (unoq.upload.address) for arduino:zephyr 0.51.0. (Older QClaw docs cite 0x8100000; that's stale for this core — trust boards.txt.) The flash ends with a reset, so the sketch runs immediately. Nothing may be visible for the first ~2030 s after a cold power-on while the boot logo owns the matrix.