metronome/pico-explorer/README.md
Me Here 3192f3debc PM_X-1 0.0.1: Pimoroni Explorer sibling firmware + Kit 0.0.23 device-id reply
Adds pico-explorer/ as a parallel CircuitPython firmware target alongside the 52Pi
Kit in pico-cp/. Same engine, same program-string grammar, same programs.json, same
live-sync protocol. Read-only on the device (no on-device beat editing); the web
editor's Live sync mirrors all edits in real time and the Explorer emits its own
play/stop/bpm/sel deltas back.

Hardware (Pimoroni Explorer PIM744):
- RP2350B + 2.8" ST7789V 320x240 LCD (8-bit parallel; CircuitPython's official
  board definition pre-builds the BusDisplay so we just use board.DISPLAY).
- 6 user buttons - A/B/C on the left of the screen, X/Y/Z on the right.
- Piezo speaker on GP12 (PWM) with amp enable on GP13.
- I2C QwSTEMMA on GP20/21 - reserved, unused by the firmware.
- No touchscreen, no joystick, no RGB LED. Run state shows on a tiny on-screen dot.

Buttons:
- A = play/stop. B = tap tempo. C = menu.
- X = prev track (hold-repeat). Z = next track (hold-repeat).
- Y = tempo -1 (hold-repeat; -5 after 1.5s).
- X+Z chord = tempo +1 (mirrors Y).
- In a menu: X/Z move the row cursor, Y decrements, A cycles/increments/selects,
  B = back, C = close.

Files added:
- pico-explorer/{boot.py, code.py, app.py, programs.json, README.md}.
  app.py = 1444 lines (~73KB source -> 29.8KB compiled .mpy).
- info-explorer.html.

Files touched:
- pico-cp/app.py: bump to 0.0.23. Version-query (SysEx 0x02 -> 0x03) reply now
  includes the device id as "K;<version>" (backward-compat: editor parses
  "contains ';'?" - old firmware sent bare version, treated as K).
- editor.html + editor-beta.html: _parseDeviceReply() splits id;version, FW_PATHS
  maps id to .py/.mpy URL pair, so Update firmware now pushes the right binary.
- build.sh + deploy.sh: precompile pico-explorer/app.py -> dist/explorer-app.mpy,
  zip pm_x1_circuitpy.zip alongside pm_k1_circuitpy.zip, ship
  pico-explorer-app.{py,mpy} next to pico-cp-app.{py,mpy}.
- docs/livesync-protocol.md: new section 7 - per-device emit/apply matrix.

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

74 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_X-1 "Explorer" — CircuitPython edition (Pimoroni Explorer · RP2350)
The **CircuitPython** firmware for the [Pimoroni Explorer Kit (PIM744)](https://shop.pimoroni.com/products/explorer),
set up as a self-contained appliance. Sibling to the PM_K-1 build in `../pico-cp/` (the 52Pi EP-0172
kit) — same engine, same program strings, same `programs.json`, same web editor.
This board is a **2.8″ ST7789V 320×240 LCD + 6 user buttons (A/B/C on the left, X/Y/Z on the right)
+ piezo speaker** built around an RP2350B (Pico 2 class chip). **No touchscreen, no joystick, no
RGB LED.** Editing is done in the web editor with **Live sync** on; the device mirrors changes in
real time and emits its own play/stop/bpm/sel deltas back.
## Controls
| Button | Action |
| ------ | --------------------------------------------------------------------- |
| **A** | play / stop |
| **B** | tap tempo |
| **C** | menu (Settings / Help / About / Practice log) |
| **X** | prev track (hold to repeat) |
| **Y** | tempo 1 (hold to repeat; after ~1.5 s the step grows to 5) |
| **Z** | next track (hold to repeat) |
| **X + Z** | tempo +1 (chord; same hold-repeat as Y) |
In a menu: **X / Z** move the cursor up / down, **Y** decrements the focused value, **A** commits or
cycles, **B** = back, **C** = close.
## Install
1. **Flash CircuitPython for Pico 2 / RP2350.** Hold **BOOTSEL** on the Explorer, plug it in over
USB-C, drop the [Pimoroni Explorer (RP2350) CircuitPython `.uf2`](https://circuitpython.org/board/pimoroni_explorer2350/)
onto the `RP2350` drive. A `CIRCUITPY` drive appears.
2. **Copy the bundle onto `CIRCUITPY`**`boot.py`, `code.py`, **`app.mpy`**, `programs.json`,
`font_s.bin` / `font_m.bin` / `font_l.bin`, `logo.bin` / `midi.bin` / `usb.bin`, `editor.html`
(offline editor). If an old `app.py` is on the drive, delete it.
3. **Power-cycle.** It boots into appliance mode and runs.
## Program it from the web
Open <https://metronome.varasys.io> in Chrome / Edge / Firefox. The set-list **⋯** menu →
**📟 Save to device** pushes a `programs.json` over USB-MIDI; the device persists it and reloads.
Click **🔗 Live sync** to mirror edits in real time.
## Pin reference
The display, buttons, and audio are wired into the board — no jumpers required. CircuitPython's
official board definition for `pimoroni_explorer2350` exposes `board.DISPLAY` pre-initialized, so
the firmware just uses it.
| Function | GPIO |
| ----------------- | -------- |
| Button A | GP16 |
| Button B | GP15 |
| Button C | GP14 |
| Button X | GP17 |
| Button Y | GP18 |
| Button Z | GP19 |
| Piezo audio (PWM) | GP12 |
| Piezo amp enable | GP13 |
| I²C SDA (QwSTEMMA) | GP20 |
| I²C SCL (QwSTEMMA) | GP21 |
| Display | `board.DISPLAY` (8080 parallel bus on GP26..GP39, initialized by board.c) |
## Calibration (flags at the top of `app.py`)
- **Speaker too loud / quiet:** the piezo + amp gain is fixed in hardware. `MUTE_SPEAKER`
silences the click; `SPEAKER_AUTO_MUTE` auto-mutes when a MIDI host is listening.
- **Buttons feel inverted:** the polarity is hard-coded to active-low (pull-up). If a button
fires on release instead of press, check the `BTN_*` pin map at the top of `app.py`.
- **Display orientation:** the board's CircuitPython init mounts the panel landscape
(320 × 240). If your screen looks rotated, that's a board.c-level thing — file a CircuitPython
bug, don't patch the firmware.
If `app.py` ever errors, CircuitPython prints the traceback **on the screen and over USB serial**
send me that.