def abort(self): """ Stop movement of the stage @return int: error code (0:OK, -1:error) """ # Not pidevice.SystemAbort(): will cause halt or reboot. if self._has_abort: if self._has_is_moving: if pidevice.IsMoving: try: pidevice.StopAll() # pidevice.errcheck = True self.log.debug("PI Device has aborted and stoped all move! ") return 0 except GCSError as exc: self.log.error("PI GCSError(StopAll): " + str(GCSError(exc))) return -1 except (KeyboardInterrupt, SystemExit): # user wants to quit self.log.warning("User wants to quit: keyboard interrupt or system exit!") pidevice.StopAll() except Exception: self.log.error("Hardware PI cannot abort move !") return -1 else: # if not moving, PI stage is stoped already. self.log.warning("PI Device has aborted and stoped all move! ") return 0 else: try: pidevice.StopAll() # pidevice.errcheck = True self.log.debug("PI Device has aborted and stoped all move! ") return 0 except GCSError as exc: self.log.error("PI GCSError: " + str(GCSError(exc))) # raise GCSError(exc) # FIXME return -1 except (KeyboardInterrupt, SystemExit): # user wants to quit self.log.warning("User wants to quit: keyboard interrupt or system exit!") pidevice.StopAll() except Exception: self.log.error("Hardware PI cannot abort move !") return -1 else: self.log.warning('PI System Abort/StopAll Function not yet implemented') return 0
def OpenTCPIPDaisyChain(self, ipaddress, ipport=50000): """Open a TCPIP daisy chain connection. To get access to a daisy chain device you have to call ConnectDaisyChainDevice(). @param ipaddress: IP address to connect to as string. @param ipport: Port to use as integer, defaults to 50000. @return: Found devices as list of strings. """ debug('GCSDll.OpenTCPIPDaisyChain(ipaddress=%r, ipport=%s)', ipaddress, ipport) cipaddress = ctypes.c_char_p(str(ipaddress).encode()) cipport = ctypes.c_int(int(ipport)) numdev = ctypes.byref(ctypes.c_int()) bufsize = 10000 bufstr = ctypes.create_string_buffer('\000'.encode(), bufsize + 2) self._dcid = getattr(self._handle, self._prefix + 'OpenTCPIPDaisyChain')(cipaddress, cipport, numdev, bufstr, bufsize) if self._dcid < 0: raise GCSError(self._error) devlist = bufstr.value.decode().split('\n')[:-1] devlist = [item.strip() for item in devlist] debug('GCSDll.OpenTCPIPDaisyChain: %r', devlist) self._ifdescription = 'TCPIP daisy chain at %s:%s' % (ipaddress, ipport) return devlist
def OpenRS232DaisyChain(self, comport, baudrate): """Open an RS-232 daisy chain connection. To get access to a daisy chain device you have to call ConnectDaisyChainDevice(). @param comport: Port to use as integer (1 means "COM1"). @param baudrate: Baudrate to use as integer. @return: Found devices as list of strings. """ debug('GCSDll.OpenRS232DaisyChain(comport=%s, baudrate=%s)', comport, baudrate) ccomport = ctypes.c_int(int(comport)) cbaudrate = ctypes.c_int(int(baudrate)) numdev = ctypes.byref(ctypes.c_int()) bufsize = 10000 bufstr = ctypes.create_string_buffer('\000'.encode(), bufsize + 2) self._dcid = getattr(self._handle, self._prefix + 'OpenRS232DaisyChain')(ccomport, cbaudrate, numdev, bufstr, bufsize) if self._dcid < 0: raise GCSError(self._error) devlist = bufstr.value.decode().split('\n')[:-1] devlist = [item.strip() for item in devlist] debug('GCSDll.OpenRS232DaisyChain: %r', devlist) self._ifdescription = 'RS-232 daisy chain at COM%s, %s Baud' % ( comport, baudrate) return devlist
def ConnectRS232(self, comport, baudrate): """Open an RS-232 connection to the device. @param comport: Port to use as integer (1 means "COM1") or name ("dev/ttys0") as string. @param baudrate: Baudrate to use as integer. """ cbaudrate = ctypes.c_int(int(baudrate)) try: comport = int(comport) except ValueError: debug('GCSDll.ConnectRS232ByDevName(devname=%r, baudrate=%s)', comport, baudrate) cdevname = ctypes.c_char_p(str(comport).encode()) self._id = getattr(self._handle, self._prefix + 'ConnectRS232ByDevName')(cdevname, cbaudrate) else: debug('GCSDll.ConnectRS232(comport=%s, baudrate=%s)', comport, baudrate) ccomport = ctypes.c_int(int(comport)) self._id = getattr(self._handle, self._prefix + 'ConnectRS232')(ccomport, cbaudrate) if self._id < 0: raise GCSError(self._error) self._ifdescription = 'RS-232 port %s, %s Baud' % (comport, baudrate) self.flush()
def _answersize(self): """Get the size of an answer in the com buffer as integer.""" size = ctypes.c_int() if not getattr(self._handle, self._prefix + 'GcsGetAnswerSize')( self._id, ctypes.byref(size)): raise GCSError(self._error) return size.value
def send(self, msg): """Send 'msg' to the socket. @param msg : String to send. """ debug('PISocket.send: %r', msg) if self._socket.send(msg.encode('cp1252')) != len(msg): raise GCSError(gcserror.E_2_SEND_ERROR)
def GetAsyncBuffer(self, firstline=1, lastline=0, numtables=1): """Query all available data points, return list with 'numtables' columns. DEPRECATED: Use GCSMessages.bufdata instead. Buffer is used by qDRR(), qDDL(), qGWD(), qTWS(), qJLT() and qHIT(). @param firstline : Optional, but must be >= 1 and smaller than 'lastline'. @param lastline : Optional, defaults to query all available data points. @param numtables : Arrange data into 'numtables' columns, defaults to "1". @return: List of data points as float with 'numtables' columns. """ debug('DEPRECATED -- GcsDll.GetAsyncBuffer(id%d, firstline=%r, lastline=%r, numtables=%r)', self._id, firstline, lastline, numtables) maxindex = lastline * numtables or self._asyncbufferindex if firstline < 1: raise SystemError('firstline must be 1 or larger') minindex = (firstline - 1) * numtables if minindex > maxindex: raise SystemError('firstline must not be larger than lastline') cvalues = ctypes.byref(ctypes.c_float) if not getattr(self._handle, self._prefix + 'GetAsyncBuffer')(self._id, cvalues): raise GCSError(self._error) data = [[] for _ in range(numtables)] for i in range(minindex, maxindex): data[i % numtables].append(float(cvalues[i])) debug('DEPRECATED -- GCSDll.GetAsyncBuffer(id%d): %r', self._id, data) return data
def _find_device(serialnumber, pid, vid): """Find USB device according to serialnumber, PID and VID or raise GCS Error. @param serialnumber : Serial number of the device as string. @param pid : Device product ID as integer. @param vid : Device vendor ID as integer. @return : USB device instance. """ debug('PIUSB._find_device(serialnumber=%s, pid=%#x, vid=%#x)', serialnumber, pid, vid) devices = usb.core.find(find_all=True, idVendor=vid, idProduct=pid) if not devices: raise GCSError(gcserror.E_6_CONNECTION_FAILED) for dev in devices: debug('PIUSB._find_device:\n%s', dev) if getdevinfo(dev, dev.iSerialNumber) == serialnumber: return dev usb.util.dispose_resources(dev) raise GCSError(gcserror.E_6_CONNECTION_FAILED)
def RemoveStage(self, axis): """Remove a dataset of a user defined stage from the PI stages database. @param axis: Name of axis whose stage parameters should be removed as string. """ debug('GCSDll.RemoveStage(axis=%r)', axis) axis = ctypes.c_char_p(str(axis).encode()) if not getattr(self._handle, self._prefix + 'RemoveStage')(self._id, axis): raise GCSError(self._error)
def send(self, msg): """Send a GCS command to the device, do not query error from device. @param msg : GCS command as string, with or without trailing line feed character. """ debug('GCSDll.send(id%d): %r', self._id, msg) msg = ctypes.c_char_p(str(msg).encode('cp1252')) if not getattr(self._handle, self._prefix + 'GcsCommandset')(self._id, msg): raise GCSError(self._error)
def send(self, msg): """Send a GCS command to the device, do not query error from device. @param msg : GCS command as string with trailing line feed character. """ if len(msg) % 2: # some controllers need a string of size of modulus 2 msg += '\0' debug('PIUSB.send: %r', msg) if self._ep_out.write(msg) != len(msg): raise GCSError(gcserror.E_2_SEND_ERROR)
def _getanswer(self, bufsize): """Return the answer from the com buffer. @param bufsize : Size in characters of string buffer to store the answer as integer. @return : Answer as string. """ bufstr = ctypes.create_string_buffer('\000'.encode(), bufsize + 2) if not getattr(self._handle, self._prefix + 'GcsGetAnswer')(self._id, bufstr, bufsize + 1): raise GCSError(self._error) return bufstr.value
def InterfaceSetupDlg(self, key=''): """Open dialog to select the interface. @param key: Optional key name as string to store the settings in the Windows registry. """ debug('GCSDll.InterfaceSetupDlg(key=%r)', key) key = ctypes.c_char_p(str(key).encode()) self._id = getattr(self._handle, self._prefix + 'InterfaceSetupDlg')(key) if self._id < 0: raise GCSError(self._error) self._ifdescription = 'Interface Setup Dialog' self.flush()
def ConnectTCPIPByDescription(self, description): """Open a TCP/IP connection to the device using the device 'description'. @param description: One of the identification strings listed by EnumerateTCPIPDevices(). """ debug('GCSDll.ConnectTCPIPByDescription(description=%r)', description) cdescription = ctypes.c_char_p(str(description).encode()) self._id = getattr(self._handle, self._prefix + 'ConnectTCPIPByDescription')(cdescription) if self._id < 0: raise GCSError(self._error) self._ifdescription = 'TCPIP %r' % description self.flush()
def ConnectUSB(self, serialnum): """Open an USB connection to a device. @param serialnum: Serial number of device or one of the identification strings listed by EnumerateUSB(). """ debug('GCSDll.ConnectUSB(serialnum=%r)', serialnum) cserialnum = ctypes.c_char_p(str(serialnum).encode()) self._id = getattr(self._handle, self._prefix + 'ConnectUSB')(cserialnum) if self._id < 0: raise GCSError(self._error) self._ifdescription = 'USB %r' % serialnum self.flush()
def getconfigs(self): """Get available configurations in PIStages database for the connected controller. @return : Answer as string. """ debug('GCSDll.getconfigs()') bufsize = 20000 configs = ctypes.create_string_buffer('\000'.encode(), bufsize + 2) funcname = self._prefix + 'GetAvailableControllerConfigurationsFromDatabase' if not getattr(self._handle, funcname)(self._id, configs, bufsize + 1): raise GCSError(self._error) configs = configs.value.decode(encoding='cp1252', errors='ignore') debug('GCSDll.getconfigs(id%d): %r', self._id, configs) return configs
def ConnectTCPIP(self, ipaddress, ipport=50000): """Open a TCP/IP connection to the device. @param ipaddress: IP address to connect to as string. @param ipport: Port to use as integer, defaults to 50000. """ debug('GCSDll.ConnectTCPIP(ipaddress=%s, ipport=%s)', ipaddress, ipport) cipaddress = ctypes.c_char_p(str(ipaddress).encode()) cipport = ctypes.c_int(int(ipport)) self._id = getattr(self._handle, self._prefix + 'ConnectTCPIP')(cipaddress, cipport) if self._id < 0: raise GCSError(self._error) self._ifdescription = 'TCPIP %s:%s' % (ipaddress, ipport) self.flush()
def ConnectNIgpib(self, board, device): """Open a connection from a NI IEEE 488 board to the device. @param board: GPIB board ID as integer. @param device: The GPIB device ID of the device as integer. """ debug('GCSDll.ConnectNIgpib(board=%s, device=%s)', board, device) cboard = ctypes.c_int(int(board)) cdevice = ctypes.c_int(int(device)) self._id = getattr(self._handle, self._prefix + 'ConnectNIgpib')(cboard, cdevice) if self._id < 0: raise GCSError(self._error) self._ifdescription = 'GPIB board %s, device %s' % (board, device) self.flush()
def ConnectPciBoard(self, board): """Open a PCI board connection. @param board : PCI board number as integer. """ debug('GCSDll.ConnectPciBoard(board=%s)', board) cboard = ctypes.c_int(int(board)) if self._prefix == 'C843_': self._id = getattr(self._handle, self._prefix + 'Connect')(cboard) else: self._id = getattr(self._handle, self._prefix + 'ConnectPciBoard')(cboard) if self._id < 0: raise GCSError(self._error) self._ifdescription = 'PCI board %s' % board self.flush()
def saveconfig(self, items, config): """Read parameters according to 'config' from controller and write them to the PIStages database. @param items : Items of the controller the configuration is assigned to as string. Consists of the key word (e.g. "axis") and ID (e.g. "4"), examples: "axis 1", "axis 4". @param config: Name of a configuration not yet existing in PIStages database as string. """ debug('GCSDll.saveconfig(items=%r, config=%r)', items, config) items = ctypes.c_char_p(str(items).encode()) config = ctypes.c_char_p(str(config).encode()) bufsize = 20000 warnings = ctypes.create_string_buffer('\000'.encode(), bufsize + 2) funcname = self._prefix + 'ReadConfigurationFromControllerToDatabase' if not getattr(self._handle, funcname)(self._id, items, config, warnings, bufsize + 1): self.warning = warnings.value.decode(encoding='cp1252', errors='ignore') raise GCSError(self._error)
def EnumerateTCPIPDevices(self, mask=''): """Get identification strings of all TCP connected devices. @param mask: String to filter the results for certain text. @return: Found devices as list of strings. """ debug('GCSDll.EnumerateTCPIPDevices(mask=%r)', mask) mask = ctypes.c_char_p(str(mask).encode()) bufsize = 100000 bufstr = ctypes.create_string_buffer('\000'.encode(), bufsize + 2) if getattr(self._handle, self._prefix + 'EnumerateTCPIPDevices')(bufstr, bufsize, mask) < 0: raise GCSError(self._error) devlist = bufstr.value.decode(encoding='cp1252', errors='ignore').split('\n')[:-1] devlist = [item.strip() for item in devlist] debug('GCSDll.EnumerateTCPIPDevices: %r', devlist) return devlist
def on_deactivate(self): """ Deinitialise and deactivate the hardware module. @return: error code (0:OK, -1:error) """ # TODO add def shutdown(self) to set Votage=0 V for safety. # self._set_servo_state(False) # If not shutdown, keep servo on to stay on target. try: pidevice.errcheck = True pidevice.CloseConnection() self.log.warning("PI Device has been closed connection !") return 0 except GCSError as exc: self.log.error("PI GCSError: " + str(GCSError(exc))) return -1
def calibrate(self, param_list=None): """ Calibrate the stage. PI GCS ATZ() will move axes to their whole range, careful ! NOT recommend to do ATZ by this function, use PI Software instead. @param dict param_list : param_list: optional, if a specific calibration of an axis is desired, then the labels of the needed axis should be passed in the param_list. If nothing is passed, then all connected axis will be calibrated. After calibration the stage moves to home position which will be the zero point for the passed axis. @return dict pos : dictionary with the current position of the axis """ param_dict = {} if self._has_calibrate: try: self.abort() pidevice.errcheck = True pidevice.ATZ(axes=[1, 2]) # PI Piezo Auto To Zero Calibration, just do it after power shutdown. # PI GCS ATZ() will move axes to their whole range, Careful ! # TODO: NOT recommend to do ATZ by this function, use PI Software instead. time.sleep(10.0) # has ATZ(), also should has qATZ() if pidevice.qATZ(axes=[1]) and pidevice.qATZ(axes=[2]): param_dict = self.get_pos([param_dict.keys()]) return param_dict else: raise ValueError("PI Auto To Zero Function not succeed !") except GCSError as exc: self.log.error("PI GCSError(ATZ or qATZ): " + str(GCSError(exc))) # raise GCSError(exc) raise except (KeyboardInterrupt, SystemExit): # user wants to quit self.log.warning("User wants to quit: keyboard interrupt or system exit!") raise except Exception: raise else: self.log.warning('PI Auto To Zero Function not yet implemented') return param_dict
def get_pos(self, param_list=None): """ Get the current position of the stage axis @param list param_list : optional, if a specific position of an axis is desired, then the labels of the needed axis should be passed in the param_list. If nothing is passed, then the positions of all axes are returned. @return dict param_dict : with keys being the axis labels and item the current position. """ param_dict = {} if self._has_get_pos: new_param_list = self._axis_label_conver2pipy(param_list) try: param_dict_get = pidevice.qPOS(new_param_list) # self.log.debug("Hardware get before conver :" + str(param_dict)) # axis dict get conversion param_dict = self._axis_dict_get(param_dict_get) # self.log.debug("Hardware get :" + str(param_dict)) return param_dict except GCSError as exc: self.log.debug("PI GCSError(qPOS): " + str(GCSError(exc))) try: self.on_target() # try wait for on target, then get positions. param_dict_get = pidevice.qPOS(new_param_list) param_dict = self._axis_dict_get(param_dict_get) return param_dict except (KeyboardInterrupt, SystemExit): # user wants to quit self.log.warning("User wants to quit: keyboard interrupt or system exit!") return param_dict except Exception: raise except: self.log.error("Hardware get_pos failed !") raise else: self.log.warning('PI qPOS() Function not yet implemented') return param_dict
def ConnectDaisyChainDevice(self, deviceid, daisychainid=None): """Connect device with 'deviceid' on the daisy chain 'daisychainid'. Daisy chain has to be connected before, see Open<interface>DaisyChain() functions. @param daisychainid : Daisy chain ID as int from the daisy chain master instance or None. @param deviceid : Device ID on the daisy chain as integer. """ debug('GCSDll.ConnectDaisyChainDevice(deviceid=%s, daisychainid=%s)', deviceid, daisychainid) if daisychainid is None: daisychainid = self._dcid cdeviceid = ctypes.c_int(int(deviceid)) cdaisychainid = ctypes.c_int(int(daisychainid)) self._id = getattr(self._handle, self._prefix + 'ConnectDaisyChainDevice')(cdaisychainid, cdeviceid) if self._id < 0: raise GCSError(self._error) if self._ifdescription: self._ifdescription += '; ' self._ifdescription += 'daisy chain %d, device %s' % (daisychainid, deviceid) self.flush()
def OpenUSBDaisyChain(self, description): """Open a USB daisy chain connection. To get access to a daisy chain device you have to call ConnectDaisyChainDevice(). @param description: Description of the device returned by EnumerateUSB(). @return: Found devices as list of strings. """ debug('GCSDll.OpenUSBDaisyChain(description=%r)', description) cdescription = ctypes.c_char_p(str(description).encode()) numdev = ctypes.byref(ctypes.c_int()) bufsize = 10000 bufstr = ctypes.create_string_buffer('\000'.encode(), bufsize + 2) self._dcid = getattr(self._handle, self._prefix + 'OpenUSBDaisyChain')(cdescription, numdev, bufstr, bufsize) if self._dcid < 0: raise GCSError(self._error) devlist = bufstr.value.decode(encoding='cp1252', errors='ignore').split('\n')[:-1] devlist = [item.strip() for item in devlist] debug('GCSDll.OpenUSBDaisyChain: %r', devlist) self._ifdescription = 'USB daisy chain at SN %r' % description return devlist
def waitonmacro(pidevice, timeout=300, predelay=0, polldelay=0.1): """Wait until all macros are finished, then query and raise macro error. @type pidevice : pipython.gcscommands.GCSCommands @param timeout : Timeout in seconds as float, defaults to 300 seconds. @param predelay : Time in seconds as float until querying any state from controller. @param polldelay : Delay time between polls in seconds as float. """ maxtime = time() + timeout waitonready(pidevice, timeout=timeout, predelay=predelay) assert pidevice.HasqRMC() or pidevice.HasIsRunningMacro(), 'device does not support wait on macro' while True: if pidevice.HasqRMC() and not pidevice.qRMC().strip(): break if pidevice.HasIsRunningMacro() and not pidevice.IsRunningMacro(): break if time() > maxtime: stopall(pidevice) raise SystemError('waitonmacro() timed out after %.1f seconds' % timeout) sleep(polldelay) if pidevice.HasMAC_qERR(): errmsg = pidevice.MAC_qERR().strip() if errmsg and int(errmsg.split('=')[1].split()[0]) != 0: raise GCSError(gcserror.E1012_PI_CNTR_ERROR_IN_MACRO, message=errmsg)
def move_rel(self, param_dict): """ Move stage relatively, positive or negative value.And if step is too small, PI GCS will ignore.#TODO:check this in PI GCS. @param dict param_dict : dictionary, which passes all the relevant parameters, which should be changed. Usage: {'axis_label': <the-abs-pos-value>}. 'axis_label' must correspond to a label given to one of the axis. The values for the axes are in meter, the value for the rotation is in degrees. @return dict param_dict : dictionary with the current magnet position """ pos = {} # get origin pos() try: self.on_target() pos = self.get_pos([param_dict.keys()]) except GCSError as exc: self.log.warning("PI GCSError: " + str(GCSError(exc))) raise if self._has_move_rel: # if config range is smaller than PI GCS range if self._has_diff_constrains: # if target is not in the config range if self._move_rel_range_check(pos, param_dict) is False: self.log.warning('''Cannot make the movement of the axis, out config range! Command ignore.''') try: # self.abort() self.on_target() pos = self.get_pos([param_dict.keys()]) except GCSError as exc: self.log.debug("PI GCSError: " + str(GCSError(exc))) pass except: self.log.warning("PI GCS move_rel / MVR failed !") pass finally: return pos # move rel try: # self.log.debug("Send MVR to hardware PI before conver: " + str(param_dict)) new_param_dict = self._axis_dict_send(param_dict) # self.log.debug("Send MVR to hardware PI actually: :" + str(new_param_dict)) pidevice.MVR(new_param_dict) # Send str upper + um: 1 2 3 try: self.on_target() pos = self.get_pos([param_dict.keys()]) except: pass except GCSError as exc: self.log.error("PI GCSError(MVR): " + str(GCSError(exc))) except: self.log.error("PI GCS move_rel / MVR failed !") finally: return pos else: self.log.warning('PI GCS MVR Function not yet implemented') return pos
def move_abs(self, param_dict): """ Move the stage to an absolute position @param dict param_dict : dictionary, which passes all the absolute parameters, which should be changed. Usage: {'axis_label': <the-abs-pos-value>}. 'axis_label' must correspond to a label given to one of the axis. The values for the axes are in meter, the value for the rotation is in degrees. @return dict param_dict : dictionary with the current axis position """ # pidevice.MOV or pidevice.MVT is better ? if self._has_move_abs: # if config range is smaller than PI GCS range if self._has_diff_constrains: # if target is not in the config range if self._move_abs_range_check(param_dict) is False: self.log.warning('''Cannot make the movement of the axis, out config range! Command ignore.''') try: # self.abort() self.on_target() pos = self.get_pos([param_dict.keys()]) return pos except GCSError as exc: self.log.debug("PI GCSError: " + str(GCSError(exc))) raise except (KeyboardInterrupt, SystemExit): # user wants to quit self.log.warning("User wants to quit: keyboard interrupt or system exit!") pass except Exception: self.log.error("PI move_abs / MOV failed !") # FIXME: raise # move abs: most used in scan, must be very fast to run python. try: # self.log.debug("Send MOV to hardware PI before conver: " + str(param_dict)) new_param_dict = self._axis_dict_send(param_dict) # self.log.debug("Send MOV to hardware PI actually: " + str(new_param_dict)) pidevice.MOV(new_param_dict) # Send str upper + um: 1 2 3 return param_dict except GCSError as exc: self.log.debug("PI GCSError(MOV): " + str(GCSError(exc))) pass # FIXME: if move abs failed, return get position ? # but when xy is ok and z is error, still goto xy ? return param_dict except (KeyboardInterrupt, SystemExit): # user wants to quit self.log.warning("User wants to quit: keyboard interrupt or system exit!") # pass self.abort() pos = self.get_pos([param_dict.keys()]) return pos except Exception: self.log.error("PI move_abs / MOV failed !") raise else: self.log.warning('PI GCS MOV Function not yet implemented') return param_dict
def on_activate(self): """ Initialise and activate the hardware module. @return: error code (0:OK, -1:error) """ try: self._configured_constraints = self.get_constraints() # FIXME: use this logic instead of PI GCS error to threshold commond move_abs() pidevice.errcheck = True # FIXME This will trigger a GUI, shoud be taken by Qudi GUI. # pidevice.InterfaceSetupDlg('pidevice_token') # pidevice = GCSDevice('E-727') # pidevice.ConnectTCPIP('192.168.178.42') try: devices = pidevice.EnumerateUSB(mask=self._pi_controller_mask) self.log.warning("PI ConnectUSB Devices found:" + str(devices)) if len(devices) is not 0: pidevice.ConnectUSB(devices[0]) self._has_connect_piezo_controller = True else: try: devices = pidevice.EnumerateTCPIPDevices(mask=self._pi_controller_mask) self.log.warning("PI ConnectTCPIP Devices found:" + str(devices)) if len(devices) is not 0: pidevice.ConnectTCPIPByDescription(devices[0]) self._has_connect_piezo_controller = True else: self.log.error("NOT Found the PI Devices: {} by either USB or TCPIP: ".format( self._pi_controller_mask)) raise ValueError("NOT Found the PI Devices.") except: pass except: pass if self._has_connect_piezo_controller: device_name = pidevice.qIDN() self._set_servo_state(True) self.log.warning('Activate Motor and Set servo on for PI Controller = {}'.format(device_name.strip())) else: raise ("Not Connect PI Controller = {} !".format(self._pi_controller_mask)) except GCSError as exc: self.log.error("PI GCSError: " + str(GCSError(exc))) return -1 # raise GCSError(exc) except IndexError: self.log.error("Not Found PI Controller = {} !".format(self._pi_controller_mask)) return -1 except Exception as e: self.log.error("Hardware Not Activated: PI Devices!") return -1 if self._has_connect_piezo_controller: try: self._has_move_abs = pidevice.HasMOV() self._has_get_pos = pidevice.HasqPOS() # above is important to logic interfuse motor scanner # Hardware module xyz range self-auto-check. self._has_diff_constrains = self._has_diff_constrains_check() # Safe range init set by PI GCS for one axis with object lens. self._set_safe_range4objectlens_axis() if self._has_move_abs and self._has_get_pos: try: self._has_move_rel = pidevice.HasMVR() self._has_abort = pidevice.HasStopAll() self._has_is_moving = pidevice.HasIsMoving() self._has_calibrate = pidevice.HasATZ() self._has_get_velocity = pidevice.HasqVEL() self._has_set_velocity = pidevice.HasVEL() # above is not as important as MOV() and qPOS() in motor-scanner-interfuse except GCSError as exc: self.log.warning("PI GCSError: " + str(GCSError(exc))) pass finally: pidevice.errcheck = False # TODO: If communication speed like MOV() for motor scanner is an issue, # can disable error checking. self.log.debug("PI PZT is ready to go.") return 0 else: self.log.error("PI Device has no MOV() or qPOS() func !") return -1 except: self.log.error("PI GCSError: " + str(GCSError(exc))) return -1