23 Commits
Author SHA1 Message Date
janikandClaude Fable 5 158e1ccf03 stm32_link: sync iin_avg_ma comment with live firmware protocol
Firmware now runs BOTH iin limits (IIN_MAX reverse-feed and the IIN_MIN
forward OCP, raised to -47A) on the 8-sample boxcar; wire format is
unchanged (verified field-by-field against the live code64 console,
including a synthetic-frame decode). Note the field is a raw int16 mA
cast and wraps at +-32.768A (observed +26.5A at a true -39.0A) -- the
float iin field is the honest monitor above that.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 17:06:00 +07:00
janikandClaude Fable 5 465455d427 GUI sweep: converter-collapse abort + measured finish-time estimate
The mid-sweep abort only watched the supply readback (~0V = supply
protection tripped), so a DUT-side collapse sailed past it: run
2026-07-07 10:58, Vout 48->3.1V at Vin=55V with the supply still up at
55V/0A, sweep kept stepping the 75V column through garbage. Add a
second abort when the load voltage drops below half the expected Vout;
the message names the STM32 limit/fault bits from the last frame
before the brownout blackout (the MCU rides the Vout rail).

Status line now appends ETA hh:mm (N pts, ~M min left): remaining
grid is deterministic (feasibility-gated steps), per-point cost is not
(instrument round-trips vary per setup), so it is a running average of
measured point times (thermal holds excluded) extrapolated over the
remaining feasible points. Grid size is printed at sweep start.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 14:39:48 +07:00
janikandClaude Fable 5 f709d634e8 bench-plot: per-file Vin-bin checkbox picker for combining runs
Combining multiple CSVs pooled everything blindly; when two runs cover
the same Vin bin the user now gets a checkbox grid (row per Vin bin,
column per file, counts per cell, overlapping bins highlighted) to
decide per bin which file contributes. Opens automatically on overlap;
--pick forces it (also useful to cut bad columns from a single file),
--no-pick suppresses it for scripted use.

Also: picker/file-dialog windows force themselves to the foreground
(spawned from the GUI button, Windows opened them hidden behind the
GUI); unreadable or still-being-written (empty) CSVs are skipped with a
note instead of killing the run; fatal errors show a messagebox since
stderr is invisible when launched from the GUI.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:59:34 +07:00
janikandClaude Fable 5 ca5f0fe9c2 GUI: non-blocking disconnect, never close VISA sessions under the worker
Pressing Disconnect with the instruments powered off froze the GUI
(apparent crash, 2026-07-06 15:52): worker.join(5) expired while the
worker sat in multi-second VISA timeouts, then bench.close() ran on the
GUI thread -- each driver close() first writes local() to the dead
device (stacked timeouts) and closing a session under an in-flight read
can also take NI-VISA down natively.

_disconnect now detaches the UI immediately and runs all instrument
teardown on a background thread; if the worker is still stuck in I/O
after a 15s join the sessions are deliberately left open (OS reclaims
them at exit) instead of being closed under a live read. Reconnecting
while a teardown is still releasing the instruments is refused with a
console hint.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 16:59:20 +07:00
janikandClaude Fable 5 5b168439e8 GUI sweep: supply-trip protection after the 80V OVP shutdown
Run 2026-07-06 13:08: stepping 78->80V released the 46A load mid-ramp,
the supply output overshot to 80.46V and a protection (OVP by all log
evidence) shut it down; the sweep then logged garbage rows for the rest
of the grid. Three fixes:

- release the load down to l_start BEFORE each supply voltage step
  (down-steps only; descending load sweeps keep the gated path)
- OVP preflight: query the programmed OVP level at sweep start, abort
  under 2V margin above the sweep max, warn under 5V
- dead-supply abort: supply readback ~0V mid-sweep drops the garbage
  point, queries which protection fired (OVP/OV/OC/OP/OT) via
  _supply_trip_cause, reports it, and stops -- collected points are
  still ramped down and saved

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 14:49:07 +07:00
janikandClaude Fable 5 668ce30a1d GUI: I limit field is the environment input-current limit, no hardcoded 20A
The 20A PSU ceiling was hardcoded and clamped user entries, which breaks
benches with a different supply. Now the sweep I limit field IS the max
input current allowed for the test environment: used verbatim as the
supply CC limit and as the step-rejection / measured-backstop ceiling.
Manual supply-current clamp removed; manual CC/CP load gate now checks
against the I limit field value. PSU_MAX_CURRENT_A is reduced to
INPUT_LIMIT_DEFAULT_A (initial field value only).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 12:53:44 +07:00
janikandClaude Fable 5 7f8672d7b9 GUI: live STM32 telemetry + sweep guards + auto-logging + bench-plot
- stm32_link.py: port to the live 114-byte broadcast protocol (magic
  0xAA55AA55, odd parity 8-O-1, 100 Hz publish, repetition-validated,
  no CRC); 39 params incl. adc4_trig_phase/iin_zero_sum, CLEAR_FLAGS,
  30-bit flag table; commands stay CRC-16 framed; Telemetry aliases
  BroadcastData, efficiency uses iout_slow and eff_net subtracts P_sys
