Skip to content

Commit bc1664d

Browse files
committed
Work around RTS/DTR serial reset issues on Windows
Some devices (e.g. Heltec V3.1) are reset when the RTS or DTR pins are messed with, which means that without workarounds, Meshtastic CLI will cause a reset with any operation that opens the serial port. This behavior is documented in this PySerial issue: pyserial/pyserial#124 On Linux, we already handle this by disabling the HUPCL termios flag, which has the effect of preventing the offending lines being toggled. On Windows, setting the initial state of RTS and DTR before opening the port has a similar effect. Implement this workaround so that Meshtastic CLI can be used on Windows with these devices.
1 parent 32a61b0 commit bc1664d

File tree

1 file changed

+13
-4
lines changed

1 file changed

+13
-4
lines changed

meshtastic/serial_interface.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,12 @@ def __init__(self, devPath: Optional[str]=None, debugOut=None, noProto: bool=Fal
4646

4747
logging.debug(f"Connecting to {self.devPath}")
4848

49-
# first we need to set the HUPCL so the device will not reboot based on RTS and/or DTR
49+
# set port to None to prevent automatically opening
50+
self.stream = serial.Serial(
51+
port=None, baudrate=115200, exclusive=True, timeout=0.5, write_timeout=0
52+
)
53+
54+
# first we need to clear HUPCL (UNIX) or clear RTS/DTR (Windows) so the device will not reboot based on RTS and/or DTR
5055
# see https://github.com/pyserial/pyserial/issues/124
5156
if platform.system() != "Windows":
5257
with open(self.devPath, encoding="utf8") as f:
@@ -55,10 +60,14 @@ def __init__(self, devPath: Optional[str]=None, debugOut=None, noProto: bool=Fal
5560
termios.tcsetattr(f, termios.TCSAFLUSH, attrs)
5661
f.close()
5762
time.sleep(0.1)
63+
else:
64+
self.stream.rts = 0
65+
self.stream.dtr = 0
66+
67+
# set proper port and open now that we've worked-around RTS/DTR issues
68+
self.stream.port = self.devPath
69+
self.stream.open()
5870

59-
self.stream = serial.Serial(
60-
self.devPath, 115200, exclusive=True, timeout=0.5, write_timeout=0
61-
)
6271
self.stream.flush() # type: ignore[attr-defined]
6372
time.sleep(0.1)
6473

0 commit comments

Comments
 (0)