Tomo - Embodied Continuity on Embedded Hardware
TL;DR: A persistent embodied creature on an Adafruit PyPortal Titano — no AI backend, no network, no score — whose posture and condition mirror the rhythm of your care over time.
What it is
Tomo is a small organism living on a PyPortal Titano (SAMD51, 3.5″ TFT, 256 KB RAM) built entirely with CircuitPython builtins — displayio, synthio, audioio, digitalio — plus two external buttons. It tracks six internal variables that drift continuously while powered; when they cross thresholds, Tomo shifts among seven display states (stable, dormant, blooming, strained, fragmented, recovering, curious), each expressed through body deformation, posture, gaze, and sound rather than icons or text.
Why it exists
It is explicitly not a pet simulator, notification dashboard, or habit tracker. There is no score, no win condition, no streak counter, and no guilt mechanics. The design thesis is continuity, not cognition: the only question Tomo asks is whether you showed up today, whether you showed up last week, and whether the gap between the two is growing.
Core features
- Six-variable state engine with flash persistence — state survives power cycles
- Visit-rhythm analysis (
patterns.py): hour bins, gap history, and a neglect multiplier - Three interactions: Visit (Button A, boosts coherence), Tend (Button B, restores viability), and a Ritual (both held ≥1.2 s, large boost with 5-minute cooldown and an ascending arpeggio)
- 17 sprite BMPs generated by a desktop Pillow script
- Fully tunable thresholds and drift rates in
config.py
How it works
A never-exiting main loop (code.py) ties together a debounced two-button input handler with ritual detection, a rendering layer using a persistent TileGrid with stable bitmap swaps, and an audio module that gates the speaker and tears synthesis down after each sound. State and pattern data persist as JSON on flash. A companion WHITEPAPER.md documents the state machine and design decisions in depth.