Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
a22659d
Add horizontal desktop printed enclosure and assembly instructions. S…
mbchars Oct 10, 2026
5c8e0be
tools: case-models builds mbchars' horizontal desktop case
claude Oct 10, 2026
646331c
web: /build's case switch and 3D preview get a fourth case, mbchars' …
claude Oct 10, 2026
dd528bc
docs: changelog for mbchars' horizontal desktop case and the fourth p…
claude Oct 10, 2026
9b64efd
Merge pull request #489 from Patternflow-lab/upstream/horizontal-desktop
engmung Oct 10, 2026
5ffe66e
Merge pull request #490 from engmung/dev
engmung Oct 10, 2026
06066c0
web: ZuperZuche's build joins the map - the first print, from Moscow
engmung Oct 10, 2026
a3bb6fa
web: the 3D preview names whose case it is, in the build map's label
engmung Oct 10, 2026
511e776
Merge pull request #491 from engmung/dev
engmung Oct 10, 2026
b1fdebf
원래 레포 engmung/Patternflow main 최신을 merge 한다
claude Oct 12, 2026
abd75e3
web: Play 01 Flash starts in download mode, assumes the Wi-Fi step wo…
claude Oct 12, 2026
10379f5
web: the build guide, the Pattern tab and the breadboard page give th…
claude Oct 12, 2026
cb129a7
docs: the README is new from its first screen: four doors, First ligh…
claude Oct 12, 2026
95895ed
docs: READMEs and docs tidied: first flash in download mode, indexes …
claude Oct 12, 2026
5cb5f95
docs: changelog for the flash chapter, /flash, the README and the doc…
claude Oct 12, 2026
9a16156
evidence for PR #7: screenshots of the Play guide's 01 Flash and the …
claude Oct 12, 2026
8f69f95
evidence for PR #7 leaves the tree (it stays at 9a16156)
claude Oct 12, 2026
a2235af
evidence for PR #7, under short names so the PR body's image links st…
claude Oct 12, 2026
bc0e4c7
evidence for PR #7 leaves the tree again (it stays at a2235af)
claude Oct 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,10 @@
## Tested
<!-- How did you check it works? (built locally, flashed the board, ran the site…) -->

