feat(console): Analog In panel — live 10 Hz readout, strip chart, AO→AI loopback sweep (S1) — Studio v0.74 - #190
Open
mbreiser wants to merge 1 commit into
Open
feat(console): Analog In panel — live 10 Hz readout, strip chart, AO→AI loopback sweep (S1) — Studio v0.74#190mbreiser wants to merge 1 commit into
mbreiser wants to merge 1 commit into
Conversation
…rt, AO→AI loopback sweep; 0xA4 flags decode; G3 gain tooltip (S1) — Studio v0.74
Studio half S1 of docs/development/analog-input-plan.md § 4 (decisions
2026-09-07). Works against today's io_ext firmware and reads the F1 flags byte
when present.
- js/studio-analog-in.js (new; classic dual-export, DOM-free): createMonitor
(windowed ring buffer, min/max, rate), createPoller (single-flight ticker
gated on panel-open / connected / io_ext / user pause / session.running /
sweep; reports state CHANGES only, parks after N consecutive read errors),
sweepPlan / fitLinear / summarizeSweep / sweepCsv (AO 0→5000 mV loopback
self-test with ok/check/fail verdict — a flat +10 V reading is the LAB-209
un-reworked-board signature), describeFlags (0xA4 flags byte), drawStripChart.
- arena_studio.html: left-rail "Analog In" button + panel (values, ±10 V bars,
min/max, 30 s canvas trace, rate 10/5/2 Hz, Live/Paused, Reset, loopback
sweep with table + Copy CSV). The poller reads via session.send directly —
NOT the logging send() — so the Console log is not flooded at 10 Hz; state
transitions and the sweep are logged; the sweep is also logged to the bridge
run log (event analog_loopback_sweep) and restores the previous AO level.
I/O panel's one-shot Read shows the flags text. Trial-panel gain tooltip now
states the G3-faithful scale (×10; 10 = 100 fps/V; 2–5 = 20–50 fps/V).
HELP-map entries; footer v0.74.
- js/arena-wire-g6.js: decodeAnalogIn returns {flags, cal1, cal2, bits12}
(null/false on 4-byte pre-F1 replies); wire tests extended.
- tests/test-studio-analog-in.js (new, in pixi run test): 105 checks — monitor,
single-flight poller with injected timers, sweep math incl. saturation and
10 % slope verdicts, wire flags, and the HTML wiring (script order, rail,
panel ids, handlers, quiet read, run gate, io_ext gate, HELP, tooltip, footer).
- Release notes v0.74; CLAUDE.md Console convention: periodic reads bypass
send() and reuse StudioAnalogIn.createPoller.
Not bench-tested (no hardware); browser-verified offline: panel renders, poller
shows the gate reason and issues no reads while disconnected.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Studio half S1 of docs/development/analog-input-plan.md § 4 (plan PR #189; decisions 2026-09-07). Pairs with firmware F1 (reiserlab/LED-Display_G6_Firmware_Arena#46) but works against today's io_ext firmware too — the F1 flags byte is optional on the wire.
What changed (Studio v0.74)
New Console tool: "Analog In" (left-rail button + panel)
GET_ANALOG_INviasession.senddirectly (not the loggingsend()), is single-flight (a tick is skipped while a read is on the wire), and pauses itself with a visible reason whenever the gate says no: panel closed, not connected, no io_ext firmware, user pause, a run in progress, or a sweep in flight. Only state transitions are logged; it parks after 5 consecutive read errors with a resume hint.ok(slope within 5 %, max error ≤ 150 mV) /check/fail, Copy CSV, and the previous AO level is restored. A flat reading near +10 V at every step is called out as the LAB-209 un-reworked-board signature. The sweep is also written to the bridge run log (analog_loopback_sweep).Elsewhere
js/arena-wire-g6.jsdecodeAnalogInreturns{flags, cal1, cal2, bits12}(null/false on 4-byte replies).send(), reuseStudioAnalogIn.createPoller).Code
js/studio-analog-in.js(new, classic dual-export, DOM-free):createMonitor,createPoller,sweepPlan,fitLinear,summarizeSweep,sweepCsv,describeFlags,median,barFraction,formatMv,drawStripChart.arena_studio.html: rail button, panel section, CSS, poller/sweep wiring before the handler table, fourdata-cmdhandlers (caipoll,caireset,caisweep,caisweepcsv).Tests
tests/test-studio-analog-in.js(new, inpixi run test): 105 checks — monitor (window trim, min/max persistence, rate, cap), poller (single-flight skip, gate pause reported once, error streak → park → resume, gate reopen forgives errors, injected timers start/restart/stop), sweep math (exact fit, NaN rows, saturation → fail, 10 % slope → check, channel 2, CSV), wire flags decode, and HTML wiring (script order, rail, every panel id, every handler, quiet read, run gate, io_ext gate, HELP entries, gain tooltip, footer, AO restore).tests/test-arena-wire-g6.js: flags decode cases (183 → 186).pixi run testpasses; touched JS Prettier-clean; all inline Studio script blocks parse.🤖 Generated with Claude Code