PySigmaKoki 2.0.0__tar.gz → 2.1.2__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,17 +1,17 @@
1
- Metadata-Version: 1.1
1
+ Metadata-Version: 2.1
2
2
  Name: PySigmaKoki
3
- Version: 2.0.0
3
+ Version: 2.1.2
4
4
  Summary: Python Interface for Instruments by Sigma Koki
5
5
  Home-page: https://github.com/akira-okumura/PySigmaKoki
6
6
  Author: Akira Okumura
7
7
  Author-email: oxon@mac.com
8
8
  License: BSD License
9
- Description:
10
- This is an interface module for instruments produced by Sigma Koki
11
-
12
9
  Platform: MacOS :: MacOS X
13
10
  Platform: POSIX
14
11
  Platform: Windows
15
12
  Classifier: Topic :: Terminals :: Serial
16
13
  Classifier: Development Status :: 5 - Production/Stable
17
14
  Classifier: Programming Language :: Python
15
+
16
+
17
+ This is an interface module for instruments produced by Sigma Koki
@@ -0,0 +1,17 @@
1
+ Metadata-Version: 2.1
2
+ Name: PySigmaKoki
3
+ Version: 2.1.2
4
+ Summary: Python Interface for Instruments by Sigma Koki
5
+ Home-page: https://github.com/akira-okumura/PySigmaKoki
6
+ Author: Akira Okumura
7
+ Author-email: oxon@mac.com
8
+ License: BSD License
9
+ Platform: MacOS :: MacOS X
10
+ Platform: POSIX
11
+ Platform: Windows
12
+ Classifier: Topic :: Terminals :: Serial
13
+ Classifier: Development Status :: 5 - Production/Stable
14
+ Classifier: Programming Language :: Python
15
+
16
+
17
+ This is an interface module for instruments produced by Sigma Koki
@@ -0,0 +1,8 @@
1
+ README.md
2
+ setup.py
3
+ sigma_koki.py
4
+ PySigmaKoki.egg-info/PKG-INFO
5
+ PySigmaKoki.egg-info/SOURCES.txt
6
+ PySigmaKoki.egg-info/dependency_links.txt
7
+ PySigmaKoki.egg-info/requires.txt
8
+ PySigmaKoki.egg-info/top_level.txt
@@ -0,0 +1 @@
1
+ pyserial
@@ -0,0 +1 @@
1
+ sigma_koki
@@ -0,0 +1,12 @@
1
+ # PySigmaKoki
2
+ Python module to control Sigma Koki stages
3
+
4
+ # Example
5
+ >>> import sigma_koki
6
+ >>> gsc02 = sigma_koki.GSC02()
7
+ >>> gsc02.open('/dev/tty.usbserial-FTT75V89A')
8
+ >>> gsc02.setSpeed(1, 50, 20000, 1000, 50, 20000, 1000)
9
+ >>> gsc02.returnToMechanicalOrigin('+', '+')
10
+ >>> gsc02.move(-50000, -50000)
11
+ >>> gsc02.getStatus()
12
+ '- 50000,- 50000,K,K,R'
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -2,7 +2,7 @@ from distutils.core import setup
2
2
  import sigma_koki
3
3
 
