@@ -94,6 +94,7 @@ def __init__(self, com_port: str, baud_rate: int, verbose: bool = False):
9494 #: float: Last time a command was sent to the MS2000 Controller
9595 self ._last_cmd_send_time = time .perf_counter ()
9696
97+
9798 @staticmethod
9899 def scan_ports () -> list [str ]:
99100 """Scans for available COM ports
@@ -109,6 +110,7 @@ def scan_ports() -> list[str]:
109110 com_ports .sort (key = lambda value : int (value [3 :]))
110111 return com_ports
111112
113+
112114 def connect_to_serial (
113115 self ,
114116 rx_size : int = 12800 ,
@@ -143,8 +145,6 @@ def connect_to_serial(
143145
144146 # set the size of the rx and tx buffers before calling open
145147 self .serial_port .set_buffer_size (rx_size , tx_size )
146-
147- # try to open the serial port
148148 try :
149149 self .serial_port .open ()
150150 except SerialException :
@@ -164,7 +164,8 @@ def connect_to_serial(
164164 )
165165
166166 #: list[str]: Default axes sequence of the MS2000 Controller
167- self .default_axes_sequence = self .get_default_motor_axis_sequence ()
167+ self .default_axes_sequence = ["X" , "Y" , "Z" ] # self.get_default_motor_axis_sequence()
168+
168169
169170 def get_default_motor_axis_sequence (self ) -> None :
170171 """Get the default motor axis sequence from the ASI device
@@ -187,6 +188,7 @@ def get_default_motor_axis_sequence(self) -> None:
187188
188189 return default_axes_sequence
189190
191+
190192 def set_feedback_alignment (self , axis , aa ):
191193 """Set the stage feedback alignment.
192194
@@ -200,6 +202,7 @@ def set_feedback_alignment(self, axis, aa):
200202 self .send_command (f"AZ { axis } \r " )
201203 self .read_response ()
202204
205+
203206 def set_backlash (self , axis , val ):
204207 """Enable/disable stage backlash correction.
205208
@@ -210,10 +213,10 @@ def set_backlash(self, axis, val):
210213 val : float
211214 Distance of anti-backlash motion [mm]
212215 """
213- cmd_str = f"B { axis } ={ val :.7f} \r "
214216 self .send_command (f"B { axis } ={ val :.7f} \r " )
215217 self .read_response ()
216218
219+
217220 def set_finishing_accuracy (self , axis , ac ):
218221 """Set the stage finishing accuracy.
219222
@@ -227,6 +230,7 @@ def set_finishing_accuracy(self, axis, ac):
227230 self .send_command (f"PC { axis } ={ ac :.7f} \r " )
228231 self .read_response ()
229232
233+
230234 def set_error (self , axis , ac ):
231235 """
232236 Set the stage drift error
@@ -240,14 +244,15 @@ def set_error(self, axis, ac):
240244 """
241245 self .send_command (f"E { axis } ={ ac :.7f} \r " )
242246 self .read_response ()
243-
247+
244248
245249 def disconnect_from_serial (self ) -> None :
246250 """Disconnect from the serial port if it's open."""
247251 if self .is_open ():
248252 self .serial_port .close ()
249253 self .report_to_console ("Disconnected from the serial port." )
250254
255+
251256 def is_open (self ) -> bool :
252257 """Returns True if the serial port exists and is open.
253258
@@ -259,6 +264,7 @@ def is_open(self) -> bool:
259264 # short circuits if serial port is None
260265 return self .serial_port and self .serial_port .is_open
261266
267+
262268 def report_to_console (self , message : str ) -> None :
263269 """Print message to the output device, usually the console.
264270
@@ -268,10 +274,10 @@ def report_to_console(self, message: str) -> None:
268274 Message to print to the output device
269275 """
270276 # useful if we want to output data to something other than the console
271- # (ui element etc)
272277 if self .verbose :
273278 print (message )
274279
280+
275281 def wait_for_device (self , report : bool = False ) :
276282 """Waits for the all motors to stop moving."""
277283 if not report :
@@ -283,6 +289,7 @@ def wait_for_device(self, report: bool = False) :
283289 busy = self .is_device_busy ()
284290 self .report = temp
285291
292+
286293 def send_command (self , cmd : bytes ) -> None :
287294 """Send a serial command to the device.
288295
@@ -309,6 +316,7 @@ def send_command(self, cmd: bytes) -> None:
309316
310317 # sleep to avoid error, emperically found this made it work
311318 time .sleep (0.1 )
319+
312320
313321 def read_response (self ) -> str :
314322 """Read a line from the serial response.
@@ -320,16 +328,15 @@ def read_response(self) -> str:
320328 """
321329 response = self .serial_port .readline ()
322330 self .safe_to_write .set ()
323-
324331 response = response .decode (encoding = "ascii" )
325332 # Remove leading and trailing empty spaces
326333 self .report_to_console (f"Received Response: { response .strip ()} " )
327-
328334 if response .startswith (":N" ):
329335 raise MS2000Exception (response )
330336
331337 return response # in case we want to read the response
332338
339+
333340 def moverel (self , x : int = 0 , y : int = 0 , z : int = 0 ) -> None :
334341 """Move the stage with a relative move on multiple axes.
335342
@@ -345,6 +352,7 @@ def moverel(self, x: int = 0, y: int = 0, z: int = 0) -> None:
345352 self .send_command (f"MOVREL X={ x } Y={ y } Z={ z } \r " )
346353 self .read_response ()
347354
355+
348356 def moverel_axis (self , axis : str , distance : float ) -> None :
349357 """Move the stage with a relative move on one axis
350358
@@ -358,6 +366,7 @@ def moverel_axis(self, axis: str, distance: float) -> None:
358366 self .send_command (f"MOVREL { axis } ={ round (distance , 6 )} \r " )
359367 self .read_response ()
360368
369+
361370 def move (self , pos_dict ) -> None :
362371 """Move the stage with an absolute move on multiple axes
363372
@@ -372,6 +381,7 @@ def move(self, pos_dict) -> None:
372381 self .send_command (f"MOVE { pos_str } \r " )
373382 self .read_response ()
374383
384+
375385 def move_axis (self , axis : str , distance : float ) -> None :
376386 """Move the stage with an absolute move on one axis
377387
@@ -385,6 +395,7 @@ def move_axis(self, axis: str, distance: float) -> None:
385395 self .send_command (f"MOVE { axis } ={ round (distance , 6 )} \r " )
386396 self .read_response ()
387397
398+
388399 def set_max_speed (self , axis : str , speed : float ) -> None :
389400 """Set the speed on a specific axis. Speed is in mm/s.
390401
@@ -401,6 +412,7 @@ def set_max_speed(self, axis: str, speed: float) -> None:
401412 self .send_command (f"SPEED { axis } ={ speed } \r " )
402413 self .read_response ()
403414
415+
404416 def get_axis_position (self , axis : str ) -> int :
405417 """Return the position of the stage in ASI units (tenths of microns).
406418
@@ -415,12 +427,10 @@ def get_axis_position(self, axis: str) -> int:
415427 """
416428 self .send_command (f"WHERE { axis } \r " )
417429 response = self .read_response ()
418- # try:
419430 pos = float (response .split (" " )[1 ])
420- # except:
421- # pos = float('Inf')
422431 return pos
423432
433+
424434 def get_axis_position_um (self , axis : str ) -> float :
425435 """Return the position of the stage in microns.
426436
@@ -437,6 +447,7 @@ def get_axis_position_um(self, axis: str) -> float:
437447 response = self .read_response ()
438448 return float (response .split (" " )[1 ]) / 10.0
439449
450+
440451 def get_position (self , axes ) -> dict :
441452 """Return current stage position in ASI units.
442453
@@ -465,8 +476,7 @@ def get_position(self, axes) -> dict:
465476 cmd = f"WHERE { ' ' .join (axes )} \r "
466477 self .send_command (cmd )
467478 response = self .read_response ()
468-
469- # return response.split(" ")[1:-1]
479+
470480 pos = response .split (" " )
471481 axes_seq = list (
472482 filter (
@@ -483,14 +493,17 @@ def get_position(self, axes) -> dict:
483493 # Report position failed. Don't crash, we can try again.
484494 pass
485495 return axis_dict
496+
486497 else :
487498 result = {}
488499 for axis in axes :
489500 result [axis ] = self .get_axis_position (axis )
490501 return result
491502
503+
492504 # Utility Functions
493505
506+
494507 def is_axis_busy (self , axis : str ) -> bool :
495508 """Returns True if the axis is busy.
496509
@@ -507,6 +520,7 @@ def is_axis_busy(self, axis: str) -> bool:
507520 res = self .read_response ()
508521 return "B" in res
509522
523+
510524 def is_device_busy (self ) -> bool :
511525 """Returns True if any axis is busy.
512526
@@ -519,17 +533,20 @@ def is_device_busy(self) -> bool:
519533 res = self .read_response ()
520534 return "B" in res
521535
536+
522537 def wait_for_device (self , timeout : float = 1.75 ) -> None :
523538 """Waits for the all motors to stop moving.
524539
525540 timeout : float
526541 Timeout in seconds. Default is 1.75 seconds.
527542 """
543+
528544 if self .verbose :
529545 print ("Waiting for device..." )
530546 busy = self .is_device_busy ()
531547 waiting_time = 0.0
532-
548+
549+ # t_start = time.time()
533550 while busy :
534551 waiting_time += 0.001
535552 if waiting_time >= timeout :
@@ -540,6 +557,7 @@ def wait_for_device(self, timeout: float = 1.75) -> None:
540557 if self .verbose :
541558 print (f"Waited { waiting_time :.2f} s" )
542559
560+
543561 def stop (self ):
544562 """Stop all stage movement immediately"""
545563
@@ -548,6 +566,7 @@ def stop(self):
548566 if self .verbose :
549567 print ("ASI Stages stopped successfully" )
550568
569+
551570 def set_speed (self , speed_dict ):
552571 """Set speed
553572
@@ -560,6 +579,7 @@ def set_speed(self, speed_dict):
560579 self .send_command (f"S { axes } " )
561580 self .read_response ()
562581
582+
563583 def set_speed_as_percent_max (self , pct ):
564584 """Set speed as a percentage of the maximum speed
565585
@@ -601,6 +621,7 @@ def get_speed(self, axis: str):
601621 response = self .read_response ()
602622 return float (response .split ("=" )[1 ])
603623
624+
604625 def get_encoder_counts_per_mm (self , axis : str ):
605626 """Get encoder counts pre mm of axis
606627
@@ -619,6 +640,7 @@ def get_encoder_counts_per_mm(self, axis: str):
619640 response = self .read_response ()
620641 return float (response .split ("=" )[1 ].split ()[0 ])
621642
643+
622644 def scanr (
623645 self ,
624646 start_position_mm : float ,
@@ -655,6 +677,7 @@ def scanr(
655677 self .send_command (command )
656678 self .read_response ()
657679
680+
658681 def scanv (
659682 self ,
660683 start_position_mm : float ,
@@ -689,6 +712,7 @@ def scanv(
689712 self .send_command (command )
690713 self .read_response ()
691714
715+
692716 def start_scan (self , axis : str , is_single_axis_scan : bool = True ):
693717 """
694718 Start scan
@@ -703,11 +727,13 @@ def start_scan(self, axis: str, is_single_axis_scan: bool = True):
703727 self .send_command ("SCAN" )
704728 self .read_response ()
705729
730+
706731 def stop_scan (self ):
707732 """Stop scan."""
708733 self .send_command ("SCAN P" )
709734 self .read_response ()
710735
736+
711737 def is_moving (self ):
712738 """Check to see if the stage is moving.
713739
@@ -744,6 +770,7 @@ def is_moving(self):
744770 print ("WARNING: WAIT UNTIL DONE RECEIVED NO RESPONSE" )
745771 return False
746772
773+
747774 def set_triggered_move (self , axis ):
748775 '''
749776 Set ASI to repeat the latest relative movement
0 commit comments