metronome/pico-cp/README.md
Me Here d558dccbde Phase 2: editor 'Save/Load to device' + bundle the editor on the drive
Add to the editor's set-list ⋯ menu:
  - 📟 Save to device — writes the active set list as programs.json (the same file the
    PM_K-1 firmware reads). Uses the File System Access API to write straight onto the
    CIRCUITPY drive (Chrome/Edge); falls back to a download to drag on. Reuses
    setupToPatch() per item -> {title, programs:[{name, prog}]}.
  - 📥 Load from device — reads a programs.json back into a new set list (patchToSetup
    per item; reuses the existing import path).
Bundle the built editor.html into pm_k1_circuitpy.zip so the drive carries its own
offline programmer. info-kit + pico-cp/README document the workflow.

Verified: editor loads with no console errors; both menu buttons + all four functions
present; zip contains editor.html. (FSA save needs a real user gesture to test on-device.)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-28 22:20:35 -05:00

65 lines
3.9 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.

# PM_K1 "Kit" — CircuitPython edition (USB drive + editor)
The **CircuitPython** firmware for the 52Pi EP0172 Pico kit. Unlike the MicroPython version
(`../pico/main.py`), this makes the Pico mount as a **USB drive (`CIRCUITPY`)** that carries the
firmware and your tracks — so you can edit on the web and reprogram it without Thonny. It runs the
same programstring language as <https://metronome.varasys.io>.
> **Status: experimental, phase 1.** This drives the screen/touch/joystick/buzzer and reads your
> grooves from `programs.json`. The editor's oneclick "Save to device" and USBMIDI audiotocomputer
> are landing in later phases. The simpler **MicroPython** firmware (`../pico/main.py`) remains the
> rocksolid fallback — and the Pico can't be bricked (BOOTSEL → drag a MicroPython `.uf2` back).
## Install
1. **Flash CircuitPython:** hold **BOOTSEL**, plug in, and drop the CircuitPython `.uf2` for your board
onto the `RPIRP2` drive (<https://circuitpython.org/board/raspberry_pi_pico/> — or the Pico 2 / W
build). It reboots and a **`CIRCUITPY`** drive appears.
2. **Copy everything from the bundle** onto `CIRCUITPY` (draganddrop — it's a normal drive now):
- `code.py` (this firmware — runs on boot)
- `programs.json` (your grooves)
- `font_s.bin`, `font_m.bin`, `font_l.bin` (the antialiased fonts — kept as files to save RAM)
- `editor.html` (an offline copy of the web editor, so the drive carries its own programmer)
3. It starts immediately. Editing `programs.json` (or resaving it from the editor) makes CircuitPython
**autoreload** with the new tracks.
## Controls (same as the MicroPython build)
- **Touch:** onscreen `◀◀ / ▶ / ▶▶` (prev · play/stop · next) and ` / TAP / +`.
- **Joystick:** up/down = tempo, left/right = previous/next groove.
- **Button A (GP15)** play/stop · **Button B (GP14)** tap tempo.
- **RGB LED** flashes each beat; **buzzer** clicks (accent/normal/ghost).
## programs.json
```json
{ "title": "PolyMeter",
"programs": [ { "name": "Four on the floor", "prog": "t120;kick:4;snare:4=.x.x;hatClosed:4/2" } ] }
```
Each `prog` is a program string from the web editor. Add/replace entries and save — the device reloads.
**Easiest way to (re)program it:** in the editor (the web app, or the `editor.html` on the drive), build a
set list, then the setlist **⋯** menu → **📟 Save to device** → pick the `CIRCUITPY` drive. In Chrome/Edge it
writes `programs.json` straight onto the drive (the Pico autoreloads); elsewhere it downloads the file to drag
on. **📥 Load from device** reads a `programs.json` back into a new set list.
## Calibration (flip flags at the top of `code.py`)
- **Red/blue swapped:** flip `MADCTL` between `0x48` (default) and `0x40`.
- **Colours look negative:** toggle `INVERT_COLORS`.
- **Taps land wrong:** set `TOUCH_DEBUG = True`, watch the serial output, then set
`TOUCH_SWAP_XY` / `TOUCH_INVERT_X` / `TOUCH_INVERT_Y`.
- **Joystick reversed:** toggle `JOY_INVERT_X` / `JOY_INVERT_Y`.
- **LED too bright / too dim:** change `LED_BRIGHTNESS` (0..1, default 0.15).
- **Screen tearing:** the SPI panel has no tearing-effect sync; `SPI_BAUD` (default 62.5 MHz) is pushed fast
to minimise it — lower it only if the display is unstable.
- **Screen blank / garbled:** the panel lot may differ; drop `SPI_BAUD`, and if it's a 240×320 ILI9341
instead of the 320×480 ST7796, the init/size need changing (this targets the 320×480 you have).
- **RGB LED** is driven by the core `neopixel_write` module — no library to install. If it stays dark,
your CircuitPython build is unusually missing that module (everything else still works).
If `code.py` ever errors, CircuitPython prints the traceback **on the screen and over USB serial**
copy that to me and I'll fix it.
The fonts are the same baked antialiased blobs as the MicroPython build (see `../pico/gen_font.py`).