@@ -47,7 +47,10 @@ class slcanBus(BusABC):
47
47
48
48
_SLEEP_AFTER_SERIAL_OPEN = 2 # in seconds
49
49
50
+ LINE_TERMINATOR = b'\r '
51
+
50
52
def __init__ (self , channel , ttyBaudrate = 115200 , bitrate = None ,
53
+ sleep_after_open = _SLEEP_AFTER_SERIAL_OPEN ,
51
54
rtscts = False , ** kwargs ):
52
55
"""
53
56
:param str channel:
@@ -59,6 +62,8 @@ def __init__(self, channel, ttyBaudrate=115200, bitrate=None,
59
62
Bitrate in bit/s
60
63
:param float poll_interval:
61
64
Poll interval in seconds when reading messages
65
+ :param float sleep_after_open:
66
+ Time to wait in seconds after opening serial connection
62
67
:param bool rtscts:
63
68
turn hardware handshake (RTS/CTS) on and off
64
69
"""
@@ -72,7 +77,9 @@ def __init__(self, channel, ttyBaudrate=115200, bitrate=None,
72
77
self .serialPortOrig = serial .serial_for_url (
73
78
channel , baudrate = ttyBaudrate , rtscts = rtscts )
74
79
75
- time .sleep (self ._SLEEP_AFTER_SERIAL_OPEN )
80
+ self ._buffer = bytearray ()
81
+
82
+ time .sleep (sleep_after_open )
76
83
77
84
if bitrate is not None :
78
85
self .close ()
@@ -87,9 +94,7 @@ def __init__(self, channel, ttyBaudrate=115200, bitrate=None,
87
94
bitrate = None , rtscts = False , ** kwargs )
88
95
89
96
def write (self , string ):
90
- if not string .endswith ('\r ' ):
91
- string += '\r '
92
- self .serialPortOrig .write (string .encode ())
97
+ self .serialPortOrig .write (string .encode () + self .LINE_TERMINATOR )
93
98
self .serialPortOrig .flush ()
94
99
95
100
def open (self ):
@@ -107,12 +112,20 @@ def _recv_internal(self, timeout):
107
112
extended = False
108
113
frame = []
109
114
110
- readStr = self .serialPortOrig .read_until (b'\r ' )
115
+ # Read everything that is already available
116
+ waiting = self .serialPortOrig .read (self .serialPortOrig .in_waiting )
117
+ self ._buffer += waiting
111
118
112
- if not readStr :
113
- return None , False
114
- else :
115
- readStr = readStr .decode ()
119
+ # Check if a complete message has been received
120
+ pos = self ._buffer .find (self .LINE_TERMINATOR )
121
+ if pos == - 1 :
122
+ # Keep reading...
123
+ self ._buffer += self .serialPortOrig .read_until (self .LINE_TERMINATOR )
124
+ pos = self ._buffer .find (self .LINE_TERMINATOR )
125
+
126
+ if pos != - 1 :
127
+ readStr = self ._buffer [0 :pos ].decode ()
128
+ del self ._buffer [0 :pos + 1 ]
116
129
if readStr [0 ] == 'T' :
117
130
# extended frame
118
131
canId = int (readStr [1 :9 ], 16 )
@@ -129,45 +142,46 @@ def _recv_internal(self, timeout):
129
142
elif readStr [0 ] == 'r' :
130
143
# remote frame
131
144
canId = int (readStr [1 :4 ], 16 )
145
+ dlc = int (readStr [4 ])
132
146
remote = True
133
147
elif readStr [0 ] == 'R' :
134
148
# remote extended frame
135
149
canId = int (readStr [1 :9 ], 16 )
150
+ dlc = int (readStr [9 ])
136
151
extended = True
137
152
remote = True
138
153
139
154
if canId is not None :
140
155
msg = Message (arbitration_id = canId ,
141
- extended_id = extended ,
156
+ is_extended_id = extended ,
142
157
timestamp = time .time (), # Better than nothing...
143
158
is_remote_frame = remote ,
144
159
dlc = dlc ,
145
160
data = frame )
146
161
return msg , False
147
- else :
148
- return None , False
162
+ return None , False
149
163
150
- def send (self , msg , timeout = 0 ):
164
+ def send (self , msg , timeout = None ):
151
165
if timeout != self .serialPortOrig .write_timeout :
152
166
self .serialPortOrig .write_timeout = timeout
153
167
154
168
if msg .is_remote_frame :
155
169
if msg .is_extended_id :
156
- sendStr = "R%08X0 " % (msg .arbitration_id )
170
+ sendStr = "R%08X%d " % (msg .arbitration_id , msg . dlc )
157
171
else :
158
- sendStr = "r%03X0 " % (msg .arbitration_id )
172
+ sendStr = "r%03X%d " % (msg .arbitration_id , msg . dlc )
159
173
else :
160
174
if msg .is_extended_id :
161
175
sendStr = "T%08X%d" % (msg .arbitration_id , msg .dlc )
162
176
else :
163
177
sendStr = "t%03X%d" % (msg .arbitration_id , msg .dlc )
164
178
165
- for i in range (0 , msg .dlc ):
166
- sendStr += "%02X" % msg .data [i ]
179
+ sendStr += "" .join (["%02X" % b for b in msg .data ])
167
180
self .write (sendStr )
168
181
169
182
def shutdown (self ):
170
183
self .close ()
184
+ self .serialPortOrig .close ()
171
185
172
186
def fileno (self ):
173
187
if hasattr (self .serialPortOrig , 'fileno' ):
0 commit comments