1"""
2write_binary_grating.py
3Andrew Lorimer, January 2025
4Monash University
5
6Writes a transmission binary grating pattern using
7the confocal direct laser writing setup on Sb2S3 thin-film PCM.
8"""
9
10import configparser as cp
11import cv2
12import numpy as np
13import sys
14import matplotlib.pyplot as plt
15import write_path
16from pipython import datarectools, pitools
17import nidaqmx
18import pipython
19import time
20
21TRANSITION_SPEED = 100 # speed for moving between lines, um/s
22
23# Input parameters
24grating_pitch = 2.7 # Lambda, um
25beam_width = 0.7
26writing_speed = 10 # speed for writing crystallised lines, um/s
27dimensions = (50, 50) # horizontal * vertical, um
28origin = (0, 0) # horizontal * vertical, um
29
30def wait_target(pidevice, thresh=0.01, axes=[1, 2, 3]):
31 target = pidevice.qMOV(axes)
32 on_target = False
33 while on_target == False:
34 pos = pidevice.qPOS(axes)
35 on_target = True
36 distances = np.abs(np.array(list(pos.values())) - np.array(list(target.values())))
37 on_target = np.all(distances < thresh)
38
39
40def main(task, pidevice):
41
42 # One block is a solid area with constant refractive index in the
43 # diffraction grating
44 # One line is a single pass of the laser, with many lines making up a
45 # block (depending on the beam width)
46
47 n_blocks = int(dimensions[0] // grating_pitch)
48 n_lines = int(grating_pitch // beam_width)
49
50 pidevice.VCO({1: True})
51
52 updown = 0
53
54 for i in range(n_blocks):
55 if (i % 2 == 0):
56 # Even number block - crystallise
57
58 y_block = origin[0] + i * grating_pitch
59
60 for j in range(n_lines):
61 y_line = y_block + j*beam_width
62 x_start = origin[1] + int(not updown)*dimensions[1]
63 x_end = origin[1] + updown*dimensions[1]
64
65 # Go to line start position
66 pidevice.VEL({1: TRANSITION_SPEED})
67 pidevice.MOV({1: x_start, 2: y_line})
68 wait_target(pidevice)
69 time.sleep(0.3)
70
71 # Write line
72 pidevice.VEL({1: writing_speed})
73 pidevice.MOV({1: x_end, 2: y_line})
74 #time.sleep(0.05) # compensation for acceleration period
75 task.write(True)
76 wait_target(pidevice)
77 task.write(False)
78 time.sleep(0.3)
79
80 updown = int(not updown)
81 else:
82 # Odd number line - do nothing
83 pass
84
85if __name__ == "__main__":
86 task, pidevice = write_path.setup()
87 try:
88 main(task, pidevice)
89 finally:
90 print("Exiting")
91 task.write(False)
92 task.close()
93 pidevice.VCO({1: True, 2: True})
94 pidevice.VEL({1: TRANSITION_SPEED, 2: TRANSITION_SPEED})
95 pidevice.MOV({1: origin[1], 2: origin[0]})
96 pitools.waitontarget(pidevice, [1, 2])
97 pitools.stopall(pidevice)