Skip to content

fix(telemetrix): a dropped serial link reads as disconnected - #181

Merged
gbradham merged 1 commit into
mainfrom
claude/glider-loop-cutout-issue-a96403
Sep 18, 2026
Merged

gbradham merged 1 commit into
mainfrom
claude/glider-loop-cutout-issue-a96403

Conversation

@gbradham

Copy link
Copy Markdown
Member

Problem

An experiment on an infinite Loop driving an Arduino would run for a while, then the hardware stopped responding. Nothing was logged.

When the USB serial link drops, telemetrix-aio's TelemetrixAioSerial.write() catches the SerialException, closes the port, waits one second and returns None. We pass close_loop_on_shutdown=False, so it never raises and never stops its event loop. The worker thread stays alive, TelemetrixBoard.is_connected stays True, and every later digital_write looks like it worked while nothing reaches the board.

The one thing that does fail with the port is telemetrix's report reader (the_task). It dies on the first in_waiting poll, and its exception is stored on a task that nothing ever reads, so it is never logged either.

Fix

TelemetrixThread.is_running now also requires the report reader to be alive. A reader that ended because of a deliberate shutdown() still counts as alive. A new link_error property gives the reason. is_connected already checks is_running before every read and write, so after a drop:

  • the log says why, e.g. Telemetrix link lost (OSError(6, 'Device not configured')) - marking as disconnected
  • the board goes DISCONNECTED, and the next write raises Board not connected
  • MainWindow._on_hardware_connection_change pauses the running experiment and shows the hardware-disconnection dialog (existing behavior)

Not covered

An Arduino that resets without the USB link dropping (motor noise, brownout) keeps the port open, so writes still go through and the reset board ignores them. Catching that needs a heartbeat to the board.

Testing

  • New test_dropped_serial_link_reads_as_disconnected: fails on main, passes here.
  • Checked against telemetrix-aio's real _arduino_report_dispatcher and TelemetrixAioSerial with a port that drops partway through a run: the board reports disconnected while the thread is still alive, and the next write raises.
  • tests/: 4759 passed. Plugin suites were not run locally.
  • ruff and black are clean on the changed files.
  • Not yet tried on a real Arduino.

Once the USB link drops, telemetrix-aio's serial write catches the
SerialException, sleeps a second and returns None. With
close_loop_on_shutdown=False (what we pass) it neither raises nor stops
its loop, so the worker thread stays alive, is_connected stays True, and
every later write "succeeds" while the rig does nothing. An experiment
on an infinite Loop just stops moving, with nothing in the log.

The one thing that does die with the port is telemetrix's report reader
task. is_running now also requires that task to be alive (unless a
deliberate shutdown ended it), so the existing is_connected path marks
the board DISCONNECTED, logs the cause, and the GUI's pause-on-drop
dialog fires on the next write.

An Arduino that resets without the USB link dropping (motor noise,
brownout) is still undetected; that needs a heartbeat.
@gbradham
gbradham merged commit c7f666d into main Sep 18, 2026
7 of 8 checks passed
@gbradham
gbradham deleted the claude/glider-loop-cutout-issue-a96403 branch September 18, 2026 15:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant