circulation, the manual

cupping, colour, and collective sensing · what every file is and what to do with it

One page for the whole build, from simulator tuning to the end of the funded period (30 November 2026). The project does not target an exhibition deadline; the whole window goes into building the machine fully. Read it top to bottom once; after that, jump to the phase you are in.

The one rule everything follows. Each cup is self-sufficient: it senses, computes its Five Elements colour, and glows with no network and no computer. Everything else (hub, TouchDesigner, room) is an optional layer above a system that already works. If a change would break that, do not make the change.

The cycle the light follows

wood 목 fire 화 earth 토 metal 금 water 수

The generating cycle (상생): each element feeds the next. When held cups sit adjacent on this circle, light travels between them. It is a fixed contract of the work.

The map

The shared spec: the artwork's logic, one truth in two languages

If the browser and the cup ever disagree, the project's core claim breaks. Change the mapping in the TypeScript AND the firmware together, in one pass.

src/fiveElements.tsthe Five Elements (오행) mapping engine: pressure, trend, pulse, regularity, hold become an element and a colour; also the paper's system description
src/sync.tsthe collective layer: synchronisation score, room colour, and the 상생 circulation reading (score, flow edges, chain)
hardware/cup/cup.inothe C++ mirror of the engine plus presence and afterglow, running on the cup itself

The site: what you, curators, and the public see

Every push to main auto-deploys to circulatorysensing.com in about 30 seconds. You never deploy manually.

circulation/system.htmlthe live simulator page: three virtual cups, the flow layer, the room
src/main.tsthe simulator's code: presence, afterglow marks, light travelling cup to cup, sliders. Tune the interaction here first, hardware second
src/cupView.tsthe rendering pieces shared by circulation/system.html and sim.html: the cup panel, colour helpers, the flow layer, and the presence/afterglow display state
sim.html / src/sim.tsthe physical computing simulation: the same three cups, but a grip and a heart rate pass through simulated FSR/MAX30102 sensor behaviour (noise, calibration, contact dropout) before reaching the engine
src/sensorSim.tsthe sensor model sim.html runs: mirrors cup.ino's raw ADC, calibration bounds, IR contact threshold, and beat jitter, with fault toggles for a loose palm seal, a fidgeting hand, and an uncalibrated cup
log.htmlthe process log. One entry per build week: grant report, paper documentation, and curator-facing story in one file
.github/workflows/deploy.ymlthe auto-deploy

The hardware layer

hardware/cup/cup.inothe firmware you flash onto each ESP32. The config block at the top (CUP_ID, Wi-Fi, hub address, pins, calibration, PRESENCE, MARK_FADE_S) is the only part edited per cup
hardware/cup/README.mdwiring and library guide
hardware/TECHNICIAN_BRIEF.txtthe meeting document: real cups + printed insert, sensors, parts list, contracts, safety line. Copy-paste ready
wokwi/a circuit simulation of cup.ino itself (ESP32 + FSR + LED ring, no hardware required): validates firmware logic before or alongside a real build

The collective layer: after three cups exist

hub/hub.tsthe sync hub: listens to cups (OSC port 8000), computes sync + room colour, republishes to TouchDesigner (port 9000), logs every tick to logs/session-*.jsonl: the paper's dataset and the 계 archive feed. Run with npm run hub
hub/README.mdports and message schema
touchdesigner/RECIPES.mdthe from-zero TouchDesigner path, one concrete artifact per recipe, ending at a festival-ready show patch. Optional by design

The paper and reporting

Circulation_Paper_Draft_and_Figure_Prompts.mdthe paper draft (target ISEA 2027) with its figure plan
circulation-figure-prompts.txtthe extracted figure prompts, copy-paste ready
Circulation_Monthly_Reports_Aug-Nov_2026.mdthe SCD grant reporting skeleton, August to November

Plumbing: you rarely touch these

