class widgetAPT(QWidget): def __init__(self, parent=None, serial=00000000, verbose=False): super(widgetAPT, self).__init__(parent) self.resize(200, 100) #self.move(100, 100) #setGeometry sets both location and size #self.setGeometry(50, 50, 1180, 900) self.setWindowTitle('APT Motor') #self.m = APTMotor(0) # QT GridLayout # TODO: Implement GridLayout #grid = QGridLayout() # Layout objects sAuthor = QLabel("QT-APT", self) sAuthor.resize(100, 20) sAuthor.move(100, 0) sAuthor.setAlignment(Qt.AlignRight) sVersion = QLabel("v1.0.0", self) sVersion.resize(100, 20) sVersion.move(100, 15) sVersion.setAlignment(Qt.AlignRight) sEmail = QLabel("Michael Leung", self) sEmail.resize(100, 40) sEmail.move(100, 30) sEmail.setAlignment(Qt.AlignRight) # Motor Serial Number sSer = QLabel("Serial:", self) sSer.resize(60, 20) sSer.move(0, 0) self.txtSerial = QSpinBox(self) self.txtSerial.resize(70, 20) self.txtSerial.move(30, 0) self.txtSerial.setRange(0, 99999999) self.txtSerial.setSingleStep(1) self.txtSerial.setValue(83840946) # qle.textChanged[str].connect(self.onChanged) #do onChanged when changed self._Motor_ = APTMotor(verbose=verbose) # Motor Connect self.btnConnect = QPushButton("Connect", self) self.btnConnect.setStyleSheet("background-color: grey") self.btnConnect.setText("Connect") self.btnConnect.setCheckable(True) self.btnConnect.setToolTip("Connect to Motor") self.btnConnect.resize(50, 20) self.btnConnect.move(105, 0) self.btnConnect.clicked[bool].connect(self.connectAPT) sPos = QLabel("Pos:", self) sPos.resize(70, 20) sPos.move(0, 25) self.txtPos = QDoubleSpinBox(self) self.txtPos.resize(60, 20) self.txtPos.move(30, 25) #self.txtPos.setMaxLength(7) self.txtPos.setRange(0, 20) self.txtPos.setSingleStep(.1) self.txtPos.setDecimals(5) self.txtPos.setValue(0.0000000) self.txtPos.setToolTip("Current Motor Position") #self.txtPos.setValidator( QDoubleValidator(0, 100, 2) ) self.txtPos.setEnabled(False) # Go to position btnGOp = QPushButton("Go", self) btnGOp.resize(25, 20) btnGOp.move(100, 25) btnGOp.clicked.connect(lambda: self.motAbs(float(self.txtPos.text()))) # Movement buttons btnN3 = QPushButton("-100", self) btnN3.resize(32, 20) btnN3.move(0, 50) btnN3.clicked.connect(lambda: self.motRel(-.1)) btnN2 = QPushButton("-10", self) btnN2.resize(32, 20) btnN2.move(33, 50) btnN2.clicked.connect(lambda: self.motRel(-.01)) btnN1 = QPushButton("-1", self) btnN1.resize(32, 20) btnN1.move(66, 50) btnN1.clicked.connect(lambda: self.motRel(-.001)) btnP1 = QPushButton("+1", self) btnP1.resize(32, 20) btnP1.move(100, 50) btnP1.clicked.connect(lambda: self.motRel(.001)) btnP2 = QPushButton("+10", self) btnP2.resize(32, 20) btnP2.move(133, 50) btnP2.clicked.connect(lambda: self.motRel(.01)) btnP3 = QPushButton("+100", self) btnP3.resize(32, 20) btnP3.move(166, 50) btnP3.clicked.connect(lambda: self.motRel(.1)) sVel = QLabel("Vel:", self) sVel.resize(60, 20) sVel.move(0, 75) self.txtVel = QDoubleSpinBox(self) self.txtVel.resize(60, 20) self.txtVel.move(30, 75) #self.txtVel.setMaxLength(7) self.txtVel.setRange(0, 2.2) self.txtVel.setSingleStep(.1) self.txtVel.setValue(0.000) self.txtVel.setToolTip("Current Motor Position") self.txtVel.setEnabled(False) # Go to velocity btnGOv = QPushButton("Go", self) btnGOv.resize(25, 20) btnGOv.move(100, 75) btnGOv.clicked.connect( lambda: self._Motor_.setVel(float(self.txtVel.text()))) sBack = QLabel("Backlash:", self) sBack.resize(60, 20) sBack.move(130, 75) self.cbBacklash = QCheckBox(self) self.cbBacklash.resize(60, 20) self.cbBacklash.move(180, 75) self.show() def connectAPT(self, pressed): if pressed: #APT Motor connect Serial = int(self.txtSerial.text()) self._Motor_.setSerialNumber(Serial) self._Motor_.initializeHardwareDevice() # Success self.btnConnect.setStyleSheet("background-color: green") self.btnConnect.setText("Connected") self.txtSerial.setEnabled(False) self.txtPos.setEnabled(True) # Update text to show position self.txtPos.setValue(self._Motor_.getPos()) self.txtVel.setEnabled(True) _, _, maxVel = self._Motor_.getVelocityParameters() self.txtVel.setValue(maxVel) return True else: #APT Motor disconnect self._Motor_.cleanUpAPT() # Success self.btnConnect.setStyleSheet("background-color: grey") self.btnConnect.setText("Connect") self.txtSerial.setEnabled(True) self.txtPos.setEnabled(False) self.txtVel.setEnabled(False) self.txtPos.setValue(0.0000) self.txtPos.setToolTip("Current Motor Position") return True def motRel(self, relDistance): if self.cbBacklash.isChecked(): self._Motor_.mbRel(relDistance) else: self._Motor_.mRel(relDistance) # Update text to show position self.txtPos.setValue(self._Motor_.getPos()) def motAbs(self, absDistance): if self.cbBacklash.isChecked(): self._Motor_.mbAbs(absDistance) else: self._Motor_.mAbs(absDistance) # Update text to show position self.txtPos.setValue(self._Motor_.getPos())
# Note: You can control multiple motors by creating more APTMotor Objects # Obtain current position of motor print(Motor1.getPos()) # You can control multiple motors by creating more APTMotor Objects # Serial numbers can be added later by using setSerialNumber and initializeHardwareDevice # This functionality is particularly useful in the GUI setup. Motor2 = APTMotor() Motor2.setSerialNumber(83828393) Motor2.initializeHardwareDevice() print(Motor2.getPos()) # Move motor forward by 1mm, wait half a second, and return to original position. # mRel is move relative. mAbs is move absolute (go to position xxx) Motor1.mRel(1) # advance 1mm time.sleep(.5) Motor1.mRel(-1) # retract 1mm time.sleep(1) # Move motor forward by 1mm, wait half a second, and return to original position, at a velocity of 0.5mm/sec motVel = 0.5 #motor velocity, in mm/sec Motor1.mcRel(1, motVel) # advance 1mm time.sleep(.5) Motor1.mcRel(-1, motVel) # retract 1mm # Clean up APT object, free up memory Motor1.cleanUpAPT()
class BBD103(): """ Thorlabs USB interface to BBD103 controller for a MLS203 stage """ def __init__(self, sn_motor1=94832870, sn_motor2=94832869, **kwds): """ Connect to the thorlabs stage at the specified port. """ self.live = True self.unit_to_um = 1000.0 # units are mm self.um_to_unit = 1.0 / self.unit_to_um self.x = 0.0 self.y = 0.0 # sn_motor1 = 94832870 # sn_motor2 = 94832869 self.Motor1 = APTMotor(sn_motor1, HWTYPE=44) # initialize motor 1 "x" self.Motor2 = APTMotor(sn_motor2, HWTYPE=44) # initizalize motor 2 "y" ## getStatus # # @return True/False if we are actually connected to the stage. # def getStatus(self): return self.live def goAbsolute(self, x, y): x = x * self.um_to_unit y = y * self.um_to_unit self.Motor1.mAbs(x) # self.Motor2.mAbs(y) # def goRelative(self, x, y): x = x * self.um_to_unit y = y * self.um_to_unit self.Motor1.mRel(x) # self.Motor2.mRel(y) # def jog(self, x_speed, y_speed): # shouldn't this also specify a relative position vx = x_speed * self.um_to_unit vy = y_speed * self.um_to_unit self.Motor1.setVel(x_speed) self.Motor2.setVel(y_speed) def joystickOnOff(self, on): if on: self.writeline("!joy 2") else: self.writeline("!joy 0") ## lockout # # Calls joystickOnOff. # # @param flag True/False. # def lockout(self, flag): self.joystickOnOff(not flag) ## position # # @return [stage x (um), stage y (um), stage z (um)] # def position(self): if self.live: x0 = self.Motor1.getPos() # query single axis y0 = self.Motor2.getPos() # query single axis return {"x": x0, "y": y0} def serialNumber(self): """ Return the stages serial number. """ return self.Motor1.getHardwareInformation() def setVelocity(self, x_vel, y_vel): """ x_vel - The maximum stage velocity allowed in x. y_vel - The maximum stage velocity allowed in y. I'm not sure this should be allowed to change the max velocity here. """ pass ## shutDown # # Disconnect from the stage. # def shutDown(self): # Disconnect from the stage (not sure this is correct) if self.live: self.Motor1.cleanUpAPT() self.Motor2.cleanUpAPT() def zero(self): pass