diff --git a/Picomotor/picomotor_driver.py b/Picomotor/picomotor_driver.py new file mode 100644 index 0000000..11c7630 --- /dev/null +++ b/Picomotor/picomotor_driver.py @@ -0,0 +1,98 @@ +""" +Library to control the NewFocus 8732 picomotor driver. +""" +import serial +import time +import numpy as np + + +class picomotor: + axis_names = { "MOTz_x": "112", "MOTz_y": "122"} + steps_in_turn = { "MOTz_x": [1000,1000], "MOTz_y": [1000,1000]} # [CW, CCW] number of steps for 1 turn + + + def __init__(self, COM_port ) + """Open serial connection for NewFocus 8732 controller""" + """COM_port: ie 'COM3' (check device manager) """ + + self.serial = serial.Serial(timeout = 0.5) #19200 baud didn't work. 8 bits, no parity, 1 stop bit. + self.serial.baudrate = 9600 + self.serial.port = COM_port #'COM3' + #print("Serial connection open: ", self.serial.open()) + response = self.sendreceive(self, "*IDN?") + print(response) + + + # Initialize positions + self.positions = dict.fromkeys(axis_names, 0) #{'MOTz_x': 0, 'MOTz_y': 0, ...} #units steps + + # Turn on the slots? + #self.sendreceive(':INST 1') #? not sure if I need this? + #INST:NSEL 1 + + + def sendreceive(self, cmd): + """Send command to the picomotor driver, and readlines""" + """ Send multiple commands with ;""" + """ 8732 ends with carriage return \r. Does not echo command, but always responds. """ + line = cmd + '\r' + retval = self.serial.write(bytes(line, encoding='ascii')) + time.sleep(0.01) #not sure if need + response = self.serial.read_until(b'\r') + #self.serial.flush() #what does this do? + return response + + + def move_abs(self, axis, position, velocity) + """ Move to absolute position, and if CCW (negative steps), then use correct cw/ccw disparities""" + cw ccw = steps_in_turn[axis] #number steps in turn + current_position = self.positions[axis] #get current position + steps = position - current_position + + if steps < 0: + steps = steps*(ccw/cw) + + self.move(axis, steps, velocity) + self.positions[axis] = position + + + def move(self, axis, steps, velocity) + """ Move relative number of setups. Position CW, Negative CCW""" + """ Returns before finished moving. """ + + cmd1 = "INST:NSEL " + axis_names[axis] + + if steps < 0: + cmd2 = ":SOUR:DIR CWW" + else: + cmd2 = ":SOUR:DIR CW" + + cmd3 = "SOUR:PULS:FREQ "+ str(round(velocity)) # integer divider of 1500 + + cmd4 = ":SOUR:PULS:COUN " + str(round(abs(steps))) + + cmd = cmd1 + "; " + cmd2 + "; " + cmd3 + "; " + cmd4 + self.sendreceive(cmd) + + # Update position + self.positions[axis] = self.positions[axis] + steps + + + def wait_for_move(self) + """ Wait for picomotor to finish moving """ + timeout = 120 # timeout seconds + moving = 1 + while moving: #OPC returns 1 if all channels are finished + time.sleep(0.2) + text = self.sendreceive("*OPC?") + moving = int(text)# get 1 or 0 from text + + + def zero_positions(self) + """ Zero all positions """ + self.positions = dict.fromkeys(axis_names, 0) + + def zero_position(self, axis) + """ Zero single axis """ + self.positions[axis] = 0 + \ No newline at end of file