Skip to content

ammonhaggerty/temporal-badge

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

6 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Temporal Replay 2026 Badge — Personal Workspace

Repurposing my Temporal Replay 2026 conference badge (Moscone Center, San Francisco, May 6–7 2026) by writing new MicroPython apps against its existing on-device API. The firmware stays intact — we don't reflash, we just upload Python to /apps/.

The badge is an ESP32-S3-WROOM-1 16N8 running Amelia Wietting's custom firmware (Arduino C++ + embedded MicroPython v1.28-preview). Hardware: 128×64 SSD1306 OLED, 8×8 IS31FL3731 LED matrix, LIS2DH12 IMU, NEC IR TX/RX, vibration motor with coil-tone audio, 4 face buttons + analog joystick, LiPo battery.

Layout

badge-fs/      # read-only mirror of the badge filesystem — gitignored;
               # populate locally with scripts/pull-fs.sh
               # (firmware code is Amelia's work, not redistributed here)
docs/          # tooling & recovery notes specific to this workspace
  tooling.md   # mpremote `resume` quirk, push/pull workflows
  recovery.md  # esptool restore from the 16 MB backup
my-apps/       # new OLED apps (folder-per-app or single-file)
  hello_world/
    main.py    # entry point (tiny — just calls run_app())
    app.py     # OLED + buttons + IMU demo, native chrome, crash-safe
my-matrix-apps/  # new LED-matrix-only apps (created on demand)
scripts/
  repl.sh      # drop into screen at the right baud
  pull-fs.sh   # sync badge -> ./badge-fs/, with retries
  push-app.sh  # deploy my-apps/<name> -> /apps/<name> on the badge
.gitignore
CLAUDE.md
Instructions.md  # original handover prompt; kept for context

The on-device docs in badge-fs/docs/ are excellent — MicroPythonDeveloperGuide.md is 29 KB of well-written app-author guidance and API_REFERENCE.md is 39 KB of function-by-function reference. Read those for API details. This workspace's docs/ is intentionally thin and only covers workspace-specific things (tooling quirks, recovery from backup).

Quick start

# 1. (one-time) sync the badge filesystem locally — required, the docs
#    in badge-fs/docs/ are the canonical API reference and are not
#    redistributed in this repo
scripts/pull-fs.sh

# 2. drop into the REPL
scripts/repl.sh                 # Ctrl-A K Y to detach

# 3. deploy and run the starter app
scripts/push-app.sh hello_world --run

Authoring an app

The conventions enforced by the firmware are written up in badge-fs/apps/README.md and badge-fs/docs/MicroPythonDeveloperGuide.md. The short version:

  • Single-file (my-apps/foo.py) for one-shot demos. All badge API functions are auto-injected as globals at the entry script's scope.
  • Folder (my-apps/foo/main.py) for anything serious. The folder gets added to sys.path and you from badge import * in submodules.
  • Wrap the main function in badge_app.run_app("name", main) so an uncaught exception ends up in /last_mpy_error.txt with a native crash screen, not a frozen display.
  • badge_ui.chrome("Title", "right", "OK", "label", "BACK", "label") for header + footer matching the firmware. The button glyphs follow the user's confirm/back swap setting automatically.
  • Use BTN_CONFIRM/BTN_BACK for menu-style buttons (semantic) and BTN_UP/DOWN/LEFT/RIGHT (or PS aliases) for game controls.
  • Wrap LED-matrix drawing in with_led_override(callback) so the ambient matrix mode resumes cleanly on exit.

my-apps/hello_world/ is a working starter that demonstrates all of the above.

Hardware constraints worth knowing

  • No GPIO from Python. import machine and import esp32 are intentionally blocked. The bottom-edge JST connectors labeled CAM and I²C are unreachable without a custom firmware build. (See "Rebuild?" below.)
  • 2 MB Python heap from PSRAM. Use GCTicker or DualScreenSession from badge_app in long-running loops.
  • Python runs on Core 1 only. Don't busy-wait — the firmware service pump on Core 0 needs cycles to keep USB, IR, and the LED matrix alive.
  • IR is mode-gated. Call ir_start() before any ir_* and ir_stop() when done. Poll ir_read() within 50 ms or the RX buffer overflows.
  • Native USB-CDC + JTAG over USB-C. Toggling DTR/RTS resets the device. mpremote needs the resume keyword (see docs/tooling.md).
  • Escape chord: holding all four face buttons for ~1 s force-exits any running app — firmware-level, you don't implement it.

Rebuild from scratch?

I considered replacing the firmware and got pushed back hard by the trade-off:

  • You'd gain: GPIO access (CAM/I²C JSTs become useful), no curated-API ceiling, freedom to pull in BLE/ESP-NOW/MQTT.
  • You'd lose: native UI chrome with button-glyph hints, hardware mouse-overlay, the multi-word IR NEC frame extension with software CRC, the crash-screen lifecycle, the production game ports (Doom!), the JumperIDE workflow, and the auto-imported flat badge API. Each of those is days-to-weeks of replacement work.
  • You'd risk: one bad esptool write-flash and you're soldering JTAG. Native USB-CDC means there's no UART fallback if early-boot firmware crashes. The 16 MB backup at ~/temporal-replay-2025-badge-backup.bin exists but writing it back takes ~25 minutes.

Decision: stay on the existing firmware. If a future project specifically needs the I²C JST, look up Amelia's firmware repo (the on-device docs reference firmware/src/, pio run -e echo-dev, and scripts/generate_startup_files.py — strongly suggests a public PlatformIO project) and do a targeted fork, with the backup verified beforehand.

What's not here

  • doom1.wad is excluded by .gitignore and skipped by pull-fs.sh by default — it's multi-megabyte over USB-CDC and not architecturally interesting. Use pull-fs.sh --with-doom if you want it locally.
  • The original full flash image. It lives at ~/temporal-replay-2025-badge-backup.bin — keep it there, not in this repo.

Credits

Badge firmware and the on-device docs/API are by Amelia Wietting. This workspace just adds new MicroPython apps on top.

About

Tooling and starter MicroPython apps for the Temporal Replay 2026 conference badge (ESP32-S3, custom firmware by Amelia Wietting). The firmware stays intact — new apps land in /apps/ via mpremote.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors