metronome/pico-cp/README.md
Me Here 111da49b5a PM_K-1 CircuitPython: fix MemoryError + red/blue swap (from on-board test)
On hardware the app rendered, beeped and took input, then died with MemoryError at
the text Bitmap alloc — the two ~37KB base64 font strings stayed pinned in RAM. Move
the fonts to small binary files read at boot (font_m.bin / font_l.bin), drop the
base64 + binascii, and gc.collect() before each text bitmap. code.py 56KB -> 20KB and
RAM use drops ~37KB+. Also: cyan rendered as yellow (R/B swapped) -> MADCTL 0x40 -> 0x48.
Bundle + README updated to include the font blobs. (LED still needs the neopixel lib.)

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

3.1 KiB
Raw Permalink Blame History

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_m.bin, font_l.bin (the antialiased fonts — kept as files to save RAM)
  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

{ "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.

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.
  • 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).
  • No RGB LED: the WS2812 needs the neopixel library on CIRCUITPY/lib (circup install neopixel) — everything else works without it.

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).