1import nidaqmx
2import pipython
3import sys
4import time
5import numpy as np
6import matplotlib.pyplot as plt
7import threading
8
9from pipython import datarectools, pitools
10
11def setup():
12
13 # Set up stage
14 pidevice = pipython.GCSDevice('E-727')
15
16 usb_devices = pidevice.EnumerateUSB()
17 if len(usb_devices) < 1:
18 print("No PI stages found - exiting")
19 sys.exit()
20
21 pidevice.ConnectUSB(usb_devices[0].split(' ')[-1])
22 pitools.startup(pidevice, servostates=True)
23 pitools.waitontarget(pidevice, [1, 2, 3])
24 tstart = time.time_ns()
25 print(pidevice.qPOS([1, 2, 3]))
26 print(time.time_ns() - tstart)
27
28 task = nidaqmx.Task()
29 task.do_channels.add_do_chan("cDAQ1Mod3/port0/line2",
30 line_grouping=nidaqmx.constants.LineGrouping.CHAN_PER_LINE)
31 task.start()
32
33 return (task, pidevice)
34
35
36class BufferTimer(threading.Thread):
37 def __init__(self, event, fn, interval):
38 threading.Thread.__init__(self)
39 self.stopped = event
40 self.fn = fn
41 self.interval = interval
42 def run(self):
43 while not self.stopped.wait(self.interval):
44 self.fn()
45
46class Recorder:
47 """
48 Wrapper for the PiPython GCS 2.0 data recorder
49 """
50
51 def __init__(self, pidevice, sample_rate=500, sources=None, options=None):
52 self.sample_rate = sample_rate
53 self._drec = datarectools.Datarecorder(pidevice)
54 if options is None:
55 # Default: actual position
56 options = datarectools.RecordOptions.ACTUAL_POSITION_2
57 if sources is None:
58 # Default: all axes
59 sources = pidevice.axes
60
61 self._drec.samplefrequ = sample_rate
62 self._drec.options = options
63 self._drec.sources = sources
64 self._drec.trigsources = datarectools.TriggerSources.TRIGGER_IMMEDIATELY_4
65 self.maxsamples = int(datarectools.getmaxnumvalues(pidevice) / len(sources))
66
67 self.interval = self.maxsamples * self._drec.sampletime / 1.5
68 print(self.interval)
69 self._stop_flag = threading.Event()
70 self._refresh_thread = BufferTimer(self._stop_flag, self.get_data, self.interval)
71 self.read_in_progress = False
72
73 self.data = np.zeros((0, len(self._drec.sources)+1))
74 self.headers = []
75 self._time_start = []
76 self._time_end = []
77
78 def start(self):
79 self._drec.arm()
80 self._time_start.append(time.time_ns())
81 print("Starting recording at {}".format((self._time_start[-1] - self._time_start[0])/1e9))
82 self._refresh_thread.start()
83
84 def refresh(self):
85 self._drec._gcs.DRT(0, datarectools.TriggerSources.TRIGGER_IMMEDIATELY_4)
86 self._time_start.append(time.time_ns())
87
88 def get_data(self, refresh=True):
89 self.read_in_progress = True
90 time_start = self._time_start[-1]
91 time_current = time.time_ns()
92 print("Starting reading at {}".format((time_current - self._time_start[0])/1e9))
93 elapsed_time = (time_current - time_start) / 1e9
94
95 read_no_samples = int(elapsed_time / self._drec.sampletime)
96 extra_samples = int(0.5*read_no_samples)
97 read_no_samples += extra_samples
98 data = np.zeros((read_no_samples, len(self._drec.sources)+1))
99 print("Data: {}".format(data.shape))
100 start_timeval = (self._time_start[-1] - self._time_start[0])/1e9
101 print("Start timeval: {}".format(start_timeval))
102 print("Predicted elapsed time: {}, Actual elapsed time: {}".format(read_no_samples*self._drec.sampletime, elapsed_time))
103 times = np.arange(start_timeval, start_timeval+elapsed_time-self._drec.sampletime + extra_samples*self._drec.sampletime, step=self._drec.sampletime)
104 print("Times: {}".format(times.shape))
105 data[:,0] = times
106 tables = list(range(1, len(self._drec.sources)+1))
107 header = pidevice.qDRR(tables, 1, read_no_samples)
108 while pidevice.bufstate is not True:
109 time.sleep(0.01)
110 if refresh:
111 self.refresh()
112 d = np.array(pidevice.bufdata).transpose()
113 data[:,1:] = d
114 print(d[0,1:3])
115 print(d[-1,1:3])
116
117 self.data = np.vstack((self.data, data))
118 self.read_in_progress = False
119
120 def _plot_data(self, data):
121 fig, ax = plt.subplots()
122 ax.plot(data[:,0], data[:,1], label='x', marker='.')
123 ax.plot(data[:,0], data[:,2], label='y', marker='.')
124 ax.plot(data[:,0], data[:,3], label='z', marker='.')
125 plt.legend()
126 plt.show()
127
128 def stop(self, plot=False):
129 print("Saving")
130 self._stop_flag.set()
131 while self.read_in_progress is True:
132 time.sleep(0.1)
133 self.get_data(refresh=False)
134 diffs = np.diff(self.data[:,0])
135 max_diff = np.max(diffs)
136 print("Max gap: {}".format(max_diff))
137 np.savetxt("data.txt", self.data, delimiter=',')
138 if plot:
139 self._plot_data(self.data)
140
141
142
143def lines(task, pidevice):
144
145 focus_top = 9
146 focus_bottom = 9
147 focus_range = 50
148 start_x = 116
149 start_y = 100
150 pitch = 3
151 line_length = 20
152
153 # Go to origin
154 pidevice.MOV({1: start_x, 2: start_y, 3: focus_top})
155
156 # set velocity
157 velocities = [0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000]
158 #velocities = [1]
159 pidevice.VCO({2: True})
160
161 for i, vel in enumerate(velocities):
162
163 # Calculate x coordinate for this line
164 x = i * pitch
165 z = focus_top + (focus_bottom - focus_top) / focus_range * x
166
167 # Go to start position
168 pidevice.VEL({2: 100})
169 pidevice.MOV({1: start_x + x, 2: start_y, 3: z})
170 pitools.waitontarget(pidevice, [1, 2, 3])
171 time.sleep(0.2)
172
173 # Turn on laser
174 task.write(True)
175 time.sleep(0.006)
176
177 # Start line
178 pidevice.VEL({2: vel})
179 pidevice.MOV({2: start_y + line_length})
180 pitools.waitontarget(pidevice, [1, 2, 3])
181
182 # Turn off laser
183 task.write(False)
184 time.sleep(0.2)
185
186 # Go to origin
187 pidevice.VEL({2: 100})
188 pidevice.MOV({1: start_x, 2: start_y, 3: focus_top})
189 pitools.waitontarget(pidevice, [1, 2, 3])
190
191def dots(task, pidevice):
192
193 # Focusing procedure:
194 # Get two z values where the beam is in focus at two points: the left
195 # and right sides of the writing area. Put these values in focus_*,
196 # and the distance between the two sample points in focus_range.
197 focus_left = 8.5
198 focus_right = 8.5
199 focus_range = 10
200
201 # Positioning parameters
202 start_x = 25
203 start_y = 0
204 pitch = 5
205
206 # Go to origin
207 #pidevice.MOV({1: start_x, 2: start_y, 3: focus_left})
208 pidevice.MOV({1: start_x, 2: start_y})
209
210 # Set exposure times in ms
211 #times = np.array([10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000])
212 times = np.array([10, 20, 50, 100, 200, 500, 1000])
213 for i, t in enumerate(times):
214
215 # Go to dot position
216 y = start_y + i * pitch
217 z = focus_left + (focus_right - focus_left) / focus_range * y
218 #pidevice.MOV({2: y, 3: z})
219 pidevice.MOV({2: y})
220 #pitools.waitontarget(pidevice, [1, 2, 3])
221 pitools.waitontarget(pidevice, [1, 2])
222 time.sleep(0.1)
223
224 # Write dot
225 print("{} of {}: {} ms".format(i+1, len(times), t))
226 task.write(True)
227 time.sleep(t/1e3)
228 task.write(False)
229
230 time.sleep(0.5)
231
232 # Go to origin
233 #pidevice.MOV({1: start_x, 2: start_y, 3: focus_left})
234 #pitools.waitontarget(pidevice, [1, 2, 3])
235 pidevice.MOV({1: start_x, 2: start_y})
236 pitools.waitontarget(pidevice, [1, 2])
237
238def test_rec(pidevice):
239 pidevice.VCO({1: True, 2: True})
240 pidevice.VEL({1: 1000, 2: 1000})
241 pidevice.MOV({1: 0, 2: 0})
242 pitools.waitontarget(pidevice, [1, 2])
243 pidevice.VEL({1: 20, 2: 20})
244 rec = Recorder(pidevice)
245 rec.start()
246 pidevice.MOV({1: 100, 2: 100})
247 #pitools.waitontarget(pidevice, [1, 2, 2])
248 time.sleep(15)
249 #rec.get_data()
250 #pitools.waitontarget(pidevice, [1, 2, 3])
251 #rec.get_data()
252 # time.sleep(5)
253 # rec.get_data()
254 rec.stop(plot=True)
255
256
257if __name__ == "__main__":
258 task, pidevice = setup()
259 try:
260 #lines(task, pidevice)
261 dots(task, pidevice)
262 #test_rec(pidevice)
263 finally:
264 pitools.stopall(pidevice)
265 task.close()