import nidaqmx import pipython import sys import time import numpy as np import matplotlib.pyplot as plt import threading from pipython import datarectools, pitools def setup(): # Set up stage pidevice = pipython.GCSDevice('E-727') usb_devices = pidevice.EnumerateUSB() if len(usb_devices) < 1: print("No PI stages found - exiting") sys.exit() pidevice.ConnectUSB(usb_devices[0].split(' ')[-1]) pitools.startup(pidevice, servostates=True) pitools.waitontarget(pidevice, [1, 2, 3]) tstart = time.time_ns() print(pidevice.qPOS([1, 2, 3])) print(time.time_ns() - tstart) task = nidaqmx.Task() task.do_channels.add_do_chan("cDAQ1Mod3/port0/line2", line_grouping=nidaqmx.constants.LineGrouping.CHAN_PER_LINE) task.start() return (task, pidevice) class BufferTimer(threading.Thread): def __init__(self, event, fn, interval): threading.Thread.__init__(self) self.stopped = event self.fn = fn self.interval = interval def run(self): while not self.stopped.wait(self.interval): self.fn() class Recorder: """ Wrapper for the PiPython GCS 2.0 data recorder """ def __init__(self, pidevice, sample_rate=500, sources=None, options=None): self.sample_rate = sample_rate self._drec = datarectools.Datarecorder(pidevice) if options is None: # Default: actual position options = datarectools.RecordOptions.ACTUAL_POSITION_2 if sources is None: # Default: all axes sources = pidevice.axes self._drec.samplefrequ = sample_rate self._drec.options = options self._drec.sources = sources self._drec.trigsources = datarectools.TriggerSources.TRIGGER_IMMEDIATELY_4 self.maxsamples = int(datarectools.getmaxnumvalues(pidevice) / len(sources)) self.interval = self.maxsamples * self._drec.sampletime / 1.5 print(self.interval) self._stop_flag = threading.Event() self._refresh_thread = BufferTimer(self._stop_flag, self.get_data, self.interval) self.read_in_progress = False self.data = np.zeros((0, len(self._drec.sources)+1)) self.headers = [] self._time_start = [] self._time_end = [] def start(self): self._drec.arm() self._time_start.append(time.time_ns()) print("Starting recording at {}".format((self._time_start[-1] - self._time_start[0])/1e9)) self._refresh_thread.start() def refresh(self): self._drec._gcs.DRT(0, datarectools.TriggerSources.TRIGGER_IMMEDIATELY_4) self._time_start.append(time.time_ns()) def get_data(self, refresh=True): self.read_in_progress = True time_start = self._time_start[-1] time_current = time.time_ns() print("Starting reading at {}".format((time_current - self._time_start[0])/1e9)) elapsed_time = (time_current - time_start) / 1e9 read_no_samples = int(elapsed_time / self._drec.sampletime) extra_samples = int(0.5*read_no_samples) read_no_samples += extra_samples data = np.zeros((read_no_samples, len(self._drec.sources)+1)) print("Data: {}".format(data.shape)) start_timeval = (self._time_start[-1] - self._time_start[0])/1e9 print("Start timeval: {}".format(start_timeval)) print("Predicted elapsed time: {}, Actual elapsed time: {}".format(read_no_samples*self._drec.sampletime, elapsed_time)) times = np.arange(start_timeval, start_timeval+elapsed_time-self._drec.sampletime + extra_samples*self._drec.sampletime, step=self._drec.sampletime) print("Times: {}".format(times.shape)) data[:,0] = times tables = list(range(1, len(self._drec.sources)+1)) header = pidevice.qDRR(tables, 1, read_no_samples) while pidevice.bufstate is not True: time.sleep(0.01) if refresh: self.refresh() d = np.array(pidevice.bufdata).transpose() data[:,1:] = d print(d[0,1:3]) print(d[-1,1:3]) self.data = np.vstack((self.data, data)) self.read_in_progress = False def _plot_data(self, data): fig, ax = plt.subplots() ax.plot(data[:,0], data[:,1], label='x', marker='.') ax.plot(data[:,0], data[:,2], label='y', marker='.') ax.plot(data[:,0], data[:,3], label='z', marker='.') plt.legend() plt.show() def stop(self, plot=False): print("Saving") self._stop_flag.set() while self.read_in_progress is True: time.sleep(0.1) self.get_data(refresh=False) diffs = np.diff(self.data[:,0]) max_diff = np.max(diffs) print("Max gap: {}".format(max_diff)) np.savetxt("data.txt", self.data, delimiter=',') if plot: self._plot_data(self.data) def lines(task, pidevice): focus_top = 9 focus_bottom = 9 focus_range = 50 start_x = 116 start_y = 100 pitch = 3 line_length = 20 # Go to origin pidevice.MOV({1: start_x, 2: start_y, 3: focus_top}) # set velocity velocities = [0.1, 0.2, 0.5, 1, 2, 5, 10, 20, 50, 100, 200, 500, 1000] #velocities = [1] pidevice.VCO({2: True}) for i, vel in enumerate(velocities): # Calculate x coordinate for this line x = i * pitch z = focus_top + (focus_bottom - focus_top) / focus_range * x # Go to start position pidevice.VEL({2: 100}) pidevice.MOV({1: start_x + x, 2: start_y, 3: z}) pitools.waitontarget(pidevice, [1, 2, 3]) time.sleep(0.2) # Turn on laser task.write(True) time.sleep(0.006) # Start line pidevice.VEL({2: vel}) pidevice.MOV({2: start_y + line_length}) pitools.waitontarget(pidevice, [1, 2, 3]) # Turn off laser task.write(False) time.sleep(0.2) # Go to origin pidevice.VEL({2: 100}) pidevice.MOV({1: start_x, 2: start_y, 3: focus_top}) pitools.waitontarget(pidevice, [1, 2, 3]) def dots(task, pidevice): # Focusing procedure: # Get two z values where the beam is in focus at two points: the left # and right sides of the writing area. Put these values in focus_*, # and the distance between the two sample points in focus_range. focus_left = 8.5 focus_right = 8.5 focus_range = 10 # Positioning parameters start_x = 25 start_y = 0 pitch = 5 # Go to origin #pidevice.MOV({1: start_x, 2: start_y, 3: focus_left}) pidevice.MOV({1: start_x, 2: start_y}) # Set exposure times in ms #times = np.array([10, 20, 50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 50000, 100000]) times = np.array([10, 20, 50, 100, 200, 500, 1000]) for i, t in enumerate(times): # Go to dot position y = start_y + i * pitch z = focus_left + (focus_right - focus_left) / focus_range * y #pidevice.MOV({2: y, 3: z}) pidevice.MOV({2: y}) #pitools.waitontarget(pidevice, [1, 2, 3]) pitools.waitontarget(pidevice, [1, 2]) time.sleep(0.1) # Write dot print("{} of {}: {} ms".format(i+1, len(times), t)) task.write(True) time.sleep(t/1e3) task.write(False) time.sleep(0.5) # Go to origin #pidevice.MOV({1: start_x, 2: start_y, 3: focus_left}) #pitools.waitontarget(pidevice, [1, 2, 3]) pidevice.MOV({1: start_x, 2: start_y}) pitools.waitontarget(pidevice, [1, 2]) def test_rec(pidevice): pidevice.VCO({1: True, 2: True}) pidevice.VEL({1: 1000, 2: 1000}) pidevice.MOV({1: 0, 2: 0}) pitools.waitontarget(pidevice, [1, 2]) pidevice.VEL({1: 20, 2: 20}) rec = Recorder(pidevice) rec.start() pidevice.MOV({1: 100, 2: 100}) #pitools.waitontarget(pidevice, [1, 2, 2]) time.sleep(15) #rec.get_data() #pitools.waitontarget(pidevice, [1, 2, 3]) #rec.get_data() # time.sleep(5) # rec.get_data() rec.stop(plot=True) if __name__ == "__main__": task, pidevice = setup() try: #lines(task, pidevice) dots(task, pidevice) #test_rec(pidevice) finally: pitools.stopall(pidevice) task.close()