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>
This commit is contained in:
janik
2026-07-03 18:06:02 +07:00
co-authored by Claude Fable 5
parent 606858228c
commit 7f8672d7b9
10 changed files with 1652 additions and 274 deletions
+6 -6
View File
@@ -138,7 +138,7 @@ class MPPTTestbench:
self.meter.set_current_auto(5, True)
self.meter.set_voltage_auto(6, True)
self.meter.set_current_auto(6, True)
self.meter.set_response_speed("SLOW")
self.meter.set_response_speed("FAST")
self.meter.set_efficiency(1, "P6", "P5")
# Display: 16-item SELECT view
@@ -300,7 +300,7 @@ class MPPTTestbench:
v_stop: float,
v_step: float,
current_limit: float,
settle_time: float = 1.0,
settle_time: float = 5.0,
load_setpoint: float = 0.0,
) -> list[SweepPoint]:
"""Sweep supply voltage and record measurements at each point.
@@ -366,7 +366,7 @@ class MPPTTestbench:
i_start: float,
i_stop: float,
i_step: float,
settle_time: float = 1.0,
settle_time: float = 5.0,
) -> list[SweepPoint]:
"""Sweep load current (CC mode) at a fixed supply voltage.
@@ -473,7 +473,7 @@ class MPPTTestbench:
def run_shade_profile(
self,
steps: list[dict],
settle_time: float = 2.0,
settle_time: float = 5.0,
) -> list[SweepPoint]:
"""Run a shade / irradiance profile sequence.
@@ -629,7 +629,7 @@ class MPPTTestbench:
l_stop: float,
l_step: float,
current_limit: float,
settle_time: float = 2.0,
settle_time: float = 5.0,
load_mode: str = "CC",
) -> list[SweepPoint]:
"""2D sweep: voltage (outer) × load setpoint (inner).
@@ -770,7 +770,7 @@ class MPPTTestbench:
self,
voltage: float,
current_limit: float,
settle_time: float = 2.0,
settle_time: float = 5.0,
samples: int = 5,
sample_interval: float = 1.0,
) -> dict[str, float]: