forked from mcleu/PyAPT
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathPyAPT.py
More file actions
317 lines (278 loc) · 12.2 KB
/
PyAPT.py
File metadata and controls
317 lines (278 loc) · 12.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
# -*- coding: utf-8 -*-
"""
APT Motor Controller for Thorlabs
Adopted from
https://github.com/HaeffnerLab/Haeffner-Lab-LabRAD-Tools/blob/master/cdllservers/APTMotor/APTMotorServer.py
With thanks to SeanTanner@ThorLabs for providing APT.dll and APT.lib
V1.1
20141125 V1.0 First working version
20141201 V1.0a Use short notation for moving (movRelative -> mRel)
20150417 V1.1 Implementation of simple QT GUI
Michael Leung
mcleung@stanford.edu
"""
from ctypes import c_long, c_buffer, c_float, windll, pointer
import os
print os.getcwd()
class APTMotor():
def __init__(self, SerialNum=None, HWTYPE=31, verbose=False):
'''
HWTYPE_BSC001 11 // 1 Ch benchtop stepper driver
HWTYPE_BSC101 12 // 1 Ch benchtop stepper driver
HWTYPE_BSC002 13 // 2 Ch benchtop stepper driver
HWTYPE_BDC101 14 // 1 Ch benchtop DC servo driver
HWTYPE_SCC001 21 // 1 Ch stepper driver card (used within BSC102,103 units)
HWTYPE_DCC001 22 // 1 Ch DC servo driver card (used within BDC102,103 units)
HWTYPE_ODC001 24 // 1 Ch DC servo driver cube
HWTYPE_OST001 25 // 1 Ch stepper driver cube
HWTYPE_MST601 26 // 2 Ch modular stepper driver module
HWTYPE_TST001 29 // 1 Ch Stepper driver T-Cube
HWTYPE_TDC001 31 // 1 Ch DC servo driver T-Cube
HWTYPE_LTSXXX 42 // LTS300/LTS150 Long Travel Integrated Driver/Stages
HWTYPE_L490MZ 43 // L490MZ Integrated Driver/Labjack
HWTYPE_BBD10X 44 // 1/2/3 Ch benchtop brushless DC servo driver
'''
self.verbose = verbose
self.Connected = False
dllname = os.path.join(os.path.dirname(__file__), 'APT.dll')
if not os.path.exists(dllname):
print "ERROR: DLL not found"
self.aptdll = windll.LoadLibrary(dllname)
self.aptdll.EnableEventDlg(True)
self.aptdll.APTInit()
#print 'APT initialized'
self.HWType = c_long(HWTYPE)
self.blCorr = 0.10 #100um backlash correction
if SerialNum is not None:
if self.verbose: print "Serial is", SerialNum
self.SerialNum = c_long(SerialNum)
self.initializeHardwareDevice()
# TODO : Error reporting to know if initialisation went sucessfully or not.
else:
if self.verbose: print "No serial, please setSerialNumber"
def getNumberOfHardwareUnits(self):
'''
Returns the number of HW units connected that are available to be interfaced
'''
numUnits = c_long()
self.aptdll.GetNumHWUnitsEx(self.HWType, pointer(numUnits))
return numUnits.value
def getSerialNumberByIdx(self, index):
'''
Returns the Serial Number of the specified index
'''
HWSerialNum = c_long()
hardwareIndex = c_long(index)
self.aptdll.GetHWSerialNumEx(self.HWType, hardwareIndex, pointer(HWSerialNum))
return HWSerialNum
def setSerialNumber(self, SerialNum):
'''
Sets the Serial Number of the specified index
'''
if self.verbose: print "Serial is", SerialNum
self.SerialNum = c_long(SerialNum)
return self.SerialNum.value
def initializeHardwareDevice(self):
'''
Initialises the motor.
You can only get the position of the motor and move the motor after it has been initialised.
Once initiallised, it will not respond to other objects trying to control it, until released.
'''
if self.verbose: print 'initializeHardwareDevice serial', self.SerialNum
result = self.aptdll.InitHWDevice(self.SerialNum)
if result == 0:
self.Connected = True
if self.verbose: print 'initializeHardwareDevice connection SUCESS'
# need some kind of error reporting here
else:
raise Exception('Connection Failed. Check Serial Number!')
return True
''' Interfacing with the motor settings '''
def getHardwareInformation(self):
model = c_buffer(255)
softwareVersion = c_buffer(255)
hardwareNotes = c_buffer(255)
self.aptdll.GetHWInfo(self.SerialNum, model, 255, softwareVersion, 255, hardwareNotes, 255)
hwinfo = [model.value, softwareVersion.value, hardwareNotes.value]
return hwinfo
def getStageAxisInformation(self):
minimumPosition = c_float()
maximumPosition = c_float()
units = c_long()
pitch = c_float()
self.aptdll.MOT_GetStageAxisInfo(self.SerialNum, pointer(minimumPosition), pointer(maximumPosition), pointer(units), pointer(pitch))
stageAxisInformation = [minimumPosition.value, maximumPosition.value, units.value, pitch.value]
return stageAxisInformation
def setStageAxisInformation(self, minimumPosition, maximumPosition):
minimumPosition = c_float(minimumPosition)
maximumPosition = c_float(maximumPosition)
units = c_long(1) #units of mm
# Get different pitches of lead screw for moving stages for different stages.
pitch = c_float(self.config.get_pitch())
self.aptdll.MOT_SetStageAxisInfo(self.SerialNum, minimumPosition, maximumPosition, units, pitch)
return True
def getHardwareLimitSwitches(self):
reverseLimitSwitch = c_long()
forwardLimitSwitch = c_long()
self.aptdll.MOT_GetHWLimSwitches(self.SerialNum, pointer(reverseLimitSwitch), pointer(forwardLimitSwitch))
hardwareLimitSwitches = [reverseLimitSwitch.value, forwardLimitSwitch.value]
return hardwareLimitSwitches
def getVelocityParameters(self):
minimumVelocity = c_float()
acceleration = c_float()
maximumVelocity = c_float()
self.aptdll.MOT_GetVelParams(self.SerialNum, pointer(minimumVelocity), pointer(acceleration), pointer(maximumVelocity))
velocityParameters = [minimumVelocity.value, acceleration.value, maximumVelocity.value]
return velocityParameters
def getVel(self):
if self.verbose: print 'getVel probing...'
minVel, acc, maxVel = self.getVelocityParameters()
if self.verbose: print 'getVel maxVel'
return maxVel
def setVelocityParameters(self, minVel, acc, maxVel):
minimumVelocity = c_float(minVel)
acceleration = c_float(acc)
maximumVelocity = c_float(maxVel)
self.aptdll.MOT_SetVelParams(self.SerialNum, minimumVelocity, acceleration, maximumVelocity)
return True
def setVel(self, maxVel):
if self.verbose: print 'setVel', maxVel
minVel, acc, oldVel = self.getVelocityParameters()
self.setVelocityParameters(minVel, acc, maxVel)
return True
def getVelocityParameterLimits(self):
maximumAcceleration = c_float()
maximumVelocity = c_float()
self.aptdll.MOT_GetVelParamLimits(self.SerialNum, pointer(maximumAcceleration), pointer(maximumVelocity))
velocityParameterLimits = [maximumAcceleration.value, maximumVelocity.value]
return velocityParameterLimits
'''
Controlling the motors
m = move
c = controlled velocity
b = backlash correction
Rel = relative distance from current position.
Abs = absolute position
'''
def getPos(self):
'''
Obtain the current absolute position of the stage
'''
if self.verbose: print 'getPos probing...'
if not self.Connected:
raise Exception('Please connect first! Use initializeHardwareDevice')
position = c_float()
self.aptdll.MOT_GetPosition(self.SerialNum, pointer(position))
if self.verbose: print 'getPos ', position.value
return position.value
def mRel(self, relDistance):
'''
Moves the motor a relative distance specified
relDistance float Relative position desired
'''
if self.verbose: print 'mRel ', relDistance, c_float(relDistance)
if not self.Connected:
print 'Please connect first! Use initializeHardwareDevice'
#raise Exception('Please connect first! Use initializeHardwareDevice')
relativeDistance = c_float(relDistance)
self.aptdll.MOT_MoveRelativeEx(self.SerialNum, relativeDistance, True)
if self.verbose: print 'mRel SUCESS'
return True
def mAbs(self, absPosition):
'''
Moves the motor to the Absolute position specified
absPosition float Position desired
'''
if self.verbose: print 'mAbs ', absPosition, c_float(absPosition)
if not self.Connected:
raise Exception('Please connect first! Use initializeHardwareDevice')
absolutePosition = c_float(absPosition)
self.aptdll.MOT_MoveAbsoluteEx(self.SerialNum, absolutePosition, True)
if self.verbose: print 'mAbs SUCESS'
return True
def mcRel(self, relDistance, moveVel=0.5):
'''
Moves the motor a relative distance specified at a controlled velocity
relDistance float Relative position desired
moveVel float Motor velocity, mm/sec
'''
if self.verbose: print 'mcRel ', relDistance, c_float(relDistance), 'mVel', moveVel
if not self.Connected:
raise Exception('Please connect first! Use initializeHardwareDevice')
# Save velocities to reset after move
maxVel = self.getVelocityParameterLimits()[1]
# Set new desired max velocity
self.setVel(moveVel)
self.mRel(relDistance)
self.setVel(maxVel)
if self.verbose: print 'mcRel SUCESS'
return True
def mcAbs(self, absPosition, moveVel=0.5):
'''
Moves the motor to the Absolute position specified at a controlled velocity
absPosition float Position desired
moveVel float Motor velocity, mm/sec
'''
if self.verbose: print 'mcAbs ', absPosition, c_float(absPosition), 'mVel', moveVel
if not self.Connected:
raise Exception('Please connect first! Use initializeHardwareDevice')
# Save velocities to reset after move
minVel, acc, maxVel = self.getVelocityParameters()
# Set new desired max velocity
self.setVel(moveVel)
self.mAbs(absPosition)
self.setVel(maxVel)
if self.verbose: print 'mcAbs SUCESS'
return True
def mbRel(self, relDistance):
'''
Moves the motor a relative distance specified
relDistance float Relative position desired
'''
if self.verbose: print 'mbRel ', relDistance, c_float(relDistance)
if not self.Connected:
print 'Please connect first! Use initializeHardwareDevice'
#raise Exception('Please connect first! Use initializeHardwareDevice')
self.mRel(relDistance-self.blCorr)
self.mRel(self.blCorr)
if self.verbose: print 'mbRel SUCESS'
return True
def mbAbs(self, absPosition):
'''
Moves the motor to the Absolute position specified
absPosition float Position desired
'''
if self.verbose: print 'mbAbs ', absPosition, c_float(absPosition)
if not self.Connected:
raise Exception('Please connect first! Use initializeHardwareDevice')
if (absPosition < self.getPos()):
if self.verbose: print 'backlash mAbs', absPosition - self.blCorr
self.mAbs(absPosition-self.blCorr)
self.mAbs(absPosition)
if self.verbose: print 'mbAbs SUCESS'
return True
def go_home(self):
'''
Move the stage to home position and reset position entry
'''
if self.verbose: print 'Going home'
if not self.Connected:
raise Exception('Please connect first! Use initializeHardwareDevice')
if self.verbose: print 'go_home SUCESS'
self.aptdll.MOT_MoveHome(self.SerialNum)
return True
''' Miscelaneous '''
def identify(self):
'''
Causes the motor to blink the Active LED
'''
self.aptdll.MOT_Identify(self.SerialNum)
return True
def cleanUpAPT(self):
'''
Releases the APT object
Use when exiting the program
'''
self.aptdll.APTCleanUp()
if self.verbose: print 'APT cleaned up'
self.Connected = False