@@ -25,10 +25,11 @@ async def run_loop(self):
25
25
pool = ThreadPoolExecutor (max_workers = 2 )
26
26
rx = self .loop .run_in_executor (pool , self ._run_rx )
27
27
tx = self .loop .run_in_executor (pool , self ._run_tx )
28
- await asyncio .gather (rx , tx )
28
+ main = self ._run_main_thread ()
29
+ await asyncio .gather (main , rx , tx )
29
30
30
31
def _run_tx (self ):
31
- while self .alive and self . serial . is_open :
32
+ while self .alive :
32
33
try :
33
34
data = self .tx_queue .get (block = True , timeout = 3 )
34
35
logging .debug (f'Write: { data } ' )
@@ -41,7 +42,7 @@ def _run_tx(self):
41
42
def _run_rx (self ):
42
43
# based on ReaderThread(threading.Thread) from:
43
44
# https://github.com/pyserial/pyserial/blob/master/serial/threaded/__init__.py
44
- while self .alive and self . serial . is_open :
45
+ while self .alive :
45
46
data = self .serial .read (1 ) # request 1 to block
46
47
n = min (self .mtu - 1 , self .serial .in_waiting ) # read the remaning, can be 0
47
48
data += self .serial .read (n )
@@ -50,6 +51,15 @@ def _run_rx(self):
50
51
51
52
logging .debug (f'RX loop ended, alive={ self .alive } open={ self .serial .is_open } ' )
52
53
54
+ async def _run_main_thread (self ):
55
+ # Dummy work in main thread, it has to run to detect signals (e.g. ctrl-C)
56
+ # https://stackoverflow.com/a/29237343
57
+ # we can also use it to check if the serial is still open, instead of doing that in every thread
58
+ while self .alive :
59
+ self .alive = False if not self .serial .is_open else self .alive
60
+ await asyncio .sleep (0.5 )
61
+
62
+
53
63
def stop_loop (self ):
54
64
self .alive = False
55
65
logging .info ('Stopping RX+TX loop' )
0 commit comments