30
30
from .stage import Stage
31
31
32
32
33
- class CNCStatus (Enum ):
33
+ class CNCStatus (str , Enum ):
34
34
IDLE = "Idle"
35
35
RUN = "Run"
36
36
HOLD = "Hold"
@@ -40,6 +40,14 @@ class CNCStatus(Enum):
40
40
CHECK = "Check"
41
41
42
42
43
+ class CNCError (Exception ):
44
+ """Exception raised when a specific error is detected by the CNC"""
45
+
46
+ def __init__ (self , message : str , cncstatus : CNCStatus ):
47
+ super ().__init__ (message )
48
+ self .cncstatus = cncstatus
49
+
50
+
43
51
class CNCRouter (Stage ):
44
52
"""
45
53
Class to command CNC routers.
@@ -168,9 +176,15 @@ def get_current_status(self) -> Optional[Tuple[CNCStatus, dict]]:
168
176
:return: A tuple containing the status and a dictionary of all other parameters in the
169
177
output of the command.
170
178
"""
179
+
171
180
self .send ("?" , eol = "" )
172
181
status = self .receive ()
173
182
183
+ # Retry, sometimes it does not respond
184
+ if status == b"" :
185
+ self .send ("?" , eol = "" )
186
+ status = self .receive ()
187
+
174
188
# Sometimes, the CNC returns 'ok' and the actual response is following.
175
189
while status == "ok" :
176
190
status = self .receive ()
@@ -179,8 +193,15 @@ def get_current_status(self) -> Optional[Tuple[CNCStatus, dict]]:
179
193
if status is None :
180
194
return None
181
195
182
- # The output
196
+ # The possible outputs
183
197
# '<Idle|MPos:1.000,3.000,4.000|FS:0,0|WCO:0.000,0.000,0.000>'
198
+ # 'ALARM:1'
199
+
200
+ if status .startswith ("ALARM:1" ):
201
+ # The ALARM message is followed by something like
202
+ # '[MSG:Reset to continue]'
203
+ next = self .receive ()
204
+ raise CNCError (next , CNCStatus .ALARM )
184
205
185
206
# Discard any unwanted format
186
207
if not (status .startswith ("<" ) and status .endswith (">" )):
@@ -237,10 +258,17 @@ def receive(self) -> str:
237
258
238
259
:return: Received response string, CR-LF removed.
239
260
"""
261
+ tries = 10
240
262
# Read at least 2 bytes for CR-LF.
241
263
response = self .serial .read (2 )
242
264
while response [- 2 :] != b"\r \n " :
243
- response += self .serial .read (1 )
265
+ part = self .serial .read (1 )
266
+ response += part
267
+ # Give a chance to get out of this
268
+ if part == b"" :
269
+ tries -= 1
270
+ if tries == 0 :
271
+ return b""
244
272
# Remove CR-LF and return as string
245
273
return response [:- 2 ].decode ()
246
274
0 commit comments