feat(console): Analog In panel — live 10 Hz readout, strip chart, AO→AI loopback sweep (S1) — Studio v0.74 - #190
Merged
Merged
Conversation
mbreiser
force-pushed
the
feat/console-analog-in
branch
from
September 9, 2026 12:25
17e97b0 to
e169159
Compare
…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>
…VOLTAGE; pause the poller during the Console's FicTrac closed loop Codex cross-review 2026-09-09. The Console send() helper returns the reply frame even when the firmware answers a non-ok status (it logs the reason), so the sweep's truthiness check only caught transport failures: with Analog Out in frame_number mode every 0xA0 step is refused and the sweep would have recorded AI readings against levels that were never applied. Decode the status, abort with a hint naming the AO mode; report a refused/unknown restore too. The live poller gated on session.running (runner trials) but not on the Console's own FicTrac closed loop (bridge 'apply'), which streams 0x70 at ~100 Hz outside the runner — yield the link to it as well. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A perfectly linear channel reading AO + 1 V passed as 'ok' because the verdict looked only at slope and scatter; for a loopback self-test the offset is the diagnostic. Now ok = slope ±5 % AND |offset| ≤ 150 mV AND max |err| ≤ 150 mV; 'check' still means slope within ±15 %. Test added (Codex review item 4). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
mbreiser
force-pushed
the
feat/console-analog-in
branch
from
September 10, 2026 16:55
9312b56 to
b3dfb8a
Compare
mbreiser
added a commit
that referenced
this pull request
Sep 10, 2026
…(fw #48), first reworked-board analog results Merge plan: B1 rows ticked with the rig05-mr run (#188 merged f744e12, #186 closed), B2 ticked (#190 merged 880ffd5, #191 rebased --onto and held), 12-18 bring-up + loopback numbers. Handover: status table + Windows gotchas (Git Bash TZ prints UTC, base-retarget runs no CI, rebase --onto after a squashed parent, PYTHONUTF8, teensy upload port/power). Analog plan § 5.1: T1/T6 results — AI1 tolerance-class, AI2 stage-2 divider ≈ 0.26 (inspect R179/R181). CLAUDE.md: Windows-safe ET timestamp recipe. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
mbreiser
added a commit
that referenced
this pull request
Sep 10, 2026
… lab-PC handover + 2026-09-10 bench results (#192) * docs: controller telemetry ring buffer — feasibility, design, T1–T6 + L1–L4 bench plan (no code) Proposal for a controller-side RAM ring buffer (frame/command/state events, analog ticks yoked to frame index) drained live over USB with an ack-cursor, replacing the SD-card event-log shape of LAB-149. Answers the two-file vs integrated question (sidecar first), timestamps/clock-fit, and lays out the glass-to-glass latency measurement plan for FicTrac closed loop. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(telemetry proposal): use the 0xA8/0xA9 opcodes reserved by firmware PR #47 Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs: merge + bench plan for 2026-09-08/09 (run-log stack, analog F1/F2 + S1/S2, cleanup) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(merge plan): #186/#188 rebased; flag gzip-blind runlog index builder Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(merge plan): #189 merged; gzip index-builder fix built + tested (PR pending) Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(merge plan): #193 merged + installed in the course repo; Action rebuild green Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(merge plan): corpus gates 174/174 on rebased #188; index.json filter fix Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs: Codex cross-review of the pending merge-plan work (2026-09-09) — fixed bugs, discussion items, open questions Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(merge plan): stacks rebased onto main after #193; pixi.toml test-line collision note Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(codex review + merge plan): second pass — discussion items 4/6/7/8/9/10 done Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs: lab-PC handover — install list, branch state, gate B1 step-by-step, minimal analog, firmware, gotchas Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs(lab-pc handover): optional bench launcher — FicTrac / configGui / bridge / Studio buttons with status Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> * docs: 2026-09-10 bench day — gates B1/B2 passed, 12-18 arena flashed (fw #48), first reworked-board analog results Merge plan: B1 rows ticked with the rig05-mr run (#188 merged f744e12, #186 closed), B2 ticked (#190 merged 880ffd5, #191 rebased --onto and held), 12-18 bring-up + loopback numbers. Handover: status table + Windows gotchas (Git Bash TZ prints UTC, base-retarget runs no CI, rebase --onto after a squashed parent, PYTHONUTF8, teensy upload port/power). Analog plan § 5.1: T1/T6 results — AI1 tolerance-class, AI2 stage-2 divider ≈ 0.26 (inspect R179/R181). CLAUDE.md: Windows-safe ET timestamp recipe. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> --------- 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