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>
This commit is contained in:
2026-03-11 16:11:55 +07:00
parent a0795302a9
commit 04191259d6

View File

@@ -724,6 +724,7 @@ class TestbenchGUI(tk.Tk):
self._stop_log() self._stop_log()
if self.worker: if self.worker:
self.worker.stop() self.worker.stop()
self.worker.join(timeout=5)
self.worker = None self.worker = None
if self.bench: if self.bench:
try: try:
@@ -1130,9 +1131,11 @@ class TestbenchGUI(tk.Tk):
"success", "success",
) )
# Stop the normal worker so the sweep owns the instruments # Stop the normal worker and wait for it to finish so the
# sweep thread has exclusive access to the instrument bus
if self.worker: if self.worker:
self.worker.stop() self.worker.stop()
self.worker.join(timeout=10)
self.worker = None self.worker = None
# Restart _poll so it drains the sweep data queue # Restart _poll so it drains the sweep data queue
@@ -1190,6 +1193,13 @@ class TestbenchGUI(tk.Tk):
elif l_start > l_stop and l_step > 0: elif l_start > l_stop and l_step > 0:
l_step = -l_step l_step = -l_step
# Clear any stale state
time.sleep(0.5)
try:
bench.supply.get_error()
except Exception:
pass
# Sanity check # Sanity check
max_v = max(abs(v_start), abs(v_stop)) max_v = max(abs(v_start), abs(v_stop))
min_v = min(abs(v_start), abs(v_stop)) min_v = min(abs(v_start), abs(v_stop))
@@ -1312,6 +1322,9 @@ class TestbenchGUI(tk.Tk):
def _sweep_vi_done(self) -> None: def _sweep_vi_done(self) -> None:
self._btn_svi_run.config(state=tk.NORMAL) self._btn_svi_run.config(state=tk.NORMAL)
self._btn_svi_stop.config(state=tk.DISABLED) self._btn_svi_stop.config(state=tk.DISABLED)
# Wait for sweep thread to fully exit
if self._svi_thread:
self._svi_thread.join(timeout=5)
self._svi_thread = None self._svi_thread = None
self._svi_stop_event = None self._svi_stop_event = None
# Restart normal worker polling # Restart normal worker polling