package.json · tsconfig.json · vite.config.tsbuild configuration, plus package-lock.json, .gitignore, src/vite-env.d.ts, and README.md (the repo's front page)

What runs where

Browser, anywhere

the simulator, live on GitHub Pages or locally with npm run dev

The cup (ESP32)

cup.ino, standalone: sense, compute, glow

Your laptop at the venue

the hub (npm run hub), and TouchDesigner if used

GitHub

hosting, auto-deploy, and the public archive of everything

What you do, phase by phase

  1. Now, before any parts arrive

    • Tune the interaction in the simulator until the mapping feels true. The knobs are named constants: element thresholds in fiveElements.ts, sync windows in sync.ts, PRESENCE and MARK_FADE_S in main.ts. Change a value, push, feel it live two minutes later.
    • Take TECHNICIAN_BRIEF.txt to the technician meeting.
    • Buy a real cupping cup set and order the parts list in the brief. Lead times are the schedule risk.
    • Hold a cup mouth-down on your palm for a minute; the posture decides the insert design.
  2. Bench week, when parts arrive

    • Install the Arduino IDE, add ESP32 board support, install the three libraries named at the top of cup.ino (SparkFun MAX3010x, Adafruit NeoPixel, CNMAT OSC).
    • One component at a time, breadboard first: LED ring alone, then pressure sensor alone, then MAX30102 alone, watching the Serial Plotter. Never debug two new parts at once.
    • The pin numbers in cup.ino assume a classic ESP32 dev board; a Xiao ESP32-C3 (the brief's recommendation) needs the config block remapped first. Do not flash blindly.
    • Run the two bench experiments from the brief: palm PPG under seal pressure (the design decider) and BMP280 inside a sealed cup. Uncomment RAW_LOG in cup.ino to print raw values. Keep all logs: they are the dataset's first entries.
    • Verify the afterglow on real hardware: grip, release, watch the ring hold and fade over about 40 seconds.
  3. MVP gate end of August

    • One untethered cup: insert in a real cup, power bank, hand to colour, stable for 30 minutes.
    • Calibrate FSR_MIN / FSR_MAX (or the BMP280 equivalents) per cup from RAW_LOG values; set CUP_ID 1, 2, 3.
    • Close the month with an internal pilot: around ten colleagues' hands, every session logged, note which grips break the reading.
    • Only after this gate passes: build the other two.
  4. Three cups and the collective layer September

    • Cups and laptop on one Wi-Fi network; set WIFI_SSID and HUB_HOST in each cup's config block.
    • Run npm run hub. Cups appear as /cup messages; every session is logged to logs/. Back those files up.
    • Rehearse the three-body choreography with real people and tune the sync windows against what real triads do.
    • Iterate the insert and enclosure with what the pilot taught you; September is for making the triad solid.
  5. The room, and endurance October

    • Work through touchdesigner/RECIPES.md in order. The hub already speaks to TD on port 9000; TD only listens and paints. Still optional by architecture, but now a scheduled month, not a cut line.
    • Endurance: full-afternoon soak tests, battery rotation drills, hygiene protocol. The machine must run unattended-long, not demo-long.
    • Structured triad sessions with invited participants, logged through the hub: the dataset the paper is written from.
  6. Finish, document, archive November, funded period ends 30 Nov

    • Documentation video and photography of the finished system to submission standard.
    • Launch the standalone project website and 10-year archive (a budgeted deliverable), folding in the simulator, the process log, and rendered session data.
    • A final showing for the school (R&I team, mentor, collaborators), run like a rehearsal of a future exhibition. Demo kit: spare cup body and insert, power banks, wipes, printed contracts, phone hotspot; the serial CSV fallback reads any cup over USB if Wi-Fi dies.
    • Final seed-funding report and the paper draft. The machine, the dataset, the archive, and the draft are the deliverables.

Command cheat sheet

Run in the project folder (~/Projects/circulation).

npm installonce, after cloning on a new machine
npm run devlocal simulator at the printed localhost address
npm run hubthe sync hub (needs cups or a test sender on the network)
npm run typechecksanity check the TypeScript
npm run buildwhat the auto-deploy runs; push to main and the site updates itself

Contracts that must not change

Circulation: Cupping, Colour, and Collective Sensing · SCD Seed Funding 2026 · a cultural coordinate system, not medical advice. The plain-text version of this manual is MANUAL.md in the repository.