Source code for qcodes_contrib_drivers.drivers.Thorlabs.private.APT

import ctypes
from typing import List, Optional, Tuple, Union
import enum


[docs] class ThorlabsHWType(enum.Enum): PRM1Z8 = 31 BSC001 = 11 # 1 ch benchtop stepper driver BSC101 = 12 # 1 ch benchtop stepper driver BSC002 = 13 # 2 ch benchtop stepper driver BDC101 = 14 # 1 ch benchtop dc servo driver SCC001 = 21 # 1 ch stepper driver card (used within BSC102, 103 units) DCC001 = 22 # 1 ch DC servo driver card (used within BDC102, 103 units) ODC001 = 24 # 1 ch DC servo driver cube OST001 = 25 # 1 ch stepper driver cube MST601 = 26 # 2 ch modular stepper driver module TST001 = 29 # 1 ch stepper driver T-cube TDC001 = 31 # 1 ch DC servo driver T-cube LTSxxx = 42 # LTS300/LTS150 long travel integrated driver/stages L490MZ = 43 # L490MZ Integrated Driver/Labjack BBD10x = 44 # 1/2/3 ch benchtop brushless DC servo driver MFF10x = 48 # motorized filter flip K10CR1 = 50 # steper motor rotation mount KDC101 = 63 # 1 ch Brushed DC servo motor controller K-cube
[docs] class ThorlabsException(Exception): pass
[docs] class Thorlabs_APT: """ Wrapper class for the APT.dll Thorlabs APT Server library. The class has been tested for a Thorlabs MFF10x mirror flipper, a Thorlabs PRM1Z8 Polarizer Wheel and a Thorlabs K10CR1 rotator. Args: dll_path: Path to the APT.dll file. If not set, a default path is used. verbose: Flag for the verbose behaviour. If true, successful events are printed. event_dialog: Flag for the event dialog. If true, event dialog pops up for information. Attributes: verbose: Flag for the verbose behaviour. dll: WinDLL object for APT.dll. """ # default dll installation path _dll_path = 'C:\\Program Files\\Thorlabs\\APT\\APT Server\\APT.dll' # success and error codes _success_code = 0 def __init__(self, dll_path: Optional[str] = None, verbose: bool = False, event_dialog: bool = False): # save attributes self.verbose = verbose # connect to the DLL self.dll = ctypes.CDLL(dll_path or self._dll_path) # initialize APT server self.apt_init() self.enable_event_dlg(event_dialog)
[docs] def error_check(self, code: int, function_name: str = "") -> None: """Analyzes a functions return code to check, if the function call to APT.dll was successful. If an error occurred, this function throws an ThorlabsException. Args: code: The called function's return code function_name: Name of the called function Throws: ThorlabsException: Thrown, if the return code indicates that an error has occurred. """ if code == self._success_code: if self.verbose: print("APT: [{}]: {}".format(function_name, "OK - no error")) else: raise ThorlabsException("APT: [{}]: Unknown code: {}".format(function_name, code))
[docs] def apt_clean_up(self) -> None: """Cleans up the resources of APT.dll""" code = self.dll.APTCleanUp() self.error_check(code, 'APTCleanUp')
[docs] def apt_init(self) -> None: """Initialization of APT.dll""" code = self.dll.APTInit() self.error_check(code, 'APTInit')
[docs] def list_available_devices(self, hw_type: Union[int, ThorlabsHWType, None] = None) \ -> List[Tuple[int, int, int]]: """Lists all available Thorlabs devices, that can connect to the APT server. Args: hw_type: If this parameter is passed, the function only searches for a certain device model. Otherwise (if the parameter is None), it searches for all Thorlabs devices. Returns: A list of tuples. Each list-element is a tuple of 3 ints, containing the device's hardware type, device id and serial number: [(hw type id, device id, serial), ...] """ devices = [] count = ctypes.c_long() if hw_type is not None: # Only search for devices of the passed hardware type (model) if isinstance(hw_type, ThorlabsHWType): hw_type_range = [hw_type.value] else: hw_type_range = [int(hw_type)] else: # Search for all models hw_type_range = list(range(100)) for hw_type_id in hw_type_range: # Get number of devices of the specific hardware type if self.dll.GetNumHWUnitsEx(hw_type_id, ctypes.byref(count)) == 0 and count.value > 0: # Is there any device of the specified hardware type serial_number = ctypes.c_long() # Get the serial numbers of all devices of that hardware type for ii in range(count.value): if self.dll.GetHWSerialNumEx(hw_type_id, ii, ctypes.byref(serial_number)) == 0: devices.append((hw_type_id, ii, serial_number.value)) return devices
[docs] def enable_event_dlg(self, enable: bool) -> None: """Activates/deactivates the event dialog, which appears when an error occurs. Args: enable: True, to enable the event dialog. False, to disable it. """ c_enable = ctypes.c_bool(enable) code = self.dll.EnableEventDlg(c_enable) self.error_check(code, 'EnableEventDlg')
[docs] def get_hw_info(self, serial_number: int) -> Tuple[str, str, str]: """Returns the device's information. Args: serial_number: The device's serial number for which this function is called. Returns: device model name, firmware version, hardware notes. """ c_serial_number = ctypes.c_long(serial_number) c_sz_model = ctypes.create_string_buffer(64) c_sz_sw_ver = ctypes.create_string_buffer(64) c_sz_hw_notes = ctypes.create_string_buffer(64) code = self.dll.GetHWInfo(c_serial_number, c_sz_model, 64, c_sz_sw_ver, 64, c_sz_hw_notes, 64) self.error_check(code, 'GetHWInfo') return c_sz_model.value.decode('utf-8'), \ c_sz_sw_ver.value.decode("utf-8"), \ c_sz_hw_notes.value.decode("utf-8")
[docs] def get_hw_serial_num_ex(self, hw_type: Union[int, ThorlabsHWType], index: int) -> int: """Returns the a device's serial number by passing the model's hardware type and the device id. Args: hw_type: Hardware type (model code) to search for. index: Device id Returns: The device's serial number """ if isinstance(hw_type, ThorlabsHWType): hw_type_id = hw_type.value else: hw_type_id = int(hw_type) c_hw_type = ctypes.c_long(hw_type_id) c_index = ctypes.c_long(index) c_serial_number = ctypes.c_long() code = self.dll.GetHWSerialNumEx(c_hw_type, c_index, ctypes.byref(c_serial_number)) self.error_check(code, 'GetHWSerialNumEx') return c_serial_number.value
[docs] def init_hw_device(self, serial_number: int) -> None: """Initializes the device Args: serial_number: The device's serial number for which this function is called. """ c_serial_number = ctypes.c_long(serial_number) code = self.dll.InitHWDevice(c_serial_number) self.error_check(code, 'InitHWDevice')
[docs] def mot_get_position(self, serial_number: int) -> float: """Returns the current motor position Args: serial_number: The device's serial number for which this function is called. Returns: Motor position in degrees (0 to 360) """ c_serial_number = ctypes.c_long(serial_number) c_position = ctypes.c_float() code = self.dll.MOT_GetPosition(c_serial_number, ctypes.byref(c_position)) self.error_check(code, 'MOT_GetPosition') return c_position.value
[docs] def mot_get_status_bits(self, serial_number: int) -> int: """Returns the motor's status bits Args: serial_number: The device's serial number for which this function is called. Returns: Status bits of the motor """ c_serial_number = ctypes.c_long(serial_number) c_status_bits = ctypes.c_long() code = self.dll.MOT_GetStatusBits(c_serial_number, ctypes.byref(c_status_bits)) self.error_check(code, 'MOT_GetStatusBits') return c_status_bits.value
[docs] def mot_move_absolute_ex(self, serial_number: int, absolute_position: float, wait: bool) -> None: """Moves the motor to an absolute position Args: serial_number: The device's serial number for which this function is called. position: The position to move the motor to in degrees (0 to 360) wait: True, to block until the motor reaches the target position. False, to do this asynchronously. """ c_serial_number = ctypes.c_long(serial_number) c_absolute_position = ctypes.c_float(absolute_position) c_wait = ctypes.c_bool(wait) code = self.dll.MOT_MoveAbsoluteEx(c_serial_number, c_absolute_position, c_wait) self.error_check(code, 'MOT_MoveAbsoluteEx')
[docs] def mot_move_jog(self, serial_number: int, direction: int, wait: bool) -> None: """Returns the motor's status bits Args: serial_number: The device's serial number for which this function is called. direction: Forward (1) or reverse (2) wait: True, to block until the motor reaches the target position. False, to do this asynchronously. """ c_serial_number = ctypes.c_long(serial_number) c_direction = ctypes.c_long(direction) c_wait = ctypes.c_bool(wait) code = self.dll.MOT_MoveJog(c_serial_number, c_direction, c_wait) self.error_check(code, 'MOT_MoveJog')
[docs] def mot_stop_profiled(self, serial_number: int) -> None: """Stops the motor. Args: serial_number: The device's serial number for which this function is called. """ c_serial_number = ctypes.c_long(serial_number) code = self.dll.MOT_StopProfiled(c_serial_number) self.error_check(code, 'MOT_StopProfiled')
[docs] def mot_get_velocity_parameters(self, serial_number: int) -> Tuple[float, float, float]: """Returns the motor's velocity parameters Args: serial_number: The device's serial number for which this function is called. Returns: minimum velocity (deg/s), acceleration (deg/s/s), maximum velocity (deg/s) """ c_serial_number = ctypes.c_long(serial_number) c_min_vel = ctypes.c_float() c_accn = ctypes.c_float() c_max_vel = ctypes.c_float() code = self.dll.MOT_GetVelParams(c_serial_number, ctypes.byref(c_min_vel), ctypes.byref(c_accn), ctypes.byref(c_max_vel)) self.error_check(code, 'MOT_SetVelParams') return c_min_vel.value, c_accn.value, c_max_vel.value
[docs] def mot_set_velocity_parameters(self, serial_number: int, min_vel: float, accn: float, max_vel: float) -> None: """Sets the motor's velocity parameters Args: serial_number: The device's serial number for which this function is called. min_vel: Minimum veloctiy (starting velocity) in deg/s accn: Acceleration in deg/s/s max_vel: Maximum velocity (target velocity) in deg/s """ c_serial_number = ctypes.c_long(serial_number) c_min_vel = ctypes.c_float(min_vel) c_accn = ctypes.c_float(accn) c_max_vel = ctypes.c_float(max_vel) code = self.dll.MOT_SetVelParams(c_serial_number, c_min_vel, c_accn, c_max_vel) self.error_check(code, 'MOT_SetVelParams')
[docs] def mot_move_velocity(self, serial_number: int, direction: int) -> None: """Lets the motor rotate continuously in the specified direction. Args: serial_number: The device's serial number for which this function is called. direction: Forward (1) or reverse (2) """ c_serial_number = ctypes.c_long(serial_number) c_direction = ctypes.c_long(direction) code = self.dll.MOT_MoveVelocity(c_serial_number, c_direction) self.error_check(code, 'MOT_MoveVelocity')
[docs] def enable_hw_channel(self, serial_number: int) -> None: """Enables the hardware channel (often the motor) Args: serial_number: The device's serial number for which this function is called. """ c_serial_number = ctypes.c_long(serial_number) code = self.dll.MOT_EnableHWChannel(c_serial_number) self.error_check(code, 'MOT_EnableHWChannel')
[docs] def disable_hw_channel(self, serial_number: int) -> None: """Disables the hardware channel (often the motor) Args: serial_number: The device's serial number for which this function is called. """ c_serial_number = ctypes.c_long(serial_number) code = self.dll.MOT_DisableHWChannel(c_serial_number) self.error_check(code, 'MOT_DisableHWChannel')
[docs] def mot_move_home(self, serial_number: int, wait: bool) -> None: """Moves the motor to zero and recalibrates it Args: serial_number: The device's serial number for which this function is called. wait: True, to block until the motor reaches the target position. False, to do this asynchronously. """ c_serial_number = ctypes.c_long(serial_number) c_wait = ctypes.c_bool(wait) code = self.dll.MOT_MoveHome(c_serial_number, c_wait) self.error_check(code, 'MOT_MoveHome')
[docs] def mot_get_home_parameters(self, serial_number: int) -> Tuple[int, int, float, float]: """Returns the motor's parameters for moving home Args: serial_number: The device's serial number for which this function is called. Returns: direction, home limit switch, velocity (deg/s), zero offset (deg) """ c_serial_number = ctypes.c_long(serial_number) c_direction = ctypes.c_long() c_lim_switch = ctypes.c_long() c_velocity = ctypes.c_float() c_zero_offset = ctypes.c_float() code = self.dll.MOT_GetHomeParams(c_serial_number, ctypes.byref(c_direction), ctypes.byref(c_lim_switch), ctypes.byref(c_velocity), ctypes.byref(c_zero_offset)) self.error_check(code, 'MOT_GetHomeParams') return c_direction.value, c_lim_switch.value, c_velocity.value, c_zero_offset.value
[docs] def mot_set_home_parameters(self, serial_number: int, direction: int, lim_switch: int, velocity: float, zero_offset: float) -> None: """Sets the motor's parameters for moving home Args: serial_number: The device's serial number for which this function is called. direction: Moving direction (1 for forward, 2 for reverse) lim_switch: Home limit switch (1 for reverse, 4 for forward) velocity: Moving velocity in degrees/s zero_offset: Offset of zero position in degrees Returns: minimum velocity (deg/s), acceleration (deg/s/s), maximum velocity (deg/s) """ c_serial_number = ctypes.c_long(serial_number) c_direction = ctypes.c_long(direction) c_lim_switch = ctypes.c_long(lim_switch) c_velocity = ctypes.c_float(velocity) c_zero_offset = ctypes.c_float(zero_offset) code = self.dll.MOT_SetHomeParams(c_serial_number, c_direction, c_lim_switch, c_velocity, c_zero_offset) self.error_check(code, 'MOT_SetHomeParams')