4
4
  setup(name='PySigmaKoki',
5
- version='2.0.0',
5
+ version='2.1.2',
6
6
  description='Python Interface for Instruments by Sigma Koki',
7
7
  author='Akira Okumura',
8
8
  author_email='oxon@mac.com',
@@ -0,0 +1,314 @@
1
+ """
2
+ This is an interface module for instruments produced by Sigma Koki
3
+ """
4
+
5
+ try:
6
+ # It is not needed to import ValueError in newer Python versions
7
+ from exceptions import ValueError
8
+ except:
9
+ pass
10
+ import serial
11
+ import sys
12
+
13
+ class BaseStageController(object):
14
+ """
15
+ Stage controller class commonly used for Sigma Koki GSC02 and SHOT702
16
+ """
17
+ def __init__(self, baudrate, product):
18
+ self.__baudRate = baudrate
19
+ self.__parityBit = 'N' # None
20
+ self.__dataBit = 8
21
+ self.__stopBit = 1
22
+ self.__rtscts = True
23
+ self.__product = product
24
+ self.__acknowledge = True
25
+
26
+ def setBaudRate(self, rate):
27
+ if product == 'GSC-02' and rate in (2400, 4800, 9600, 19200):
28
+ self.__baudRate = rate
29
+ elif product == 'SHOT-702' and rate == 38400:
30
+ self.__baudRate = rate
31
+ else:
32
+ raise ValueError('Attempting to set an invalid buard rate %d to %s. Must be chosen from 2400/4800/9600/19200 for GSC-02 and 38400 for SHOT-702.' % (rate, self.__product))
33
+
34
+ def disableAcknowledge(self):
35
+ self.__acknowledge = False
36
+
37
+ def write(self, command, acknowledge=True):
38
+ # 'str' class needs be converted into 'bytes'
39
+ # e.g., 'command' -> b'command'
40
+ self.serial.write((command + '\r\n').encode())
41
+
42
+ if not self.__acknowledge or not acknowledge:
43
+ return
44
+
45
+ ack = self.readline()
46
+ if ack == 'OK':
47
+ return
48
+ else:
49
+ raise RuntimeError('%s returned bad acknowledge "%s"' % (self.__product, ack))
50
+
51
+ def query(self, command):
52
+ self.write(command, False)
53
+ return self.readline()
54
+
55
+ def readline(self):
56
+ # convert 'bytes' to 'str'
57
+ result = str(self.serial.readline())
58
+ if result[:2] == "b'" and result[-1:] == "'":
59
+ result = result[2:-1] # drop byte code prefix and suffix
60
+ if result[-4:] == '\\r\\n':
61
+ result = result[:-4] # drop delimeter
62
+
63
+ return result
64
+
65
+ def open(self, port, readTimeOut = 1, writeTimeOut = 1):
66
+ self.serial = serial.Serial(port = port,
67
+ baudrate = self.__baudRate,
68
+ bytesize = self.__dataBit,
69
+ parity = self.__parityBit,
70
+ stopbits = self.__stopBit,
71
+ timeout = readTimeOut,
72
+ writeTimeout = writeTimeOut,
73
+ rtscts = self.__rtscts)
74
+
75
+ def close(self):
76
+ self.serial.close()
77
+
78
+ def returnToMechanicalOrigin(self, stage1, stage2):
79
+ """
80
+ Moves the stages to the +/- end points and reset the coordinate values
81
+ to zero.
82
+ """
83
+ if self.__product == 'GSC-02':
84
+ if stage1 == '+' and stage2 == '+':
85
+ self.write('H:W++')
86
+ elif stage1 == '+' and stage2 == '-':
87
+ self.write('H:W+-')
88
+ elif stage1 == '-' and stage2 == '+':
89
+ self.write('H:W-+')
90
+ elif stage1 == '-' and stage2 == '-':
91
+ self.write('H:W--')
92
+ elif stage1 == '+':
93
+ self.write('H:1+')
94
+ elif stage1 == '-':
95
+ self.write('H:1-')
96
+ elif stage2 == '+':
97
+ self.write('H:2+')
98
+ elif stage2 == '-':
99
+ self.write('H:2-')
100
+ else:
101
+ return
102
+ elif self.__product == 'SHOT-702':
103
+ if stage1 == True and stage2 == True:
104
+ self.write('H:W')
105
+ elif stage1 == True:
106
+ self.write('H:1')
107
+ elif stage2 == True:
108
+ self.write('H:2')
109
+ else:
110
+ return
111
+
112
+ def move(self, stage1, stage2):
113
+ """
114
+ Moves the stages with the specified values. Since GSC-02 is a half-step
115
+ stepping driver, 1 pulse corresponds to "half-step movement" in the
116
+ stage catalogues.
117
+ """
118
+ if self.__product == 'GSC-02':
119
+ limit = 16777214
120
+ elif self.__product == 'SHOT-702':
121
+ limit = 268435455
122
+
123
+ if not (-limit <= stage1 <= limit):
124
+ raise ValueError('stage1 must be between -%d and %d.' % (limit, limit))
125
+
126
+ if not (-limit <= stage2 <= limit):
127
+ raise ValueError('stage2 must be between -%d and %d.' % (limit, limit))
128
+
129
+ command = 'M:W'
130
+ if stage1 >= 0:
131
+ command += '+P%d' % stage1
132
+ else:
133
+ command += '-P%d' % -stage1
134
+
135
+ if stage2 >= 0:
136
+ command += '+P%d' % stage2
137
+ else:
138
+ command += '-P%d' % -stage2
139
+
140
+ self.write(command)
141
+ self.go()
142
+
143
+ def jog(self, stage1, stage2):
144
+ """
145
+ Moves the stages continuously at the minimum speed.
146
+ stage1: '+' positive direction, '-' negative direction
147
+ stage2: '+' positive direction, '-' negative direction
148
+ If other values are given, stages will not move.
149
+ """
150
+ if stage1 == '+' and stage2 == '+':
151
+ self.write('J:W++')
152
+ elif stage1 == '+' and stage2 == '-':
153
+ self.write('J:W+-')
154
+ elif stage1 == '-' and stage2 == '+':
155
+ self.write('J:W-+')
156
+ elif stage1 == '-' and stage2 == '-':
157
+ self.write('J:W--')
158
+ elif stage1 == '+':
159
+ self.write('J:1+')
160
+ elif stage1 == '-':
161
+ self.write('J:1-')
162
+ elif stage2 == '+':
163
+ self.write('J:2+')
164
+ elif stage2 == '-':
165
+ self.write('J:2-')
166
+ else:
167
+ return
168
+
169
+ self.go()
170
+
171
+ def go(self):
172
+ """
173
+ Moves the stages. To be used internally.
174
+ """
175
+ self.write('G')
176
+
177
+ def decelerate(self, stage1, stage2):
178
+ """
179
+ Decelerates and stop the stages.
180
+ """
181
+ if stage1 and stage2:
182
+ self.write('L:W')
183
+ elif stage1:
184
+ self.write('L:1')
185
+ elif stage2:
186
+ self.write('L:2')
187
+
188
+ def stop(self):
189
+ """
190
+ Stops the stages immediately.
191
+ """
192
+ self.write('L:E')
193
+
194
+ def initializeOrigin(self, stage1, stage2):
195
+ """
196
+ Sets the origin to the current position.
197
+ stage1: If true, set the origin of the stage 1 to the current position
198
+ stage2: If true, set the origin of the stage 1 to the current position
199
+ """
200
+ if stage1:
201
+ self.write('R:1')
202
+
203
+ if stage2:
204
+ self.write('R:2')
205
+
206
+ def enableMotorExcitation(self, stage1 = True, stage2 = False):
207
+ """
208
+ Enables motor excitation
209
+ """
210
+ if stage1 in (True, False):
211
+ self.write('C:1%d' % stage1)
212
+
213
+ if stage2 in (True, False):
214
+ self.write('C:2%d' % stage2)
215
+
216
+ def getStatus(self):
217
+ """
218
+ Returns the status of the controller
219
+ """
220
+ return self.query('Q:')
221
+
222
+ def getACK3(self):
223
+ """
224
+ Returns the status of ACK3
225
+ """
226
+ return self.query('!:')
227
+
228
+ def getVersion(self):
229
+ """
230
+ Returns the ROM version
231
+ """
232
+ return self.query('?:V')
233
+
234
+ class GSC02(BaseStageController):
235
+ """
236
+ Stage controller GSC-02
237
+ """
238
+ def __init__(self):
239
+ # 9600 bps the initial factory setting
240
+ BaseStageController.__init__(self, 9600, 'GSC-02')
241
+ self.disableAcknowledge()
242
+
243
+ def setSpeed(self, highspeed, minSpeed1, maxSpeed1, accelerationTime1,
244
+ minSpeed2, maxSpeed2, accelerationTime2):
245
+ """
246
+ Sets the movement speeds of the stages
247
+ highspeed: If true, speed range is 50-20000, else 1-200
248
+ minSpeed1/2: Minimum speed (PPS)
249
+ maxSpeed1/2: Maximum speed (PPS)
250
+ accelerationTime1/2: Acceleration time to be taken from min to max (ms)
251
+
252
+ | _________ ... maximum speed (PPS)
253
+ | / \
254
+ | / \
255
+ | / \ ... minimum speed (PPS)
256
+ | | |
257
+ | | |
258
+ |__|______________|________
259
+ <-> acceleration time (ms)
260
+ <-> deceleration time (ms)
261
+ """
262
+ if not highspeed:
263
+ if not (1 <= minSpeed1 <= maxSpeed1 <= 200):
264
+ raise ValueError('Must be 1 <= minSpeed1 <= maxSpeed1 <= 200 in low speed range.')
265
+ if not (1 <= minSpeed2 <= maxSpeed2 <= 200):
266
+ raise ValueError('Must be 1 <= minSpeed2 <= maxSpeed2 <= 200 in low speed range.')
267
+ else:
268
+ if not (50 <= minSpeed1 <= maxSpeed1 <= 20000):
269
+ raise ValueError('Must be 50 <= minSpeed1 <= maxSpeed1 <= 20000 in high speed range.')
270
+ if not (50 <= minSpeed2 <= maxSpeed2 <= 20000):
271
+ raise ValueError('Must be 50 <= minSpeed2 <= maxSpeed2 <= 20000 in high speed range.')
272
+
273
+ if not (0 <= accelerationTime1 <= 1000):
274
+ raise ValueError('Must be 0 <= accelerationTime1 <= 1000.')
275
+
276
+ if not (0 <= accelerationTime2 <= 1000):
277
+ raise ValueError('Must be 0 <= accelerationTime2 <= 1000.')
278
+
279
+ if highspeed:
280
+ self.write('D:2S%dF%dR%dS%dF%dR%d' % (minSpeed1, maxSpeed1, accelerationTime1, minSpeed2, maxSpeed2, accelerationTime2))
281
+ else:
282
+ self.write('D:1S%dF%dR%dS%dF%dR%d' % (minSpeed1, maxSpeed1, accelerationTime1, minSpeed2, maxSpeed2, accelerationTime2))
283
+
284
+ class SHOT702(BaseStageController):
285
+ """
286
+ Stage controller SHOT-702
287
+ """
288
+ def __init__(self):
289
+ # 9600 bps the initial factory setting
290
+ BaseStageController.__init__(self, 38400, 'SHOT-702')
291
+
292
+ def setSpeed(self, minSpeed1, maxSpeed1, accelerationTime1, minSpeed2, maxSpeed2, accelerationTime2):
293
+ """
294
+ Sets the movement speeds of the stages
295
+ minSpeed1/2: Minimum speed (PPS)
296
+ maxSpeed1/2: Maximum speed (PPS)
297
+ accelerationTime1/2: Acceleration time to be taken from min to max (ms)
298
+ """
299
+ if not (1 <= minSpeed1 <= maxSpeed1 <= 500000):
300
+ raise ValueError('Must be 1 <= minSpeed1 <= maxSpeed1 <= 500000.')
301
+
302
+ if not (1 <= minSpeed2 <= maxSpeed2 <= 500000):
303
+ raise ValueError('Must be 1 <= minSpeed2 <= maxSpeed2 <= 500000.')
304
+
305
+ if not (0 <= accelerationTime1 <= 1000):
306
+ raise ValueError('Must be 0 <= accelerationTime <= 1000.')
307
+
308
+ if not (0 <= accelerationTime2 <= 1000):
309
+ raise ValueError('Must be 0 <= accelerationTime <= 1000.')
310
+
311
+ self.write('D:WS%dF%dR%dS%dF%dR%d' % (minSpeed1, maxSpeed1, accelerationTime1, minSpeed2, maxSpeed2, accelerationTime2))
312
+
313
+ # Some query commands, ?:P, ?:S, ?:D, and ?:B, are not implemented yet
314
+
@@ -1,228 +0,0 @@
1
- """
2
- This is an interface module for instruments produced by Sigma Koki
3
- """
4
-
5
- try:
6
- from exceptions import ValueError
7
- except:
8
- pass
9
- import serial
10
- import sys
11
-
12
- class GSC02(object):
13
- """
14
- Stage controller GSC-02
15
- """
16
- def __init__(self):
17
- self.__baudRate = 9600 # 9600 bps
18
- self.__parityBit = 'N' # None
19
- self.__dataBit = 8
20
- self.__stopBit = 1
21
- self.__rtscts = True
22
-
23
- def setBaudRate(self, rate):
24
- if rate in (2400, 4800, 9600, 19200):
25
- self.__baudRate = rate
26
- else:
27
- raise ValueError('Invalid buard rate %d was given. Must be chosen from 2400/4800/9600/19200.' % rate)
28
-
29
- def open(self, port, readTimeOut = 1, writeTimeOut = 1):
30
- self.serial = serial.Serial(port = port,
31
- baudrate = self.__baudRate,
32
- bytesize = self.__dataBit,
33
- parity = self.__parityBit,
34
- stopbits = self.__stopBit,
35
- timeout = readTimeOut,
36
- writeTimeout = writeTimeOut,
37
- rtscts = self.__rtscts)
38
-
39
- def write(self, command):
40
- self.serial.write(command + b'\r\n')
41
-
42
- def readline(self):
43
- return self.serial.readline()[:-2]
44
-
45
- def returnToMechanicalOrigin(self, stage1, stage2):
46
- """
47
- Moves the stages to the +/- end points and reset the coordinate values
48
- to zero.
49
- """
50
- if stage1 == b'+' and stage2 == b'+':
51
- self.write(b'H:W++')
52
- elif stage1 == b'+' and stage2 == b'-':
53
- self.write(b'H:W+-')
54
- elif stage1 == b'-' and stage2 == b'+':
55
- self.write(b'H:W-+')
56
- elif stage1 == b'-' and stage2 == b'-':
57
- self.write(b'H:W--')
58
- elif stage1 == b'+':
59
- self.write(b'H:1+')
60
- elif stage1 == b'-':
61
- self.write(b'H:1-')
62
- elif stage2 == b'+':
63
- self.write(b'H:2+')
64
- elif stage2 == b'-':
65
- self.write(b'H:2-')
66
- else:
67
- return
68
-
69
- def move(self, stage1, stage2):
70
- """
71
- Moves the stages with the specified values. Since GSC-02 is a half-step
72
- stepping driver, 1 pulse corresponds to "half-step movement" in the
73
- stage catalogues.
74
- """
75
- if not (-16777214 <= stage1 <= 16777214):
76
- raise ValueError('stage1 must be between -16777214 and 16777214.')
77
-
78
- if not (-16777214 <= stage2 <= 16777214):
79
- raise ValueError('stage2 must be between -16777214 and 16777214.')
80
-
81
- command = b'M:W'
82
- if stage1 >= 0:
83
- command += b'+P%d' % stage1
84
- else:
85
- command += b'-P%d' % -stage1
86
-
87
- if stage2 >= 0:
88
- command += b'+P%d' % stage2
89
- else:
90
- command += b'-P%d' % -stage2
91
-
92
- self.write(command)
93
- self.go()
94
-
95
- def jog(self, stage1, stage2):
96
- """
97
- Moves the stages continuously at the minimum speed.
98
- stage1: '+' positive direction, '-' negative direction
99
- stage2: '+' positive direction, '-' negative direction
100
- If other values are given, stages will not move.
101
- """
102
- if stage1 == b'+' and stage2 == b'+':
103
- self.write(b'J:W++')
104
- elif stage1 == b'+' and stage2 == b'-':
105
- self.write(b'J:W+-')
106
- elif stage1 == b'-' and stage2 == b'+':
107
- self.write(b'J:W-+')
108
- elif stage1 == b'-' and stage2 == b'-':
109
- self.write(b'J:W--')
110
- elif stage1 == b'+':
111
- self.write(b'J:1+')
112
- elif stage1 == b'-':
113
- self.write(b'J:1-')
114
- elif stage2 == b'+':
115
- self.write(b'J:2+')
116
- elif stage2 == b'-':
117
- self.write(b'J:2-')
118
- else:
119
- return
120
-
121
- self.go()
122
-
123
- def go(self):
124
- """
125
- Moves the stages. To be used internally.
126
- """
127
- self.write(b'G')
128
-
129
- def decelerate(self, stage1, stage2):
130
- """
131
- Decelerates and stop the stages.
132
- """
133
- if stage1 and stage2:
134
- self.write(b'L:W')
135
- elif stage1:
136
- self.write(b'L:1')
137
- elif stage2:
138
- self.write(b'L:2')
139
-
140
- def stop(self):
141
- """
142
- Stops the stages immediately.
143
- """
144
- self.write(b'L:E')
145
-
146
- def initializeOrigin(self, stage1, stage2):
147
- """
148
- Sets the origin to the current position.
149
- stage1: If true, set the origin of the stage 1 to the current position
150
- stage2: If true, set the origin of the stage 1 to the current position
151
- """
152
- if stage1:
153
- self.write(b'R:1')
154
-
155
- if stage2:
156
- self.write(b'R:2')
157
-
158
- def setSpeed(self, highspeed, minSpeed1, maxSpeed1, accelerationTime1,
159
- minSpeed2, maxSpeed2, accelerationTime2):
160
- """
161
- Sets the movement speeds of the stages
162
- highspeed: If true, speed range is 50-20000, else 1-200
163
- minSpeed1/2: Minimum speed (PPS)
164
- maxSpeed1/2: Maximum speed (PPS)
165
- accelerationTime1/2: Acceleration time to be taken from min to max (ms)
166
-
167
- | _________ ... maximum speed (PPS)
168
- | / \
169
- | / \
170
- | / \ ... minimum speed (PPS)
171
- | | |
172
- | | |
173
- |__|______________|________
174
- <-> acceleration time (ms)
175
- <-> deceleration time (ms)
176
- """
177
- if not highspeed:
178
- if not (1 <= minSpeed1 <= maxSpeed1 <= 200):
179
- raise ValueError('Must be 1 <= minSpeed1 <= maxSpeed1 <= 200 in low speed range.')
180
- if not (1 <= minSpeed2 <= maxSpeed2 <= 200):
181
- raise ValueError('Must be 1 <= minSpeed2 <= maxSpeed2 <= 200 in low speed range.')
182
- else:
183
- if not (50 <= minSpeed1 <= maxSpeed1 <= 20000):
184
- raise ValueError('Must be 50 <= minSpeed1 <= maxSpeed1 <= 20000 in high speed range.')
185
- if not (50 <= minSpeed2 <= maxSpeed2 <= 20000):
186
- raise ValueError('Must be 50 <= minSpeed2 <= maxSpeed2 <= 20000 in high speed range.')
187
-
188
- if not (0 <= accelerationTime1 <= 1000):
189
- raise ValueError('Must be 00 <= accelerationTime1 <= 1000.')
190
-
191
- if not (0 <= accelerationTime2 <= 1000):
192
- raise ValueError('Must be 00 <= accelerationTime2 <= 1000.')
193
-
194
- if highspeed:
195
- self.write(b'D:2S%dF%dR%dS%dF%dR%d' % (minSpeed1, maxSpeed1, accelerationTime1, minSpeed2, maxSpeed2, accelerationTime2))
196
- else:
197
- self.write(b'D:1S%dF%dR%dS%dF%dR%d' % (minSpeed1, maxSpeed1, accelerationTime1, minSpeed2, maxSpeed2, accelerationTime2))
198
-
199
- def enableMotorExcitation(self, stage1 = True, stage2 = False):
200
- """
201
- Enables motor excitation
202
- """
203
- if stage1 in (True, False):
204
- self.write(b'C:1%d' % stage1)
205
-
206
- if stage2 in (True, False):
207
- self.write(b'C:2%d' % stage2)
208
-
209
- def getStatus(self):
210
- """
211
- Returns the status of the controller
212
- """
213
- self.write(b'Q:')
214
- return self.readline()
215
-
216
- def getACK3(self):
217
- """
218
- Returns the status of ACK3
219
- """
220
- self.write(b'!:')
221
- return self.readline()
222
-
223
- def getVersion(self):
224
- """
225
- Returns the ROM version
226
- """
227
- self.write(b'?:V')
228
- return self.readline()