Skip to content

3.0.0

Latest

Choose a tag to compare

@github-actions github-actions released this 24 Jul 14:33

projectMM v3.0.0

The biggest release since 1.0 — 164 commits across ~10 PRs. Highlights: the parallel-LED drivers consolidate into one runtime-peripheral module; a streaming shift-ring drives 12,288 lights (48×256) on a single S3; Home Assistant MQTT discovery; a live on-device scripting engine (MoonLive); a new ESP32-S31 board with 1 Gb Ethernet; Philips Hue output; a migrated library of 20+ effects and 60 palettes; a multicore render/encode split; and a ground-up robustness pass proven with live-hardware scenario tests.

If you like projectMM, give it a ⭐️, fork it, or open an issue or pull request. It helps the project grow, improve, and get noticed.

🔬 How it's built

Every feature follows projectMM's Industry standards, our own code principle: spec the behaviour from primary sources (the ESP32 / peripheral datasheets, the WS2812 timing spec, reference DSP), reach for the textbook algorithm and the textbook name (a DC-blocker high-pass, a Hann window, an in-order completion FIFO, a bit-transpose), pin it with unit + scenario tests first, then write every line fresh against our own architecture, crediting the prior art by name. New this release: many features were verified with live-hardware scenario tests — the same scripts drive real boards over HTTP and leave each bench board exactly as they found it.

✨ Highlights

One "Parallel LED" driver, three DMA peripherals

  • MultiPinLedDriver, MoonLedDriver, and ParlioLedDriver merge into a single ParallelLedDriver whose peripheral control picks the DMA backend — i80, MoonI80, or Parlio. The add-module picker shows one card on every board; the dropdown offers only what the chip supports (i80 on S3/P4/S31/classic, MoonI80 on the LCD_CAM chips, Parlio on the P4). Switching the peripheral is live — no reboot (ADR-0016).
  • A one-driver-per-hardware-block guard, stable board-portable option labels, and clean per-chip capability filtering.

The MoonI80 streaming shift-ring — 12,288 lights on one chip

  • MoonI80 is our own GDMA driver below esp_lcd. Its streaming ring feeds a small pool of internal buffers refilled behind the DMA read head, so strand length stops being a memory question — the whole frame never has to fit RAM. A full 48×256 = 12,288-light wall renders clean on a single ESP32-S3.
  • A 74HCT595 pin expander fans one GPIO out to 8 strands (6 pins → 48 strands). Auto-derived ring geometry (or expert ring* controls), a validated viability rule, and a clock-oracle lapping refill for very long strands.

Home Assistant & smart-home

  • MQTT Discovery (JSON schema) with LWT availability — projectMM appears in Home Assistant automatically, including an update entity (a badge when a newer release is out). Homebridge control and Ethernet opt-in alongside.

MoonLive — live on-device scripting

  • Write an effect as a small script that compiles to native code on the device and renders each tick; edit the source live and it recompiles without a reboot, with @control-declared sliders bound to real controls. Runs on three instruction sets (Xtensa S3, RISC-V P4/S31, and the desktop) — a broken script fails safe (renders dark, shows the error) rather than crashing.

New platform — ESP32-S31

  • A new board variant: 1 Gb RGMII Ethernet, on-board mic + I²C scan, RISC-V dual-core. Builds, publishes to the web installer + releases, and offers all three LED peripherals.

Effects, modifiers, layouts & palettes

  • A migrated MoonLight effect library (20+ effects) plus faithfully-migrated E_MoonModules effects, 60 palettes, and a demo-reel showcase. New: Wave, GridBlacks (a spacer layout with mid-strand dark gaps), Region and the earlier modifiers, text/font primitives.
  • A reusable LightPresets library — build a channel-role wiring (RGB / GRBW / moving-head layouts) once, reference it by name from many drivers.

Output & performance

  • Philips Hue output (HueDriver) — drive Hue bulbs from the pipeline, with room/light filtering.
  • Classic ESP32 i80 driver over the I2S peripheral; 16-lane parallel output; an async double-buffer that hides the WS2812 wire time behind DMA; a SWAR bit-transpose encoder.
  • A multicore render↔encode split — the LED encode / packet build runs on core 1 while core 0 renders the next frame, so a frame costs max(render, output) instead of the sum. Degrades cleanly to single-core when memory is tight.
  • Diff-on-the-wire state push — only changed control values go over the WebSocket, fixing a 1 Hz LED stutter from re-serialising unchanging data.

Robustness — any input, no crash, no reboot

  • A running device tolerates any add / remove / replace / reorder of modules in any order. Fixed this release: a module replace on a split-render device (use-after-free), a live peripheral swap freeing a buffer the encode worker reads, a driver destroyed while the worker was inside it (vptr race), a reordered code-wired child losing its persisted state, a preset name with a quote wiping the custom-preset library on reboot, an out-of-memory preset restore, and the MoonI80 whole-frame double-buffer freeze (it now runs single-buffer; the ring is its scale path).
  • Audio is now one mode control (Local / Receive network / Simulate); a Local-mode mic status no longer lingers after switching modes.

Toolchain, tooling & docs

  • ESP-IDF pinned to v6.1-beta1. Windows ESP32 builds fixed end-to-end; the whole tree builds clean under GCC with a sanitizer (ASan/TSan) gate. A ScratchBuffer<T> primitive for the memory-holding effects.
  • MoonDeck (the dev/bench toolkit, renamed from scripts/) with live output, and a MkDocs documentation site. Per-module generated docs, and a live-scenario harness that drives peripheral switches on real hardware.

⚠️ Breaking change — action on upgrade

A field device carrying a pre-consolidation MultiPinLedDriver, MoonLedDriver, or ParlioLedDriver persisted type will drop that driver on boot (the old type no longer resolves). Re-add a "Parallel LED" driver and pick the peripheral your board uses, then re-enter its pins. The web installer's board catalog already names the new type, so a fresh install or catalog re-inject wires it correctly. Full details + the other renamed controls: MIGRATING.md.

📦 Install

Flash from your browser — pick your board, flash the matching firmware, hand over WiFi via Improv: the web installer. Step-by-step in the Getting started guide. Desktop builds (macOS arm64 / Windows x64) and per-variant firmware binaries are attached below.

Supported targets this release: ESP32 (classic / Olimex / WROVER), ESP32-S3, ESP32-P4, ESP32-S31 (new), plus macOS arm64 / Windows x64 desktop.