- gui_workers.py: STM32Worker reader thread with counter dedup, rate/
  loss counters, 20 s graph history, full-rate telemetry CSV writer
- gui.py: right-side telemetry panel (link state, power + EFF net,
  heatsink/board temps, Vfly group, control, HRTIM, status-flag
  checkboxes, fault registers), Vfly + selectable corr/phase-ofs
  graphs, 20 s rolling window on all plots, dual CSV logging (merged
  stm_* columns + <stem>_telem.csv), logging on by default into
  logs/data_<timestamp>.csv, Plot Eff button
- sweep guards: PSU 20 A input-current gate (conservative estimate +
  measured backstop + I-limit clamp), thermal pause at 57/77 C holding
  the load at 1 A until cooled 5 C below threshold, CC range pinned to
  R2 for the whole run with empirical range-max readback rejection
- plot_eff.py + bench-plot entry point: efficiency vs Vin vs current
  maps from any logged CSV (sweep / data log / telem autodetect), file
  dialog when launched without args
- bench.py: HIOKI FAST response speed, 5 s settle defaults; cli.py
  stm32-read prints the full broadcast; README + .gitignore updates

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-03 18:06:02 +07:00
janikandClaude Opus 4.8 606858228c gui: default load port COM11 to match this bench
Completes the port migration (CLI already defaults to COM11/COM4); the
GUI toolbar field still hardcoded COM1. Supply/meter stay "auto".

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 12:31:50 +07:00
janikandClaude Opus 4.8 d2dfc73f9e tooling: sync bench + debug console to live STM32 protocol
The mppt-testbench Python tooling had drifted from the flashed firmware
(bundled fw e7a23a3 vs live 1b85532) and could no longer communicate:

- stm32_link.py: CRC8 -> CRC-16/CCITT-FALSE; telemetry 68B -> 78B
  (btemp, cmp_outer/inner, iout_slow, vfly_ofs_applied); add PTYPE_INT16
  and commands 0x12-0x18; replace PARAMS with the current 37-param map
  (single dt_normal, no dt brackets; test_corr/phase_ofs, phase PI,
  precharge PI, duty dither; vfly_active 0-3).
- tuner.py: retire per-bracket deadtime; sweep the single dt_normal.
- cli.py: update tune-deadtime, help/examples, btemp readout;
  default ports COM11 (load) / COM4 (stm32).
- debug console TUI: sync protocol.py/app.py/status_bar/telemetry_panel
  from live (new command keys, link RX/TX/loss stats, single dead-time,
  new telemetry fields, param-write auto-retry); add duty_fft.py.
- README: rewrite parameter table, deadtime section, ports, keybindings.

Verified: protocol round-trip self-tests + live `bench stm32-read`
reading all 37 params over COM4.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-01 12:03:51 +07:00
grabowskiandClaude Opus 4.6 903fa78585 Add tune-param-vsweep command for parameter sweeps across voltage range
Automates running tune-param at multiple voltages, saves per-voltage
CSVs compatible with plot-tune, and prints a summary table.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 15:51:59 +07:00
grabowskiandClaude Opus 4.6 ce493204cb Add plot-tune command for multi-voltage parameter sweep analysis
Overlays efficiency curves from multiple CSV files (one per voltage),
finds per-voltage best and overall sweetspot (best average across all
voltages), and generates efficiency overlay, heatmap, and loss plots.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-13 11:40:42 +07:00
grabowskiandClaude Opus 4.6 1c41910c1e Add STM32 tuning integration and rewrite README with step-by-step guide
- stm32_link.py: synchronous serial interface to STM32 debug protocol
  (ping, telemetry read/avg, param read/write, frame parser)
- tuner.py: automated tuning combining HIOKI + STM32 measurements
  (param sweep, deadtime optimization, multi-point sweep, CSV/plot output)
- CLI commands: stm32-read, stm32-write, tune-param, tune-deadtime
- README: complete step-by-step guide covering setup, sweeps, analysis,
  tuning, shade profiles, debug console, and parameter reference

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 16:52:09 +07:00
grabowskiandClaude Opus 4.6 3f65b5f2f2 Add plot-sweep command, degauss buttons, sweep ramp-down, and time estimate
- Add offline `plot-sweep` CLI command: generates efficiency overlay,
  heatmap, and power loss plots from sweep CSV (no instruments needed)
