Firmware (pico-cp/): the Pico now owns its filesystem by default (boot.py), so it can save the
practice log and write editor-pushed set lists; the drive is read-only to the computer, which also
protects the firmware. Hold button A at power-on for editor mode (drive writable; universal drag).
- Replaced the on-screen touch buttons with an on-device PRACTICE LOG (time · BPM · duration ·
track), newest-first, persisted to /history.json next to programs.json. Plays < 5s aren't logged;
tap a row twice to delete it. Real timestamps once the editor syncs the clock.
- USB-MIDI SysEx receiver: clock-set (0x01 -> RTC) and program-push (0x10 -> write programs.json,
reload, ACK/NAK). disable autoreload so our own writes never self-restart.
- Fixed swing: the parser was discarding the 's' flag, so /2s never swung. Now the scheduler uses a
per-step duration with long-short (2:1, SWING_RATIO 2/3) pairs on even subdivisions, matching the
web engine. Verified: ride:4/2s -> 266/133ms vs straight 200/200.
Editor (editor.html): requestMIDIAccess({sysex:true}); Save to device now pushes programs.json as
SysEx to the device (+ clock sync), waits for ACK, shows "Saved ✓", and falls back to downloading the
file (drag onto the drive in editor mode) when no device answers. Heartbeat also keeps the clock synced.
Web MIDI works in Chromium AND Firefox; the drag fallback covers any browser/OS incl. Safari.
Docs (pico-cp/README, info-kit, README) updated for the two modes, push programming, and the log.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
172 lines
11 KiB
HTML
172 lines
11 KiB
HTML
<!DOCTYPE html>
|
||
<html lang="en">
|
||
<head>
|
||
<meta charset="UTF-8" />
|
||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||
<title>VARASYS PM_K‑1 Kit — wiring, parts & firmware (Raspberry Pi Pico build)</title>
|
||
<meta name="description" content="PM_K‑1 Kit — build a touchscreen polymeter metronome from a Raspberry Pi Pico on the 52Pi EP‑0172 breadboard kit (3.5in ST7796 cap‑touch, joystick, RGB, buzzer). Pinout, parts list, and the MicroPython firmware to flash." />
|
||
<link rel="icon" type="image/svg+xml" href="data:image/svg+xml;base64,@BUILD:favicon@">
|
||
<script>
|
||
(function(){ try{ var p = localStorage.getItem("metronome.theme");
|
||
if (p!=="light" && p!=="dark" && p!=="system") p = "system";
|
||
document.documentElement.dataset.theme = p==="system" ? (matchMedia("(prefers-color-scheme: light)").matches ? "light" : "dark") : p;
|
||
} catch(e){ document.documentElement.dataset.theme = "dark"; } })();
|
||
</script>
|
||
<style>
|
||
/*@BUILD:include:src/base.css@*/
|
||
:root{ --bg1:#12151c; --bg2:#05070a; --txt:#c7d0db; --muted:#7f8b9a; --link:#6cb6ff;
|
||
--panel-bg:#161b22; --panel-bd:#2a313c; --field-bg:#0e1116; --field-bd:#2a313c; --silk:#aab2bc; }
|
||
:root[data-theme="light"]{ --bg1:#f5f8fc; --bg2:#dde4ec; --txt:#1e2630; --muted:#5c6776; --link:#1769c4;
|
||
--panel-bg:#ffffff; --panel-bd:#d2dae4; --field-bg:#f1f4f8; --field-bd:#d2dae4; }
|
||
body{ margin:0; min-height:100vh; padding:22px 16px 56px; color:var(--txt);
|
||
background:radial-gradient(circle at 50% -8%, var(--bg1), var(--bg2)); }
|
||
a{ color:var(--link); }
|
||
main{ width:100%; max-width:980px; margin:0 auto; }
|
||
.info-hero{ text-align:center; padding:16px 8px 2px; }
|
||
.info-hero h1{ font-size:clamp(24px,5vw,36px); margin:0; letter-spacing:-.01em; }
|
||
.info-hero .sub{ margin:9px auto 0; max-width:64ch; font-size:14.5px; }
|
||
.steps{ width:100%; max-width:760px; margin:8px auto 0; color:var(--muted); font-size:14px; line-height:1.6; }
|
||
.steps li{ margin:5px 0; }
|
||
.steps code, .about code, .sub code { background:var(--field-bg); border:1px solid var(--field-bd); border-radius:5px; padding:1px 5px; font-size:12.5px; }
|
||
.dl{ display:inline-flex; align-items:center; gap:7px; margin:4px 10px 4px 0; padding:9px 14px; border-radius:10px;
|
||
background:linear-gradient(180deg,#34c6ff,var(--cyan)); color:#04121b; font-weight:700; text-decoration:none; font-size:13.5px; }
|
||
.dl.alt{ background:var(--field-bg); color:var(--txt); border:1px solid var(--field-bd); font-weight:600; }
|
||
</style>
|
||
</head>
|
||
<body>
|
||
|
||
/*@BUILD:include:src/header.html@*/
|
||
|
||
<main>
|
||
<section class="info-hero">
|
||
<h1>PM_K‑1 Kit</h1>
|
||
<p class="sub">Build it yourself: a Raspberry Pi Pico on the 52Pi breadboard kit becomes a touchscreen polymeter metronome — same engine, same program strings, with MicroPython firmware you flash in two minutes.</p>
|
||
</section>
|
||
|
||
/*@BUILD:include:src/infoembed.html@*/
|
||
|
||
<section class="about">
|
||
<h2>What it is</h2>
|
||
<div class="ff-tags"><span class="hw">Buildable now</span><span>Raspberry Pi Pico</span><span>52Pi EP‑0172 kit</span><span>~$45 incl. Pico</span></div>
|
||
<p>This is the first member of the family you can actually build today from off‑the‑shelf parts: a
|
||
<b>Raspberry Pi Pico</b> seated on the <b>52Pi EP‑0172 "Pico Breadboard Kit Plus"</b>, which carries a
|
||
3.5″ <b>ST7796</b> 320×480 capacitive‑touch screen (<b>GT911</b>), a PSP <b>joystick</b>, a <b>WS2812 RGB</b>
|
||
LED, a <b>buzzer</b> and two buttons — all pre‑wired, so you don't solder anything; you just seat the Pico
|
||
and copy one file onto it.</p>
|
||
<p>It runs the same <b>polymeter engine</b> and the same <b>program strings</b> as the web editor: design a
|
||
groove on the site, copy its program string into the firmware's <code>PROGRAMS</code> list, and it plays on
|
||
the device. Tap the screen, nudge tempo with the joystick; the RGB flashes each beat (amber accent / cyan
|
||
normal / violet ghost) and the buzzer clicks. Powered over the Pico's USB.</p>
|
||
</section>
|
||
|
||
<details class="spec" open>
|
||
<summary>Wiring — the EP‑0172 fixed pinout (Raspberry Pi Pico)</summary>
|
||
<div class="spec-body">
|
||
<p class="sub">Everything is wired on the board; this is just what the firmware drives. No breadboarding required.</p>
|
||
<table class="bom">
|
||
<thead><tr><th>Component</th><th>Raspberry Pi Pico pins</th></tr></thead>
|
||
<tbody>
|
||
<tr class="grp"><td colspan="2">Display — 3.5″ ST7796, 320×480 (SPI0)</td></tr>
|
||
<tr><td class="part">SCK / MOSI</td><td>GP2 / GP3</td></tr>
|
||
<tr><td class="part">CS / DC / RST</td><td>GP5 / GP6 / GP7</td></tr>
|
||
<tr class="grp"><td colspan="2">Touch — GT911 capacitive (I2C0)</td></tr>
|
||
<tr><td class="part">SDA / SCL <span class="spec">— addr 0x5D</span></td><td>GP8 / GP9</td></tr>
|
||
<tr class="grp"><td colspan="2">Controls & feedback</td></tr>
|
||
<tr><td class="part">PSP joystick X / Y</td><td>ADC0 (GP26) / ADC1 (GP27)</td></tr>
|
||
<tr><td class="part">Button A (play/stop) / Button B (tap)</td><td>GP15 / GP14</td></tr>
|
||
<tr><td class="part">WS2812 RGB LED</td><td>GP12</td></tr>
|
||
<tr><td class="part">Buzzer</td><td>GP13</td></tr>
|
||
</tbody>
|
||
</table>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="spec" open>
|
||
<summary>Parts</summary>
|
||
<div class="spec-body">
|
||
<p class="sub">An off‑the‑shelf kit, not a custom board — ballpark one‑off prices (USD).</p>
|
||
<table class="bom">
|
||
<thead><tr><th>Part</th><th class="q">Qty</th><th class="c">~$</th></tr></thead>
|
||
<tbody>
|
||
<tr><td class="part">Raspberry Pi Pico (or Pico W / Pico 2) <span class="spec">— the brain</span></td><td class="q">1</td><td class="c">5</td></tr>
|
||
<tr><td class="part">52Pi EP‑0172 "Pico Breadboard Kit Plus" <span class="spec">— 3.5″ ST7796 cap‑touch, GT911, PSP joystick, WS2812 RGB, buzzer, 2 buttons, breadboard, acrylic panel</span></td><td class="q">1</td><td class="c">38</td></tr>
|
||
<tr><td class="part">USB cable <span class="spec">— power + flashing</span></td><td class="q">1</td><td class="c">2</td></tr>
|
||
<tr class="total"><td>Total (one‑off)</td><td class="q"></td><td class="c">≈ $45</td></tr>
|
||
</tbody>
|
||
</table>
|
||
<p class="sub" style="margin-top:10px">Reference: <a href="https://wiki.52pi.com/index.php?title=EP-0172" target="_blank" rel="noopener">52Pi EP‑0172 wiki</a>
|
||
· <a href="https://github.com/geeekpi/pico_breakboard_kit" target="_blank" rel="noopener">vendor code</a>. Lots may ship the screen as ST7796 (320×480) — this build targets that.</p>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="spec" open>
|
||
<summary>Firmware — flash it in two minutes</summary>
|
||
<div class="spec-body">
|
||
<p>
|
||
<a class="dl" href="/pico-main.py" download="main.py">Download main.py ↓</a>
|
||
<a class="dl alt" href="https://codeberg.org/VARASYS/metronome/src/branch/main/pico" target="_blank" rel="noopener">Source + README ↗</a>
|
||
</p>
|
||
<p class="sub"><b>Two separate steps</b> — and <b><code>main.py</code> is not a drag‑and‑drop file.</b> The
|
||
<code>RPI‑RP2</code> drive only accepts a <code>.uf2</code> firmware file; a <code>.py</code> copied there is
|
||
discarded on reboot. You drag‑and‑drop the firmware once, then copy <code>main.py</code> over USB serial.</p>
|
||
<ol class="steps">
|
||
<li><b>Install MicroPython</b> (drag‑and‑drop, one time): hold <b>BOOTSEL</b>, plug the Pico into USB, and drop
|
||
the MicroPython <code>.uf2</code> onto the <code>RPI‑RP2</code> drive
|
||
(<a href="https://micropython.org/download/RPI_PICO/" target="_blank" rel="noopener">Pico</a> /
|
||
<a href="https://micropython.org/download/RPI_PICO2/" target="_blank" rel="noopener">Pico 2</a>). It reboots
|
||
on its own and the drive disappears — that's correct.</li>
|
||
<li><b>Copy <code>main.py</code></b> (the Pico is no longer a USB drive, so use a serial tool):
|
||
in <a href="https://thonny.org" target="_blank" rel="noopener">Thonny</a> pick the interpreter
|
||
<i>MicroPython (Raspberry Pi Pico)</i>, then <i>File ▸ Save as ▸ Raspberry Pi Pico</i> as <code>main.py</code>;
|
||
or <code>mpremote cp main.py :main.py</code>.</li>
|
||
<li>Reset — it boots straight into the metronome.</li>
|
||
<li>Add your own grooves by pasting program strings from the editor into the <code>PROGRAMS</code> list at the
|
||
top of <code>main.py</code>. If colours, touch, or the joystick look off, flip a flag in the
|
||
<code>CONFIG</code> block (see the README's calibration notes).</li>
|
||
</ol>
|
||
<p class="sub">It's one self‑contained file — the ST7796 driver, GT911 touch, WS2812 RGB, buzzer and the
|
||
polymeter engine, no external libraries.</p>
|
||
</div>
|
||
</details>
|
||
|
||
<details class="spec">
|
||
<summary>CircuitPython edition — self‑contained appliance (USB drive · push programming · MIDI audio · practice log)</summary>
|
||
<div class="spec-body">
|
||
<p class="sub">An alternative firmware that turns the Pico into a self‑contained appliance: it mounts as a
|
||
<b>USB drive</b> carrying the firmware, your tracks and an offline copy of this editor; drives a full
|
||
lanes/pads touchscreen; <b>logs your practice</b> to <code>history.json</code> on the device; takes new
|
||
set lists <b>pushed from the editor over USB‑MIDI</b>; and plays out your <b>computer's speakers over
|
||
USB‑MIDI</b>. By default the firmware owns the drive (read‑only to the computer — so it can log and
|
||
can't be accidentally erased); hold <b>button A</b> at power‑on for editor mode (drive writable). The
|
||
MicroPython firmware above stays the simple, rock‑solid option.</p>
|
||
<p>
|
||
<a class="dl" href="/pm_k1_circuitpy.zip" download>Download CircuitPython bundle ↓</a>
|
||
<a class="dl alt" href="https://codeberg.org/VARASYS/metronome/src/branch/main/pico-cp" target="_blank" rel="noopener">Source + README ↗</a>
|
||
</p>
|
||
<ol class="steps">
|
||
<li>Flash <b>CircuitPython</b> (<a href="https://circuitpython.org/board/raspberry_pi_pico/" target="_blank" rel="noopener">raspberry_pi_pico</a>)
|
||
via BOOTSEL, unzip the bundle onto <code>CIRCUITPY</code>, and power‑cycle. It boots into appliance mode.</li>
|
||
<li><b>Program it from the web:</b> build a set list in the <a href="/editor.html">editor</a> (Chrome/Edge/Firefox),
|
||
then the set‑list <b>⋯</b> menu → <b>📟 Save to device</b>. It's pushed over USB‑MIDI and the device shows
|
||
<b>Saved ✓</b>. (Fallback for any browser: it downloads <code>programs.json</code> — boot holding A and drag it on.)</li>
|
||
<li><b>Play through your computer:</b> click <b>🎹 Device audio</b>, then press play on the device — the full
|
||
groove sounds through your speakers over USB‑MIDI, in sync; the screen shows a <b>MIDI</b> badge and the buzzer mutes.</li>
|
||
<li><b>Practice log:</b> plays over 5 s appear at the bottom of the screen (time · BPM · duration · track); tap a row twice to delete.</li>
|
||
</ol>
|
||
</div>
|
||
</details>
|
||
|
||
<p class="sub" style="max-width:760px;margin:14px auto 0">Embed this widget elsewhere with one <code><div></code> + a script —
|
||
see <a href="/embed.html">the embed docs</a>.</p>
|
||
</main>
|
||
|
||
/*@BUILD:include:src/footer.html@*/
|
||
|
||
<script>
|
||
const APP_VERSION = "v0.0.1-dev";
|
||
window.INFO_DEVICE = { file:"/kit.html", name:"PM_K‑1 Kit" };
|
||
/*@BUILD:include:src/infoembed.js@*/
|
||
/*@BUILD:include:src/chrome.js@*/
|
||
</script>
|
||
</body>
|
||
</html>
|