## Which row
<!-- Which row of the table in CONTRIBUTING.md (https://github.com/engmung/Patternflow/blob/main/CONTRIBUTING.md#where-your-contribution-goes) this is: a guide fix, a feature, a remix… -->

---
- [ ] Touches `web/` → it builds (`npm run build`)
- [ ] Touches `firmware/` → every composition builds (`./firmware/bundles/build.sh all`), and the core still names no feature (`python firmware/toolchain/check_boundaries.py`)
- [ ] Touches a markdown file → its relative links resolve (`python3 .github/scripts/check_links.py`)
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ Patternflow is an open-source hardware instrument: four rotary encoders controll
It is standalone (not Eurorack), powered from a 5 V power bank through a screw terminal, and it is not an analog video synthesizer. Sound arrives through the Audio edition (on-board microphone, OSC, MIDI), not the default firmware.

## Repository map
- `docs/` — contracts and long-form docs: `EDITIONS.md` (the firmware seam — read it before touching firmware), `rest-api.md` / `osc-spec.md` / `midi-spec.md` / `audio-ws-spec.md` (wire contracts integrations are built against), `pfst-v2-spec.md` (show files), `panel-compatibility.md`, `RELEASING.md`, `SERVICES.md` (production server ops), the assembly map (`docs/assembly/`), the manifesto, investigations, and media (build-guide images in `docs/build-guide/`). Root-level guides: `BUILD_GUIDE.md` (the **v3.0 board**), `BUILD_GUIDE_v2.md` (legacy v2.x board), `PATTERN_GUIDE.md` (community → deck → Pattern Lab → device), `FEATURE_GUIDE.md` (writing a firmware feature or edition), `AUDIO_GUIDE.md` (sound into the panel). The live roadmap is patternflow.work/journal and the `/roadmap` page.
- `docs/` — contracts and long-form docs: `EDITIONS.md` (the firmware seam — read it before touching firmware), `rest-api.md` / `osc-spec.md` / `midi-spec.md` / `audio-ws-spec.md` (wire contracts integrations are built against), `pfst-v2-spec.md` (show files), `panel-compatibility.md`, `RELEASING.md`, `SERVICES.md` (production server ops), the assembly map (`docs/assembly/`), the manifesto, investigations, and media (build-guide images in `docs/build-guide/`). Root-level guides: `BUILD_GUIDE.md` (the **v3 board**: v3.9, and v3.0 the same way), `BUILD_GUIDE_v2.md` (legacy v2.x board), `PATTERN_GUIDE.md` (community → deck → Pattern Lab → device), `FEATURE_GUIDE.md` (writing a firmware feature or edition), `AUDIO_GUIDE.md` (sound into the panel). The live roadmap is patternflow.work/journal and the `/roadmap` page.
- `firmware/` — PlatformIO/Arduino code for the ESP32-S3. Main sketch folder: `firmware/patternflow/` with `patternflow.ino`, `config.h` (pin mappings, brightness, limits, LED calibration), `net_config.h` (Wi-Fi / Improv / OTA / self-update defaults and the lane scale — core only; a feature's own tunables live in `features/<name>/<name>_config.h`, and settings TUNE a feature, they never add one; per-device secrets in gitignored `patternflow_secrets.h`), and `pattern_registry.h` (function-pointer pattern table; compiles in Origin alone — the rest of the curated set ships as the Basics pack). Shared engine code lives in `firmware/patternflow/src/` (`core_display.h` HUB75 driver, `core_encoders.h`, canvas/color/math/noise helpers, Wi-Fi/OTA/web-console modules, the hotspot in `core_hotspot.h`) — core only: OSC, audio, MQTT, weather, shows, MIDI and the clock all live in `features/`. `firmware/patternflow/abi/` is the frozen host ⇄ module contract. Curated patterns live in `firmware/patternflow/presets/` (`preset_origin.h`, `preset_wave_saw.h`, dated presets), each using its own pattern namespace; user patterns are `.pfm` modules uploaded to the device over Wi-Fi, built from `firmware/modules/` via `firmware/toolchain/build_module.py` (the old `custom1.h`–`custom3.h` root slots are gone). Features attach through `firmware/patternflow/features/` (named `addons/` until 2026-08-30; legacy spellings are shimmed for out-of-tree bundles — see docs/EDITIONS.md) — a directory and a descriptor of function pointers, with the core naming none of them (see its README). `firmware/bundles/` names firmwares built from the same tree (the shelf editions `audio` and `performance`, plus `clock` and `midi`, compositions the tree keeps buildable but does not publish; the default build has no bundle): two files each, saying which features compile in and what the build calls itself; `firmware/bundles/build.sh` builds the default or a named one, `shelf.sh` stages a publishable image. Device console pages are plain HTML in `firmware/patternflow/console/`, spliced into `*_index.h` by `firmware/toolchain/console_pages.py`. Tooling lives in `firmware/toolchain/` (repo-level scripts) and `firmware/patternflow/toolchain/` (PlatformIO `extra_scripts`, which must stay sketch-relative). Also: `firmware/encoder_test/` (standalone encoder diagnostic) and `firmware/CUSTOM_PATTERNS.md` (pattern authoring guide).
- `hardware/` — Hardware designs. `case/` (Blender source in `source/`, STLs by printer bed size, `legacy_v2/` for the v2.x board), `pcb/` (KiCad 10.0 source, Gerbers per revision, schematic PDF), `bom/` (`bom_v3.9.csv` — **the BOM source of truth**; the guide's table is derived from it. `bom_v3.0.csv` is kept for the previous board).
- `web/` — Next.js site at patternflow.work: landing page (`/`, `/pattern`, `/build`, `/inside` are tabs of one view), the interactive guide (`/guide` is a hub over `/guide/build`, `/guide/play`, `/guide/make` and `/guide/audio`, each with a `/ko` twin; one 3D stage in `components/guide/`, the firmware simulator in `lib/guide/`), Pattern Lab (`/pattern-lab`), community (`/community/**`, SQLite + Drizzle + Better Auth, only on the Pi deployment), browser flasher (`/flash`), the edition shelf (`/editions`; `/variants` redirects there), the feature catalogue (`/features`, reels per feature), device update handoff (`/update`), journal, roadmap. `lib/pattern/` is the pattern runtime and annotations, `lib/lab/` the Pattern Lab, `lib/community/` the community, `lib/ai/` the Gemini client. Architecture doc: `web/ARCHITECTURE.md`. The JS presets in `web/src/lib/presets/` are the source of truth for firmware preset headers.
- `hardware/` — Hardware designs. `case/` (Blender source in `source/`, STLs by printer bed size, `knobs/`, `legacy_v2/` for the v2.x board, `legacy_lasercut/` for the v1/v2 acrylic drawings, and `remixes/` — community enclosures, one folder each, whose README is its license header), `pcb/` (KiCad 10.0 source, Gerbers per revision, schematic PDF), `bom/` (`bom_v3.9.csv` — **the BOM source of truth**; the guide's table is derived from it. `bom_v3.0.csv` is kept for the previous board).
- `web/` — Next.js site at patternflow.work: landing page (`/`, `/pattern`, `/build`, `/inside` are tabs of one view), the interactive guide (`/guide` is a hub over `/guide/build`, `/guide/play`, `/guide/make` and `/guide/audio`, each with a `/ko` twin; one 3D stage in `components/guide/`, the firmware simulator in `lib/guide/`), Pattern Lab (`/pattern-lab`), community (`/community/**`, SQLite + Drizzle + Better Auth, only on the Pi deployment), browser flasher (no page of its own: the **Flash Patternflow** button on `/pattern` and in the Play guide, installing `public/flash/manifest.json` and the images in `public/flash/bin/`; the bare `/flash` redirects to `/guide/play#flash`), the edition shelf (`/editions`; `/variants` redirects there), the feature catalogue (`/features`, reels per feature), device update handoff (`/update`), journal, roadmap. `lib/pattern/` is the pattern runtime and annotations, `lib/lab/` the Pattern Lab, `lib/community/` the community, `lib/ai/` the Gemini client. Architecture doc: `web/ARCHITECTURE.md`. The JS presets in `web/src/lib/presets/` are the source of truth for firmware preset headers.
- `tools/` — desktop-side helpers: `patternflow-audio-extension` (the browser audio-react extension — also the authoring source the device's `/audio-in` console page is assembled from), `patternflow-audio-android` (phone capture app), `rtpmidi-probe`, and `case-models` (builds the /build preview's per-case 3D models, `web/public/cases/<id>/model.glb`, from the case files in the repo; run by hand, not by the site build).
- `integrations/` — host-software integrations, each with its own README. `integrations/ableton/` is the Max for Live bridge (knobs → Live parameters over OSC). The Home Assistant integration left this repository on 2026-09-03; its author maintains it separately. Integrations are built against the contracts in `docs/` (`rest-api.md`, `osc-spec.md`, `midi-spec.md`), not against the firmware source. `docs/rest-api.md` also has the table for choosing between HTTP, OSC and MQTT, and the rules that make the device's single-connection web server easy to knock over.

Expand Down
6 changes: 5 additions & 1 deletion AUDIO_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ written for AI coding agents; everything above it is for people.
Any of these puts the same firmware on your panel:

- **One click:** [patternflow.work/editions](https://patternflow.work/editions)
→ Audio → flash from the browser.
→ Audio → **Install to my panel**. Your browser hands the image to a panel
that already runs Patternflow, over Wi-Fi; patterns, networks and settings
stay. A DevKit that has never run Patternflow takes the core first, from
**Flash Patternflow** ([BUILD_GUIDE §8](BUILD_GUIDE.md#8-firmware)), and
then this.
- A release's `patternflow-audio.ino.bin` via the console's `/update` page.
- Build it yourself: `./firmware/bundles/build.sh audio` (add
`flash <hostname>` to send it over Wi-Fi).
Expand Down
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,16 @@ All notable changes to Patternflow will be documented in this file, newest first

- **/build lets you pick the case, and the 3D view shows the one you pick.** The Build panel's switch (the official v3.9 case, Besoiobiy's printed case, SimonePDA's laser-cut one; `?case=` links to one) brings up that case's card, a remix's opening with its README on GitHub, and swaps the device in the preview for that case, with the same v3.9 board, DevKit and LED panel inside (and, on Besoiobiy's case, its own knob caps). SimonePDA's case comes in its two finishes, acrylic and MDF. Each model is made by `tools/case-models` from the case's own files in this repository (the guide's v3.9 case, Besoiobiy's STLs, SimonePDA's cutting layout) and sits beside the case's photos, `web/public/cases/<id>/model.glb`. The model the page loads first is 0.32 MB, where the old v3.0 one (`3dforweb.glb`, now removed) was 1.15 MB; a remix's model loads when it is picked, and the guide takes its LED panel from the official one.
- **/build has a fourth case, mbchars' horizontal desktop one, in the switch and in the 3D view.** Its card is its README's facts and the author's photos, and the switch is four tabs, two by two on a phone. `tools/case-models/mbchars.py` puts its model together from the remix's STLs, since no assembled file exists, and checks it against the README; in it the panel lies the long way (`ledTurn` in `placement.json`), the official knob is printed white (`knobLook`), and the orange is the one in the author's 3MF, `#F46B16` (`pla_orange`). The model is 0.38 MB and loads when the case is picked; the other three rebuild byte for byte. The case is 41 cm across, so on a desktop's tall view it is drawn smaller, by as little as keeps it clear of the arrows; on a phone all four cases, and on a desktop the three upright ones, are still drawn at the one scale. The build map's pin for the same build goes by the maker's name now, mbchars (it was extraplojo).
- **The 3D view on /build has arrows and a name.** On the Build tab, arrows either side of the device step through the cases, round and back to the first, as the build map's arrows step through builds; the switch, the card and `?case=` follow. Over the device is whose case it is, the name on its tab (Official, Besoiobiy, SimonePDA, mbchars), in the build map's label.
- **The preview's case is white, not beige, and the rest of it looks more like the photos.** The printed parts are a neutral white PLA (`#f4f4f2`, matte), where the guide's warm white had come along; the case front measures b\* +0.4 and L\* 89.8 where it was +1.7 and 82.5. The frame goes through the shoulder of the Neutral tone curve, which leaves what is under its knee as lit and rolls off what is brighter with its channels together, so a bright light no longer clips red and green first and leaves the white yellow. The light is made on the page from light panels, as on the guide's stage, instead of an environment map fetched from a CDN at run time. The LED panel is a grid of round LEDs on a black mask where it was solid blocks on grey (each LED becomes its whole cell once it is under about three pixels across, as on a phone), its sides and back are the panel's black frame, and what glowed before (the whites, and the bright yellows and cyans of a pattern from the editor) glows as before. The official knob is the printed knob's own profile drawn round, where it was a 32-sided prism. SimonePDA's clear acrylic is clear: the canvas is see-through, and every partly covered pixel used to reach the page far too bright, which drew the sheet frosted white; its three feet, which no photo shows on it, now come out only with the parts and on Assemble. Every case is drawn at one scale, so the LED panel is the same size in all three (the remixes drew it 3.5 to 4% smaller). The three models were rebuilt with `tools/case-models/build.sh`; the official one grows by 0.8 KB.
- **The guide's first flash starts in download mode, and its Wi-Fi assumes the step won't come.** The Play guide's 01 Flash (`/guide/play`, and `/ko`), where the Build guide sends a new DevKit, now has hold BOOT, tap RST, let go as its fourth card, before Flash Patternflow, every first flash, instead of a fallback for a missing port. The Wi-Fi card says plainly that after an install from download mode the dialog usually ends without asking, and gives the moves in order: close it, press RST once, Flash Patternflow again, the port again, Connect to Wi-Fi; its flasher screens lead with that path ("Usually: after RST"), the install-right-away case second, and it carries its own Flash Patternflow button. A new last card, after Power, is the panel's own network for when that didn't take: hold K2 for HOTSPOT and `patternflow-xxxx`, join it with the password `patternflow`, open `http://192.168.4.1/` and pick your network on the Wi-Fi page, with what to do when it isn't in the phone's list yet (it comes up about 15 seconds after power-on). The stage follows the cards, and the device simulator draws the NETWORK screen's hotspot (`setHotspot`). The Build guide's flash card, the Pattern tab's notes under Flash Patternflow and the breadboard page say the same order. Anchors `#flash-1` to `#flash-3` are where they were; `#flash-4` is now download mode.
- **`/flash` goes to the guide's Flash chapter.** It had no page, though the device's Update page ("flash it over USB at patternflow.work/flash") and every release's FLASHING.md send people there; it now redirects to `/guide/play#flash`. `/flash/manifest.json` and `/flash/bin/*` are untouched.

### Docs

- **The build pages say what is true now.** Laser cut is no longer "being prepared" on /build, in the README, the v2 guide or `llms.txt`: SimonePDA's case is it. The printing time is about 10 hours for the official case on a 256 mm bed (/build said 10–12, the breadboard guide 11), the v2 guide and the assembly map name the v3.9 board, and the breadboard guide flashes through the DevKit's native USB port from the Pattern tab and links the sections that exist.
- **The README is new from its first screen.** A one-line definition, the hero and the photosensitivity warning, then four doors (Build, Play, Make patterns, Add sound), each to its guide page with the written guide beside it, and **First light**: J4-only power, download mode first, the Wi-Fi step that usually doesn't come and what to do, the panel's own network, the Basics pack. The story, the community, the facts and the editions follow, shorter, with the long reference material folded instead of cut.
- **The READMEs and docs were tidied.** Where a doc gives the first flash (`firmware/README.md`, `PATTERN_GUIDE.md`, `SUPPORT.md`, `docs/assembly/`) it now says download mode first, that the Wi-Fi step usually doesn't appear the first time and what to do, and the hotspot. The indexes (`docs/README.md`, `docs/REPOSITORY.md`, the hardware and remix READMEs, `web/README.md`, `web/ARCHITECTURE.md`) list the guide pages, the three case remixes, `legacy_lasercut/` and the bundles that exist, and stale wording went: the NETWORK screen's old rows, the custom slots, "variant", the dead `/flash` page. `BUILD_GUIDE.md` and `BUILD_GUIDE_v2.md` are as they were.

## [3.11.0] - 2026-10-04

Expand Down
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Patternflow is a device, a firmware, a website and a pile of documentation, and
| You have… | It goes in | A change touches | What CI runs on it |
| :--- | :--- | :--- | :--- |
| A fix to a guide, a README or a spec | the markdown file itself: the root guides, `docs/`, any folder's README | one file | every relative link must resolve (`docs-links`) |
| A fix to the **interactive guide** at [patternflow.work/guide](https://patternflow.work/guide) (Build, Play, Make, Audio) | its words are TypeScript, English and Korean side by side: `web/src/components/guide/copy.ts` for Play, `web/src/components/guide/copy/` for Build, Make, Audio and the hub | the copy, both languages | `web-ci` |
| A fix to the **breadboard** build guide | `web/src/app/build/breadboard/page.tsx` — that guide is React, not markdown | JSX text | `web-ci` (`next build`) |
| Your finished build, for the [build map](https://patternflow.work/inside) | `web/src/components/sections/InsideGlobe/builds.ts` plus a photo folder `web/public/builds/<slug>/` — see [Your build](#your-build). Not a git person? The [Share your build](../../issues/new?template=share_build.yml) form does the same | one `Build` entry and its photos | `web-ci` (the typecheck rejects a malformed entry) |
| A firmware **feature** | `firmware/patternflow/features/<name>/`, plus one line in the bundle it joins (`firmware/bundles/<edition>/features_local.h`) | the folder, the bundle line, an inventory row in `features/README.md`; a console page also adds a row to `firmware/toolchain/console_pages.py`; a library also goes in `platformio.ini` | `firmware-checks` (boundary, ABI freeze, presets, console pages…) and `firmware-build` (every edition, from scratch) |
Expand Down
4 changes: 3 additions & 1 deletion FEATURE_GUIDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,9 @@ python firmware/toolchain/console_pages.py check # if you added a console page
Compiling is not testing — most historical regressions were invisible on the
build in front of whoever caused them, which is why `build.sh all` exists.
CI runs the same set ([`firmware-checks.yml`](.github/workflows/firmware-checks.yml),
[`console-sync.yml`](.github/workflows/console-sync.yml)).
[`console-sync.yml`](.github/workflows/console-sync.yml), and
[`firmware-build.yml`](.github/workflows/firmware-build.yml) for every
composition, one job each).

If the user asks for a PR against this repository: it should touch only
`features/<theirs>/` plus a bundle, pass everything above, and follow
Expand Down
Loading