PySigmaKoki 1.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.0
1
+ Metadata-Version: 2.1
2
2
  Name: PySigmaKoki
3
- Version: 1.0.0
3
+ Version: 2.1.2
4
4
  Summary: Python Interface for Instruments by Sigma Koki
5
- Home-page: https://sourceforge.net/p/pysigmakoki/
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
- Classifier: Development Status :: 4 - Beta
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,17 +2,17 @@ from distutils.core import setup
2
2
  import sigma_koki
3
3
 
4
4
  setup(name='PySigmaKoki',
5
- version='1.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',
9
9
  license='BSD License',
10
10
  platforms=['MacOS :: MacOS X', 'POSIX', 'Windows'],
11
- url='https://sourceforge.net/p/pysigmakoki/',
11
+ url='https://github.com/akira-okumura/PySigmaKoki',
12
12
  py_modules=['sigma_koki'],
13
13
  install_requires=['pyserial'],
14
14
  classifiers=['Topic :: Terminals :: Serial',
15
- 'Development Status :: 4 - Beta',
15
+ 'Development Status :: 5 - Production/Stable',
16
16
  'Programming Language :: Python',
17
17
  ],
18
18
  long_description=sigma_koki.__doc__
@@ -2,26 +2,65 @@
2
2
  This is an interface module for instruments produced by Sigma Koki
3
3
  """
4
4
 
5
- import exceptions
5
+ try:
6
+ # It is not needed to import ValueError in newer Python versions
7
+ from exceptions import ValueError
8
+ except:
9
+ pass
6
10
  import serial
7
11
  import sys
8
12
 
9
- class GSC02(object):
13
+ class BaseStageController(object):
10
14
  """
11
- Stage controller GSC-02
15
+ Stage controller class commonly used for Sigma Koki GSC02 and SHOT702
12
16
  """
13
- def __init__(self):
14
- self.__baudRate = 9600 # 9600 bps
17
+ def __init__(self, baudrate, product):
18
+ self.__baudRate = baudrate
15
19
  self.__parityBit = 'N' # None
16
20
  self.__dataBit = 8
17
21
  self.__stopBit = 1
18
22
  self.__rtscts = True
23
+ self.__product = product
24
+ self.__acknowledge = True
19
25
 
20
26
  def setBaudRate(self, rate):
21
- if rate in (2400, 4800, 9600, 19200):
27
+ if product == 'GSC-02' and rate in (2400, 4800, 9600, 19200):
28
+ self.__baudRate = rate
29
+ elif product == 'SHOT-702' and rate == 38400:
22
30
  self.__baudRate = rate
23
31
  else:
24
- raise exceptions.ValueError('Invalid buard rate %d was given. Must be chosen from 2400/4800/9600/19200.' % rate)
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
25
64
 
26
65
  def open(self, port, readTimeOut = 1, writeTimeOut = 1):
27
66
  self.serial = serial.Serial(port = port,
@@ -33,35 +72,42 @@ class GSC02(object):
33
72
  writeTimeout = writeTimeOut,
34
73
  rtscts = self.__rtscts)
35
74
 
36
- def write(self, command):
37
- self.serial.write(command + '\r\n')
38
-
39
- def readline(self):
40
- return self.serial.readline()[:-2]
75
+ def close(self):
76
+ self.serial.close()
41
77
 
42
78
  def returnToMechanicalOrigin(self, stage1, stage2):
43
79
  """
44
80
  Moves the stages to the +/- end points and reset the coordinate values
45
81
  to zero.
46
82
  """
47
- if stage1 == '+' and stage2 == '+':
48
- self.write('H:W++')
49
- elif stage1 == '+' and stage2 == '-':
50
- self.write('H:W+-')
51
- elif stage1 == '-' and stage2 == '+':
52
- self.write('H:W-+')
53
- elif stage1 == '-' and stage2 == '-':
54
- self.write('H:W--')
55
- elif stage1 == '+':
56
- self.write('H:1+')
57
- elif stage1 == '-':
58
- self.write('H:1-')
59
- elif stage2 == '+':
60
- self.write('H:2+')
61
- elif stage2 == '-':
62
- self.write('H:2-')
63
- else:
64
- return
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
65
111
 
66
112
  def move(self, stage1, stage2):
67
113
  """
@@ -69,11 +115,16 @@ class GSC02(object):
69
115
  stepping driver, 1 pulse corresponds to "half-step movement" in the
70
116
  stage catalogues.
71
117
  """
72
- if not (-16777214 <= stage1 <= 16777214):
73
- raise exceptions.ValueError('stage1 must be between -16777214 and 16777214.')
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))
74
125
 
75
- if not (-16777214 <= stage2 <= 16777214):
76
- raise exceptions.ValueError('stage2 must be between -16777214 and 16777214.')
126
+ if not (-limit <= stage2 <= limit):
127
+ raise ValueError('stage2 must be between -%d and %d.' % (limit, limit))
77
128
 
78
129
  command = 'M:W'
79
130
  if stage1 >= 0:
@@ -152,6 +203,43 @@ class GSC02(object):
152
203
  if stage2:
153
204
  self.write('R:2')
154
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
+
155
243
  def setSpeed(self, highspeed, minSpeed1, maxSpeed1, accelerationTime1,
156
244
  minSpeed2, maxSpeed2, accelerationTime2):
157
245
  """
@@ -173,53 +261,54 @@ class GSC02(object):
173
261
  """
174
262
  if not highspeed:
175
263
  if not (1 <= minSpeed1 <= maxSpeed1 <= 200):
176
- raise exceptions.ValueError('Must be 1 <= minSpeed1 <= maxSpeed1 <= 200 in low speed range.')
264
+ raise ValueError('Must be 1 <= minSpeed1 <= maxSpeed1 <= 200 in low speed range.')
177
265
  if not (1 <= minSpeed2 <= maxSpeed2 <= 200):
178
- raise exceptions.ValueError('Must be 1 <= minSpeed2 <= maxSpeed2 <= 200 in low speed range.')
266
+ raise ValueError('Must be 1 <= minSpeed2 <= maxSpeed2 <= 200 in low speed range.')
179
267
  else:
180
268
  if not (50 <= minSpeed1 <= maxSpeed1 <= 20000):
181
- raise exceptions.ValueError('Must be 50 <= minSpeed1 <= maxSpeed1 <= 20000 in high speed range.')
269
+ raise ValueError('Must be 50 <= minSpeed1 <= maxSpeed1 <= 20000 in high speed range.')
182
270
  if not (50 <= minSpeed2 <= maxSpeed2 <= 20000):
183
- raise exceptions.ValueError('Must be 50 <= minSpeed2 <= maxSpeed2 <= 20000 in high speed range.')
271
+ raise ValueError('Must be 50 <= minSpeed2 <= maxSpeed2 <= 20000 in high speed range.')
184
272
 
185
273
  if not (0 <= accelerationTime1 <= 1000):
186
- raise exceptions.ValueError('Must be 00 <= accelerationTime1 <= 1000.')
274
+ raise ValueError('Must be 0 <= accelerationTime1 <= 1000.')
187
275
 
188
276
  if not (0 <= accelerationTime2 <= 1000):
189
- raise exceptions.ValueError('Must be 00 <= accelerationTime2 <= 1000.')
277
+ raise ValueError('Must be 0 <= accelerationTime2 <= 1000.')
190
278
 
191
279
  if highspeed:
192
280
  self.write('D:2S%dF%dR%dS%dF%dR%d' % (minSpeed1, maxSpeed1, accelerationTime1, minSpeed2, maxSpeed2, accelerationTime2))
193
281
  else:
194
282
  self.write('D:1S%dF%dR%dS%dF%dR%d' % (minSpeed1, maxSpeed1, accelerationTime1, minSpeed2, maxSpeed2, accelerationTime2))
195
283
 
196
- def enableMotorExcitation(self, stage1 = True, stage2 = False):
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):
197
293
  """
198
- Enables motor excitation
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)
199
298
  """
200
- if stage1 in (True, False):
201
- self.write('C:1%d' % stage1)
299
+ if not (1 <= minSpeed1 <= maxSpeed1 <= 500000):
300
+ raise ValueError('Must be 1 <= minSpeed1 <= maxSpeed1 <= 500000.')
202
301
 
203
- if stage2 in (True, False):
204
- self.write('C:2%d' % stage2)
302
+ if not (1 <= minSpeed2 <= maxSpeed2 <= 500000):
303
+ raise ValueError('Must be 1 <= minSpeed2 <= maxSpeed2 <= 500000.')
205
304
 
206
- def getStatus(self):
207
- """
208
- Returns the status of the controller
209
- """
210
- self.write('Q:')
211
- return self.readline()
305
+ if not (0 <= accelerationTime1 <= 1000):
306
+ raise ValueError('Must be 0 <= accelerationTime <= 1000.')
212
307
 
213
- def getACK3(self):
214
- """
215
- Returns the status of ACK3
216
- """
217
- self.write('!:')
218
- return self.readline()
308
+ if not (0 <= accelerationTime2 <= 1000):
309
+ raise ValueError('Must be 0 <= accelerationTime <= 1000.')
219
310
 
220
- def getVersion(self):
221
- """
222
- Returns the ROM version
223
- """
224
- self.write('?:V')
225
- return self.readline()
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
+
PySigmaKoki-1.0.0/README DELETED
@@ -1,12 +0,0 @@
1
- === Requirements ===
2
- - PySerial
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'