Skip to content

feat: G6 analog/digital-out protocol commands + designer field validation - #126

Merged
mbreiser merged 5 commits into
mainfrom
feat/g6-io-protocol-commands
Jul 1, 2026
Merged

feat: G6 analog/digital-out protocol commands + designer field validation#126
mbreiser merged 5 commits into
mainfrom
feat/g6-io-protocol-commands

Conversation

@mbreiser

@mbreiser mbreiser commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds the two experiment-relevant G6 I/O commands from #123's console (SET_AO_VOLTAGE 0xA0 → BNC J27 DAC; SET_DIGITAL_OUT 0xAA → DO1/DO2 TTL) to the YAML experiment protocol as G6-only controller commands, wired end-to-end, plus a designer-wide clamp-to-legal field-validation pass. The other 16 new console commands (SD pattern mgmt, firmware/ISP, STREAM_FRAME, GET_* reads) are operator/setup and stay out of the protocol.

Hardware-verified on a real G6 (2026-07-01): AO (J27 → 2.5 V) and DO1 (J3 toggle) confirmed via both arena_console.html and the v3 designer full-sequence runner.

What's included

  • ProtocolsetAnalogOut {mv} / setDigitalOut {channel,state} in plugin-registry.js; first-class YAML keys + a soft export-warning when used on a non-G6 rig (protocol-yaml-v3.js); v1/v2 emit (protocol-yaml.js).
  • Designers — v3 add-command gating (permissive: hide/badge only on a known non-G6 rig) + schema-driven param fields; v2 forward-compat defaults.
  • Runnerarena-runner-g6.js translates + sends both via Fictrac bridge #123's encoders with range validation; instantaneous (no clock advance).
  • Field validation (from review feedback) — numeric fields clamp to schema min/max/integer on commit, show the allowable range in the hover tooltip, and toast the correction. Covers all command scalar fields (controller + plugin + wait). Pure exported clampToSchema().
  • Tests — v3 Suite 33, wire golden vectors, runner IR/byte tests, new tests/test-plugin-registry.js; all wired into the CI workflow. pixi run test green.

Scope / follow-ups (not in this PR)

  • Web-runner-only for v1 — MATLAB (maDisplayTools) runner support + final command-name lock-in are a separate, later task; YAML stays forward-compatible so MATLAB ignores the new keys.
  • Deferred — FicTrac closed-loop as a plugin; and a review of the trialParams-only "Test on arena" dry-run vs. the full-sequence runner (logged in ROADMAP → G6 Web Control → "To review").

🤖 Generated with Claude Code

mbreiser and others added 5 commits June 30, 2026 23:23
…mands

Expose the two experiment-relevant I/O commands from PR #123's G6 console
(SET_AO_VOLTAGE 0xA0, SET_DIGITAL_OUT 0xAA) as controller commands in the YAML
protocol. These drive native G6 controller-board hardware (BNC J27 DAC, DO1/DO2
TTL), so they are controller commands (not plugins) and are gated G6-only. All
other new console commands (SD mgmt, firmware/ISP, STREAM_FRAME, GET_* reads)
are operator/setup and stay out of the protocol.

Web-runner-only for v1: YAML stays forward-compatible (unknown-key passthrough)
so the MATLAB runner tolerates the keys until coordinated separately. The web
runner wiring (arena-runner-g6.js) is deferred until PR #123's wire encoders
land on main.

- plugin-registry.js: register setAnalogOut {mv}, setDigitalOut {channel,state};
  add G6_ONLY_COMMANDS set + isG6OnlyCommand()
- protocol-yaml-v3.js: mv/channel/state as first-class keys; collectExportWarnings
  gains an optional arenaGeneration arg that soft-warns (never blocks) on a
  G6-only command targeting a non-G6 arena
- protocol-yaml.js: v1/v2 emit for the new fields (round-trip)
- experiment_designer_v3.html: rigGeneration() gates the add-command dropdown +
  card badge (permissive — hide/badge only when generation is KNOWN non-G6);
  add mv/channel/state to renderCommandCard detailKeys so fields render
- experiment_designer.html: v2 forward-compat defaults
- tests: v3_g6_io.yaml fixture + Suite 33 (19 checks); npm test green (663/663 v3)

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Now that PR #123's wire encoders (encodeSetAoVoltage/encodeSetDigitalOut) are on
main, complete the web-runner path for the two G6-only I/O controller commands.

