Skip to content

Commit 0f23b1e

Browse files
author
luoja
committed
sleep change to winapi for precise time, Supplementary variable poll_interval implementation, add variable - receive_own_messages
1 parent bf541d9 commit 0f23b1e

File tree

1 file changed

+35
-7
lines changed

1 file changed

+35
-7
lines changed

can/interfaces/slcan.py

Lines changed: 35 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
from queue import Queue, Empty
1010
import threading
1111
from serial.tools import list_ports
12+
import platform
1213
from can import BusABC, CanProtocol, Message, typechecking
1314

1415
from ..exceptions import (
@@ -29,6 +30,18 @@
2930
serial = None
3031

3132

33+
HAS_EVENTS = False
34+
35+
try:
36+
from _overlapped import CreateEvent
37+
from _winapi import WaitForSingleObject
38+
39+
HAS_EVENTS = True
40+
except ImportError:
41+
WaitForSingleObject = None
42+
HAS_EVENTS = False
43+
44+
3245
class slcanBus(BusABC):
3346
"""
3447
slcan interface
@@ -49,6 +62,7 @@ class slcanBus(BusABC):
4962
}
5063

5164
_SLEEP_AFTER_SERIAL_OPEN = 2 # in seconds
65+
_POLL_INTERVAL = 0.001
5266

5367
_OK = b"\r"
5468
_ERROR = b"\a"
@@ -61,6 +75,8 @@ def __init__(
6175
ttyBaudrate: int = 115200,
6276
bitrate: Optional[int] = None,
6377
btr: Optional[str] = None,
78+
poll_interval: float = _POLL_INTERVAL,
79+
receive_own_messages: bool = False,
6480
sleep_after_open: float = _SLEEP_AFTER_SERIAL_OPEN,
6581
rtscts: bool = False,
6682
listen_only: bool = False,
@@ -77,6 +93,8 @@ def __init__(
7793
Bitrate in bit/s
7894
:param btr:
7995
BTR register value to set custom can speed
96+
:param receive_own_messages:
97+
See :class:`can.BusABC`.
8098
:param poll_interval:
8199
Poll interval in seconds when reading messages
82100
:param sleep_after_open:
@@ -94,6 +112,8 @@ def __init__(
94112
:raise CanInitializationError: if the underlying serial connection could not be established
95113
"""
96114
self._listen_only = listen_only
115+
self.poll_interval = poll_interval
116+
self.receive_own_messages = receive_own_messages
97117

98118
if serial is None:
99119
raise CanInterfaceNotImplementedError("The serial module is not installed")
@@ -126,17 +146,18 @@ def __init__(
126146
self.set_bitrate_reg(btr)
127147
self.open()
128148

149+
self._timestamp_offset = time.time() - time.perf_counter()
150+
self.queue_read = Queue()
151+
self.event_read = threading.Event()
152+
self._recv_event = CreateEvent(None, 0, 0, None) if HAS_EVENTS else None
153+
threading.Thread(None, target=self._read_can_thread, args=(self.event_read,)).start()
129154
super().__init__(
130155
channel,
131156
ttyBaudrate=115200,
132157
bitrate=None,
133158
rtscts=False,
134159
**kwargs,
135160
)
136-
self._timestamp_offset = time.time() - time.perf_counter()
137-
self.queue_read = Queue()
138-
self.event_read = threading.Event()
139-
threading.Thread(None, target=self._read_can_thread, args=(self.event_read,)).start()
140161

141162
def set_bitrate(self, bitrate: int) -> None:
142163
"""
@@ -190,12 +211,15 @@ def _recv_internal(self, timeout: Optional[float]):
190211
except Empty:
191212
return None, False
192213

193-
def _read_can_thread(self, event_recv_send_batch_zlg):
194-
while not event_recv_send_batch_zlg.is_set():
214+
def _read_can_thread(self, event_read):
215+
while not event_read.is_set():
195216
msgs = self._read_can()
196217
for i in msgs:
197218
self.queue_read.put(i)
198-
time.sleep(0.005)
219+
if HAS_EVENTS:
220+
WaitForSingleObject(self._recv_event, int(self.poll_interval * 1000))
221+
else:
222+
time.sleep(self.poll_interval)
199223

200224
def _read_can(self) -> List[Message]:
201225
canId = None
@@ -274,6 +298,10 @@ def send(self, msg: Message, timeout: Optional[float] = None) -> None:
274298
else:
275299
sendStr = f"t{msg.arbitration_id:03X}{msg.dlc:d}"
276300
sendStr += msg.data.hex().upper()
301+
if self.receive_own_messages:
302+
msg.is_rx = False
303+
msg.timestamp = self._timestamp_offset + time.perf_counter() # Better than nothing...
304+
self.queue_read.put(msg)
277305
self._write(sendStr)
278306

279307
def shutdown(self) -> None:

0 commit comments

Comments
 (0)