- Add degauss buttons to CH5/CH6 in GUI (sends :DEMAg SCPI command)
- Gradual load ramp-down at end of 2D sweep to avoid transients
- Live sweep time estimate in GUI based on grid size × settle time
- Update HIOKI submodule to include degauss CLI command

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-12 16:31:33 +07:00
grabowskiandClaude Opus 4.6 5fe2ec4556 Fix VOLTage:RANGe? timeout and EFF overflow blocking sweeps
- Wrap get_voltage_range() in try/except since VOLTage:RANGe? is not
  supported on IT6537D — skip range check gracefully if unavailable
- Exclude derived EFF* values from auto-range error threshold check
  in _wait_meter_ready(), as efficiency overflows at near-zero power

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 17:06:13 +07:00
grabowskiandClaude Opus 4.6 04191259d6 Fix VISA timeout in 2D sweep: join worker thread before starting sweep
The worker thread was signaled to stop but never joined, causing bus
collisions when the sweep thread started talking to instruments while
the worker was still mid-query. Now:

- worker.join(timeout=10) before sweep starts
- 0.5s delay + clear supply error queue before first command
- join sweep thread before restarting worker after sweep completes
- Also join worker on disconnect

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:11:55 +07:00
grabowskiandClaude Opus 4.6 a0795302a9 Add CP mode sanity check: validate current limit vs power at min voltage
CP=500W at V=50V needs 10A on the load side — if the supply I_limit
is only 20A and the MPPT has conversion losses, this can cause the
supply to current-limit and timeout. The check now catches this upfront:

  CP check: 500W / 50V = 10.0A (limit 20.0A) OK

Also raises ValueError if the worst-case current exceeds the limit.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:06:48 +07:00
grabowskiandClaude Opus 4.6 3f46029204 Fix NameError in sweep error handler lambda
Python 3.13 deletes exception variables after the except block.
Capture the error string before passing to the lambda.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 16:02:16 +07:00
grabowskiandClaude Opus 4.6 aced4f1e23 Add CP load mode to 2D sweep and supply sanity checks
- 2D sweep now supports CC (constant current) and CP (constant power)
  load modes via --load-mode flag (CLI) and combobox (GUI)
- Supply capability check before all sweeps: validates max voltage
  against supply range and prints V/I/P summary
- Renamed sweep-vi args from --i-start/stop/step to --l-start/stop/step
  to reflect that the load setpoint can be current or power
- GUI labels update dynamically based on selected load mode

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 15:57:44 +07:00
grabowskiandClaude Opus 4.6 05f23d6417 Add HIOKI channel range controls and live range display
- GUI: voltage/current range selectors for Ch5 and Ch6 with AUTO option
- Worker: queries current V/I ranges each poll cycle, pushes to GUI
- Setting a fixed range automatically disables auto-range for that channel
- Live display shows current range values below each channel's readout

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 15:30:10 +07:00
grabowskiandClaude Opus 4.6 956be4b77a Add shade profiles, 2D V×I sweep, meter format toggle, ON/OFF indicators, and GUI console
- Shade profile: CSV-driven irradiance/voltage sequences with load control
  (bench.run_shade_profile, CLI shade-profile command, GUI profile panel)
- 2D sweep: voltage × load current efficiency map with live graph updates
  (bench.sweep_vi, CLI sweep-vi command, GUI sweep panel with background thread)
- GUI: meter format selector (scientific/normal), supply/load ON/OFF indicators,
  console log with stdout redirect and color-coded messages
- Sample profiles: cloud_pass, partial_shade, intermittent_clouds

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 15:27:48 +07:00
grabowskiandClaude Opus 4.6 74917e05f2 Arrange GUI controls in two columns: supply+load (left), meter (right)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:49:29 +07:00
grabowskiandClaude Opus 4.6 e2be7109b7 Add GUI control panel with live measurements and full instrument control
New `mppt-gui` command launches a tkinter app with:
- Live numeric readouts for all 13 measurement channels
- 4-panel real-time matplotlib graphs (power, efficiency, voltage, current)
- Full supply control: voltage, current, OVP, slew, output on/off
- Full load control: mode (CC/CR/CV/CP), setpoint, slew, load on/off
- Meter settings: wiring mode, response speed, coupling per channel
- CSV data logging with start/stop control
- Red SAFE OFF button (also Escape key) bypasses command queue
- Threaded architecture: instrument I/O never blocks the GUI
- Fix apply() silently failing: use set_current + set_voltage instead

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:42:07 +07:00
grabowskiandClaude Opus 4.6 e55caa59b1 Initial MPPT testbench: unified CLI for IT6500D + Prodigit 3366G + HIOKI 3193-10
Combines three instrument drivers (as git submodules) into a single
testbench for MPPT tracker efficiency testing. Features:
- Voltage sweep and load current sweep with CSV export
- Auto-range aware meter polling (waits for HIOKI to settle)
- Supply keepalive during long meter waits to prevent USB-TMC timeouts
- Live monitoring with real-time 4-panel matplotlib graphs
- Safe shutdown (load first, then supply)
- Post-sweep returns to 75V idle with supply ON

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-11 13:19:18 +07:00