- arena-runner-g6.js: add setAnalogOut/setDigitalOut to RUNNABLE_CONTROLLER_COMMANDS
  + the mirrored emit-list comment; translateCommand emits {op:'setAnalogOut',mv}
  / {op:'setDigitalOut',channel,state} with range validation (mv 0-5000 int;
  channel 1|2; state 0|1) → {op:'error'} on bad input; _runIR dispatches to
  W.encodeSetAoVoltage / W.encodeSetDigitalOut (instantaneous, no clock advance).
- test-arena-runner-g6.js: translateCommand IR + range-error checks; runSequence
  byte-level test (setDigitalOut(2,1)->03 aa 02 01; setAnalogOut(2500)->03 a0 c4 09).
- test-arena-wire-g6.js: golden vectors + range-throw checks for both encoders.

pixi run test green (runner 130/130, wire 112/112).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Numeric fields in the v3 designer previously accepted any value (only NaN/empty
was rejected); an out-of-range value like mv=9999 was silently saved and only
failed at run time. Now illegal values are impossible to commit.

- plugin-registry.js: add min/max/step/integer to controller command params
  (mv 0-5000, gain -128..127 int8, frame_rate/frame_index/posX 0..65535,
  pattern_ID 1..65535, duration >=0) and integer:true to backlight power /
  panel_num (which already had min/max). Add pure clampToSchema(value,schema)
  -> {value,changed,reason}.
- experiment_designer_v3.html: renderEditableField now sets native min/max/step
  on number inputs, shows the allowable range + integer in the hover tooltip
  (numFieldTooltip), and clamps/rounds to the schema on commit via clampToSchema,
  surfacing a transient toast (showToast) explaining the correction. wait.duration
  gets a {min:0} schema so it validates too. Plugin params inherit this for free
  (they already declared min/max and route through the same renderer).
- tests/test-plugin-registry.js (new, wired into pixi test): clampToSchema +
  isG6OnlyCommand unit coverage (require()-of-ESM under Node >= 22.12).

pixi run test green (plugin-registry 15/15). Browser-verified: mv 9999->5000,
wait -5->0, gain clamps, floats round, range tooltips present.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…hanges

v3 Experiment Designer v0.36 → v0.37; v2 Experiment Designer v0.9 → v0.9.1.
Timestamp 2026-07-01 00:57 ET.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
These suites were only covered by the local `pixi run test` task. Add them to
the roundtrip CI workflow (plain node, Node 24 already set) plus their source-file
triggers (js/arena-wire-g6.js, js/arena-runner-g6.js) so the G6 I/O + clampToSchema
coverage runs on push/PR instead of silently rotting.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@mbreiser
mbreiser merged commit a2fd907 into main Jul 1, 2026
3 checks passed
@mbreiser
mbreiser deleted the feat/g6-io-protocol-commands branch July 1, 2026 16:27
mbreiser added a commit that referenced this pull request Jul 2, 2026
* docs(arena-studio): unification design + wireframes v1–v5 + handover

Consolidated onto current main. v5 is the approved density/ergonomics
pass over v4 (one 44px bar; Console essentials + collapsible foot-gun
groups; 150px collapsible run-log) with content re-synced to shipped
main: ArenaSession broker shipped, run-log module built-but-unwired,
plus #126 analog/digital-out, #129 run-whole-condition, #130 0x88 +
panel-display-mode, #131 FicTrac. Handover refreshed to the verified
2026-07-01 shipped-vs-pending table.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* arena-studio: ISP firmware-push handoff + same-origin dev artifacts

Groundwork for Arena Studio's "push official builds to panels" flow:

- docs/development/arena-studio-isp-firmware-push-handoff.md — catalog
  schema (isp_file/isp_sha256, firmware repo PR #17), the 0xE0/0xE3/0xC8/
  0xC9 wire flow (encoders already in js/arena-wire-g6.js), UX notes from
  the real fleet reflash, gotchas (CORS: Pages yes / Release assets no).
- flasher/firmware/manifest-dev.json — schema-identical dev catalog to
  develop against until PR #17 + a release tag publish the real one.
- Dev builds (same-origin): isp-progress-display 23d66af (progress bar
  while ISP-flashing + first-boot smiley), both revs, .bin + .uf2; plus
  the current fleet build (dd7d3f9) ISP bins.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant