Skip to content

mpremote: Add automatic reconnect feature. #17322

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

andrewleech
Copy link
Contributor

Summary

This PR adds automatic reconnection capability to the mpremote tool. When a MicroPython device disconnects, mpremote can now automatically reconnect to the same device, eliminating the need to manually
restart the tool during development.

The new reconnect command enables automatic reconnection to the exact same port, even when using auto mode. This is particularly important in multi-device environments where you want to ensure reconnection to the same physical device.

Key features:

  • New reconnect command that works like resume (standalone command, not a flag)
  • Always reconnects to the exact same port that was previously connected when originally started in connect auto mode
  • Always reconnects to the exact same device (on any port) when started in connect id:abc123 mode.
  • Preserves resume state through reconnections
  • Handles Windows COM port timing issues with retry logic

Usage:

mpremote reconnect
mpremote connect id:cc8da28c04c40000 reconnect repl
mpremote connect /dev/ttyACM0 reconnect

This PR builds on top of #17321 which improves disconnect message handling.

Testing

Testing was performed on:

  • Windows 11 with ESP32S2 devices connected via USB (COM ports)
  • Linux (Ubuntu WSL) with ESP32S2 devices connected via USB (/dev/ttyACM*)

Tested scenarios:

  • Basic reconnection after device unplug/replug cycles
  • Using auto mode and verifying it reconnects to the same specific port (e.g., only /dev/ttyACM2)
  • Windows-specific COM port timing issues requiring multiple connection attempts
  • Multiple devices present to verify it only reconnects to the original device
  • Connection types: auto, specific ports, and device serial numbers (id:)

All tests confirmed that the tool reliably reconnects to the same physical device.

Trade-offs and Alternatives

The implementation adds minimal code complexity and has no impact on users who don't use the reconnect feature. The reconnect command is opt-in and doesn't affect existing behavior.

Design decisions:

  • Implemented as a standalone command rather than a --reconnect flag for consistency with other mpremote commands like resume
  • Always reconnects to the exact same port (even in auto mode) rather than any available device, prioritizing safety in multi-device environments
  • Added retry logic with delays specifically for Windows COM port timing issues

The only trade-off is a small increase in code size from the reconnect logic, which is justified by the significant improvement in developer workflow.

- Handle SerialException on Windows when device disconnects
- Print clean 'device disconnected' message instead of stack trace
- Fix terminal formatting issues on Linux after disconnect
- Return disconnected state after console cleanup to avoid terminal issues

This ensures proper disconnect messages on both platforms without
showing confusing error traces to users.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
Copy link

codecov bot commented May 19, 2025

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 98.54%. Comparing base (45e4deb) to head (4741c7c).
Report is 77 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #17322      +/-   ##
==========================================
- Coverage   98.54%   98.54%   -0.01%     
==========================================
  Files         169      169              
  Lines       21898    21898              
==========================================
- Hits        21580    21579       -1     
- Misses        318      319       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link

Code size report:

   bare-arm:    +0 +0.000% 
minimal x86:    +0 +0.000% 
   unix x64:    +0 +0.000% standard
      stm32:    +0 +0.000% PYBV10
     mimxrt:    +0 +0.000% TEENSY40
        rp2:    +0 +0.000% RPI_PICO_W
       samd:    +0 +0.000% ADAFRUIT_ITSYBITSY_M4_EXPRESS
  qemu rv32:    +0 +0.000% VIRT_RV32

@Josverl
Copy link
Contributor

Josverl commented May 19, 2025

Thanks for the effort.

Implemented as a standalone command rather than a --reconnect flag for consistency with other mpremote commands like resume

I have never liked that I find myself needing to type 'resume' to 95% of the commands.
I think that that resume and reconnect should be the default state, as that is what most users will expect.

  • I think the main use for soft resetting before each command is automated testing, and there adding a reset is simple. But changing that behavior will need some thought, as it may be a breaking change for tools that depend on it ( although the docs say they should not)

But for this very welcome reconnect behavior, I would propose this to be the default, and to be opted out via --no-reconnect/--nrc or environment variable.

That will make the "how do we educate this" so much simpler,
Note that the resume/no-reset behavior appears to be the default for reconnect.

Physical disconnection of a battery powered board with a running script.

mpremote reconnect
Connected to MicroPython at COM10
Use Ctrl-] or Ctrl-x to exit this shell

>>> import time
>>> x=1
>>> while 1:
...     time.sleep(1)
...     print("hoi",x) 
...     x+=1
...     
...     
... 
hoi 1
hoi 2
hoi 3
hoi 4
hoi 5
hoi 6
hoi 7
hoi 8
# Unplug USB 
Device disconnected
Waiting for reconnection on COM10...
# Reconnect USB 
Connected to MicroPython at COM10
Use Ctrl-] or Ctrl-x to exit this shell
hoi 12
hoi 13
hoi 14
hoi 15
# .... snip
hoi 24
hoi 25
hoi 26
# Pressed Ctrl-]
(micropython) PS D:\mypython\micropython> mpremote reconnect
Connected to MicroPython at COM10
Use Ctrl-] or Ctrl-x to exit this shell
hoi 30
hoi 31
hoi 32
hoi 33
hoi 34
hoi 35
hoi 36
hoi 37
hoi 38
hoi 39

@andrewleech andrewleech force-pushed the mpremote_reconnect branch from 66a38bb to 70057c8 Compare May 19, 2025 09:58
@andrewleech
Copy link
Contributor Author

Thanks @Josverl for bringing up the defaults!

Yes I too have thought it would be better to have resume the default, but not entirely sure of what the range of user effects this might have. I do think resume would be less confusing for many people, with an optional reset to be used to invert that.

I'm certainly interested in this new reconnect feature being on by default, I expect to use it as my default by adding it to the local config file etc at the very least. I'd certainly be happy to make that change if we get such a concensus from the maintainers!

@andrewleech andrewleech changed the title Mpremote reconnect mpremote: Add automatic reconnect feature. May 19, 2025
@Josverl
Copy link
Contributor

Josverl commented May 19, 2025

adding it to the local config file etc at the very least.

AFAIK mpremote finding its config file is still broken on Windows - #9573 would be needed for that

@dpgeorge dpgeorge added the tools Relates to tools/ directory in source, or other tooling label May 20, 2025
This adds a `reconnect` command that enables automatic reconnection
when a device disconnects. The reconnect feature:

- For direct port connections: reconnects to the exact same port
- For `id:` connections: recoonect to same device on any port
- Shows clear status messages during reconnection
- Preserves resume state through reconnections
- Handles Windows timing issues with retry logic

Usage: mpremote connect auto reconnect repl
       mpremote connect id:1234567890 reconnect repl

The reconnect command behaves differently based on connection type:
- For `auto` and direct ports: only reconnects to the exact same port
- For `id:` connections: finds the device on any available port

This prevents accidental connections to different devices when using auto
mode, while allowing id-based connections to find the device wherever it
reappears.

Signed-off-by: Andrew Leech <andrew.leech@planetinnovation.com.au>
@andrewleech andrewleech force-pushed the mpremote_reconnect branch from 70057c8 to 4741c7c Compare May 26, 2025 01:25
@andrewleech
Copy link
Contributor Author

#17222 adds weight to the suggestion to make resume the default.

Particularly as more users leverage dynamic USB configuration having mpremote silently perform a soft reset is disruptive and confusing.

@Josverl
Copy link
Contributor

Josverl commented Jun 4, 2025

As I usually have multiple boards connected, I frequently want mpremote to (re)connect to a specific one.
I find the CLI for that different to my initial expectations.

Use Case connect syntax Expected Actual
auto mpremote mpremote reconnect mpremote reconnect 👌
COM3: mpremote com3 or mpremote connect com3 mpremote reconnect com3 mpremote com3 reconnect 😕
COM8: mpremote connect COM8 mpremote reconnect COM8 mpremote connect com8 reconnect 😕😕

Similar on linux

Even without changing default behavior, it would make a lot more sense to me if I can use the same syntax for both the connect and reconnect commands.
(possibly sharing the same implementation.)

The more complex the commands get, the more confused I get;

As an example:
To set time before connecting:

  • mpremote connect com8 rtc --set exec "import time;print(time.localtime())" repl

perhaps becomes :

  • mpremote connect com8 rtc --set exec "import time;print(time.localtime())" reconnect repl
  • mpremote connect com8 reconnect rtc --set exec "import time;print(time.localtime())" reconnect repl

I have not been able to find a form that actually reconnects for this use case,
But I think it would be quite useful to set the time / connect to wifi and similar in such a scenario.

@andrewleech
Copy link
Contributor Author

Thanks for the feedback @Josverl yes having reconnect as a separate command is not as intuitive as I'd first thought.
However I'm actually just about to push a change to make reconnect the default, with a connect --once <auto/port> option to reverse the behaviour.
I'm also going to push a separate PR to make resume the default, I believe there's support for that more broadly now.

@projectgus projectgus self-requested a review June 5, 2025 01:51
@projectgus projectgus removed their request for review June 13, 2025 02:09
@projectgus
Copy link
Contributor

@andrewleech Changing the defaults like this sounds very sensible to me! Feel free to request a review from me after you've had time to update.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
tools Relates to tools/ directory in source, or other tooling
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy