def __init__(self, inst, props, *args, **kwargs): super(ZaberTMMMotorController, self).__init__(inst, props, *args, **kwargs) # initialize hardware communication self.con = BinarySerial(self.port, timeout=5) print('Zaber TMM Controller Initialization ...'), print('SUCCESS on port %s' % self.port) # do some initialization self._motors = {}
def __init__(self): com_ports = list(serial.tools.list_ports.comports()) xy_com_port = "NULL" z_com_port = "NULL" #detect com ports for port in com_ports: print(port) if XYDEVPORT in port[2]: xy_com_port = port[0] if ZDEVPORT in port[1]: z_com_port = port[0] if "NULL" == xy_com_port: self.x_axis_device = "NULL" self.y_axis_device = "NULL" print("Could not find xy-axis device") #connects to devices if found else: port = BinarySerial(xy_com_port) self.x_axis_device = BinaryDevice(port, 1) self.y_axis_device = BinaryDevice(port, 2) if "NULL" == z_com_port: self.z_axis_device = "NULL" print("Could not find z-axis device") else: self.z_axis_device = serial.Serial(z_com_port, 115200)
def setup_stages(): global x_linear, y_linear, z_rotary serial_conn = BinarySerial(STAGES_PORT, timeout=None) x_linear = BinaryDevice(serial_conn, 2) y_linear = BinaryDevice(serial_conn, 3) z_rotary = BinaryDevice(serial_conn, 1) x_linear.set_home_speed(linspeed2lindata(DEFAULT_HOME_SPEED)) y_linear.set_home_speed(linspeed2lindata(DEFAULT_HOME_SPEED)) # need to check that mm2rotdata does the right conversion #rotary.set_target_speed(mm2rotdata(DEFAULT_ROT_SPEED)) x_linear.set_target_speed(linspeed2lindata(DEFAULT_HOME_SPEED)) y_linear.set_target_speed(linspeed2lindata(DEFAULT_HOME_SPEED)) x_linear.set_acceleration(LIN_STAGE_ACCELERATION) y_linear.set_acceleration(LIN_STAGE_ACCELERATION) z_rotary.set_acceleration(ROT_STAGE_ACCELERATION) z_rotary.set_min_position(deg2rotdata(ROTARY_MIN_ANGLE)) z_rotary.set_max_position(deg2rotdata(ROTARY_MAX_ANGLE)) home_all()
def setup_stages(): global serial_conn, x_linear, y_linear, z_rotary serial_conn = BinarySerial(STAGES_PORT, timeout=None) if CONNECT_ROTARY: z_rotary = BinaryDevice(serial_conn, 1) z_rotary.set_home_speed(degspeed2rotdata(DEFAULT_ROT_SPEED)) z_rotary.set_target_speed(degspeed2rotdata(DEFAULT_ROT_SPEED)) z_rotary.set_acceleration(ROT_STAGE_ACCELERATION) z_rotary.set_min_position(deg2rotdata(ROTARY_MIN_ANGLE)) z_rotary.set_max_position(deg2rotdata(ROTARY_MAX_ANGLE)) x_linear = BinaryDevice(serial_conn, 2) y_linear = BinaryDevice(serial_conn, 3) x_linear.set_home_speed(linspeed2lindata(DEFAULT_HOME_SPEED)) y_linear.set_home_speed(linspeed2lindata(DEFAULT_HOME_SPEED)) x_linear.set_target_speed(linspeed2lindata(DEFAULT_HOME_SPEED)) y_linear.set_target_speed(linspeed2lindata(DEFAULT_HOME_SPEED)) x_linear.set_acceleration(LIN_STAGE_ACCELERATION) y_linear.set_acceleration(LIN_STAGE_ACCELERATION) x_linear.disable_manual_move_tracking() y_linear.disable_manual_move_tracking() home_all()
def movedist(distance, direction_sign, device): # removed speed for now (third variable) # where device = device number. from src.check_command_succeeded import check_command_succeeded from zaber.serial import BinarySerial, BinaryDevice, BinaryCommand # , BinaryReply #Added import time # Added # ------------------------------------------------------------------------- # TODO: Create device # ------------------------------------------------------------------------- # command = BinaryCommand(device, 21, steps) # Added. 21 = move rel port = BinarySerial(device) # Added # ------------------------------------------------------------------------- # TODO: Convert distances to steps. Put in the true conversion. # ------------------------------------------------------------------------- converter = 1 # converts distance to steps. (steps/distance) steps = int(distance) * converter * int( direction_sign) #number of microsteps to move # ------------------------------------------------------------------------- # TODO: Insert motor move command # ------------------------------------------------------------------------- command = BinaryCommand(0, 21, steps) port.write(command) # Added # device.move_rel(speed,blocking=True) # Added Commented Out #r eply = device.move_rel(steps) # move rel 2000 microsteps #A dded Commented out everything below # if not check_command_succeeded(reply): #print("Device move failed.") #exit(1) # else: # print("Motor moved", distance, "microsteps") return
def setup_stages(): global rotary, xAxis, yAxis serial_conn = BinarySerial(STAGES_PORT, timeout=None) rotary = BinaryDevice(serial_conn, 1) xAxis = BinaryDevice(serial_conn, 2) yAxis = BinaryDevice(serial_conn, 3) xAxis.set_home_speed(mm2lindata(DEFAULT_HOMING_SPEED)) xAxis.set_home_speed(mm2lindata(DEFAULT_HOMING_SPEED)) rotary.set_acceleration(20) xAxis.set_acceleration(2000) yAxis.set_acceleration(2000) # rotary.set_max_position home_all()
''' author: ashish license: GPL v3.0 brief: Zaber's binary stepper motor control. The code demonstrates a circular motion of the combination of two devices in a plane. Ref: http://www.zaber.com/wiki/Manuals/Binary_Protocol_Manual Pre: Do install Zaber's serial package from http://www.zaber.com/wiki/Software ''' from zaber.serial import BinarySerial, BinaryDevice, BinaryCommand import sys,os,thread,time,xlsxwriter,xlrd,re,math,serial print "Port Opening..." port = BinarySerial("/dev/ttyUSB0") port.timeout = 30 resolution_mm = 0.124023438*1e-3 spd_mm_s = 10 spd_steps = int((spd_mm_s * 1.6384)/resolution_mm) print spd_steps # Device number 0, command number 1. radius = 100000 steps = 10 theta = (2*3.14159)/steps device = BinaryDevice(port, 2) device1 = BinaryDevice(port, 3)
class ZaberTMMMotorController(MotorController): ctrl_properties = { 'port': { Type: str, Description: 'The port of the rs232 device', DefaultValue: '/dev/ttyZaber' } } MaxDevice = 2 def __init__(self, inst, props, *args, **kwargs): super(ZaberTMMMotorController, self).__init__(inst, props, *args, **kwargs) # initialize hardware communication self.con = BinarySerial(self.port, timeout=5) print('Zaber TMM Controller Initialization ...'), print('SUCCESS on port %s' % self.port) # do some initialization self._motors = {} def AddDevice(self, axis): self._motors[axis] = True # change setting of devices, because they are non-volatile # disable auto-reply 1*2^0 = 1 # enable backlash correction 1*2^1 = 2 command_number = 40 # set device mode command = BinaryCommand(axis, command_number, 3) self.con.write(command) def DeleteDevice(self, axis): del self._motors[axis] StateMap = { 1: State.On, 2: State.Moving, 3: State.Fault, } def StateOne(self, axis): limit_switches = MotorController.NoLimitSwitch command_number = 54 # return status command = BinaryCommand(axis, command_number) self.con.write(command) reply = self.con.read() while (reply.command_number != command_number) & (reply.device_number != axis): self.con.write(command) reply = self.con.read() time.sleep(0.2) if reply.data == 0: # idle return self.StateMap[1], 'Zaber is idle', limit_switches elif (reply.data >= 1) & (reply.data <= 23): return self.StateMap[2], 'Zaber is moving', limit_switches else: return self.StateMap[3], 'Zaber is faulty', limit_switches def ReadOne(self, axis): command_number = 60 # return current position command = BinaryCommand(axis, command_number) for i in range(50): self.con.write(command) reply = self.con.read() if (reply.command_number != command_number) & (reply.device_number != axis): time.sleep(0.05) else: break return int(reply.data) def StartOne(self, axis, position): command_number = 20 # move absolute command = BinaryCommand(axis, command_number, int(position)) self.con.write(command) def StopOne(self, axis): command_number = 23 # move absolute command = BinaryCommand(axis, command_number) self.con.write(command) def AbortOne(self, axis): command_number = 23 # move absolute command = BinaryCommand(axis, command_number) self.con.write(command) def SendToCtrl(self, cmd): """ Send custom native commands. The cmd is a space separated string containing the command information. Parsing this string one gets the command name and the following are the arguments for the given command i.e.command_name, [arg1, arg2...] :param cmd: string :return: string (MANDATORY to avoid OMNI ORB exception) """ # Get the process to send mode = cmd.split(' ')[0].lower() args = cmd.strip().split(' ')[1:] if mode == 'homing': try: if len(args) == 1: axis = args[0] axis = int(axis) else: raise ValueError('Invalid number of arguments') except Exception as e: self._log.error(e) self._log.info('Starting homing for Zaber mirror') try: command_number = 1 # homing command = BinaryCommand(axis, command_number) self.con.write(command) except Exception as e: self._log.error(e) print(e) return 'Error' self._log.info('Homing was finished') return "[DONE]" else: self._log.warning('Invalid command') return 'ERROR: Invalid command requested.'
def __init__(self, time_offset, COM_port, dev1_axis, dev2_axis, coordinates_fname): self.time_offset = time_offset self.COM_port = COM_port self.coordinates_fname = coordinates_fname with h5py.File('drivers/' + coordinates_fname, 'r') as f: self.coordinates_random = f['all_points'][()] np.random.shuffle(self.coordinates_random) # shape and type of the array of returned data from ReadValue self.dtype = ('f4', 'int32', 'int32') self.shape = (3, ) try: self.port = BinarySerial(COM_port) msg = self.command(0, 50, 0, 2) msg = [d.data for d in msg] if not all(elem == msg[0] for elem in msg): raise ValueError( 'ZaberTMM warning in verification : Device IDs not equal') except Exception as err: logging.warning("ZaberTMM error in initial connection : " + str(err)) self.verification_string = "False" self.__exit__() return None try: self.port.write(BinaryCommand(0, 55, 123)) msg1 = self.port.read() msg2 = self.port.read() if msg1.data != 123: logging.warning( "ZaberTMM warning in verification : motor {0} connection error" .format(msg1.device_number)) if msg2.data != 123: logging.warning( "ZaberTMM warning in verification : motor {0} connection error" .format(msg2.device_number)) self.verification_string = "True" except Exception as err: logging.warning('ZaberTMM warning in verification : ' + str(err)) self.verification_string = "False" self.warnings = [] self.position = ZaberCoordinates(dev1_axis, dev2_axis) if dev1_axis == 'x': self.devx = 1 self.devy = 2 elif dev1_axis == 'y': self.devx = 2 self.devy = 1 if not self.ReadDeviceModeX()[7]: warning = 'Home Status bit not set in Dev{0}, home device'.format( self.devx) logging.warning('ZaberTMM warning: ' + warning) self.CreateWarning(warning) if not self.ReadDeviceModeY()[7]: warning = 'Home Status bit not set in Dev{0}, home device'.format( self.devx) logging.warning('ZaberTMM warning: ' + warning) self.CreateWarning(warning) self.sweep_thread = None self.running_sweep = False self.sweep_start_position = 'current' self.sweep_square_params = {} self.step_rectangle = None self.GetPosition() # HDF attributes generated when constructor is run self.new_attributes = [ ('dev1_axis', dev1_axis), ('dev2_axis', dev2_axis), ('x_speed', str(self.ReadTargetSpeedX())), ('y_speed', str(self.ReadTargetSpeedY())), ('x_acceleration', str(self.ReadAccelerationX())), ('y_acceleration', str(self.ReadAccelerationY())) ]
class ZaberTMM: def __init__(self, time_offset, COM_port, dev1_axis, dev2_axis, coordinates_fname): self.time_offset = time_offset self.COM_port = COM_port self.coordinates_fname = coordinates_fname with h5py.File('drivers/' + coordinates_fname, 'r') as f: self.coordinates_random = f['all_points'][()] np.random.shuffle(self.coordinates_random) # shape and type of the array of returned data from ReadValue self.dtype = ('f4', 'int32', 'int32') self.shape = (3, ) try: self.port = BinarySerial(COM_port) msg = self.command(0, 50, 0, 2) msg = [d.data for d in msg] if not all(elem == msg[0] for elem in msg): raise ValueError( 'ZaberTMM warning in verification : Device IDs not equal') except Exception as err: logging.warning("ZaberTMM error in initial connection : " + str(err)) self.verification_string = "False" self.__exit__() return None try: self.port.write(BinaryCommand(0, 55, 123)) msg1 = self.port.read() msg2 = self.port.read() if msg1.data != 123: logging.warning( "ZaberTMM warning in verification : motor {0} connection error" .format(msg1.device_number)) if msg2.data != 123: logging.warning( "ZaberTMM warning in verification : motor {0} connection error" .format(msg2.device_number)) self.verification_string = "True" except Exception as err: logging.warning('ZaberTMM warning in verification : ' + str(err)) self.verification_string = "False" self.warnings = [] self.position = ZaberCoordinates(dev1_axis, dev2_axis) if dev1_axis == 'x': self.devx = 1 self.devy = 2 elif dev1_axis == 'y': self.devx = 2 self.devy = 1 if not self.ReadDeviceModeX()[7]: warning = 'Home Status bit not set in Dev{0}, home device'.format( self.devx) logging.warning('ZaberTMM warning: ' + warning) self.CreateWarning(warning) if not self.ReadDeviceModeY()[7]: warning = 'Home Status bit not set in Dev{0}, home device'.format( self.devx) logging.warning('ZaberTMM warning: ' + warning) self.CreateWarning(warning) self.sweep_thread = None self.running_sweep = False self.sweep_start_position = 'current' self.sweep_square_params = {} self.step_rectangle = None self.GetPosition() # HDF attributes generated when constructor is run self.new_attributes = [ ('dev1_axis', dev1_axis), ('dev2_axis', dev2_axis), ('x_speed', str(self.ReadTargetSpeedX())), ('y_speed', str(self.ReadTargetSpeedY())), ('x_acceleration', str(self.ReadAccelerationX())), ('y_acceleration', str(self.ReadAccelerationY())) ] def __enter__(self): return self def __exit__(self, *exc): try: if self.running_sweep: self.sweep_thread.stop() try: self.port.close() except: return except: return ####################################################### # CeNTREX DAQ Commands ####################################################### def CreateWarning(self, warning): warning_dict = {"message": warning} self.warnings.append([time.time(), warning_dict]) def GetWarnings(self): warnings = self.warnings.copy() self.warnings = [] return warnings def ReadValue(self): val = [time.time() - self.time_offset, *self.position.coordinates] return val def SweepStatus(self): if self.running_sweep: return 'Sweeping' elif not self.running_sweep: return 'Inactive' else: return 'invalid' def SweepStartPosition(self, start_position): if start_position in ['current', 'random', 'origin']: self.sweep_start_position = start_position else: warning = 'SweepStartPosition: start_position can be set to current, origin or random' self.CreateWarning(warning) logging.warning('ZaberTMM warning in ' + warning) def SweepStartPositionStatus(self): return self.sweep_start_position @SweepCheckWrapper def MoveAbsoluteXGUI(self, position): self.MoveAbsoluteX(position) @SweepCheckWrapper def MoveAbsoluteYGUI(self, position): self.MoveAbsoluteY(position) @SweepCheckWrapper def HomeAllGUI(self): self.HomeAll() @SweepCheckWrapper def RandomPosition(self): x, y = self.coordinates_random[0] self.MoveAbsoluteX(x) self.MoveAbsoluteY(y) self.coordinates_random = np.roll(self.coordinates_random, shift=-1, axis=0) def SetPointAGUI(self, point_a): self.sweep_square_params['point_a'] = point_a def GetPointAGUI(self): return self.sweep_square_params.get('point_a', None) def SetPointBGUI(self, point_b): self.sweep_square_params['point_b'] = point_b def GetPointBGUI(self): return self.sweep_square_params.get('point_b', None) def SetStepGUI(self, step): self.sweep_square_params['step'] = step def GetStepGUI(self): return self.sweep_square_params.get('step', None) def SetWaitGUI(self, wait_time): self.sweep_square_params['wait_time'] = float(wait_time) def GetWaitGUI(self): return self.sweep_square_params.get('wait_time', None) ####################################################### # Write/Query Commands ####################################################### def command(self, device, command, data, returns): while True: if self.port.can_read(): self.port.read() else: break self.port.write(BinaryCommand(device, command, data)) if returns: msg = [] for _ in range(returns): msg.append(self.port.read()) return msg else: return None ####################################################### # Commands for all devices ####################################################### def HomeAll(self): msgs = self.command(0, 1, 0, 2) if isinstance(msgs, type(None)): logging.warning('ZaberTMM warning in HomeAll : no return msgs') for msg in msgs: if msg.data != -62000: logging.warning( 'ZaberTMM warning in HomeAll : motor {0} not @home position' .format(msg.device_number)) self.position.dev_coordinates = [-62000, -62000] def MoveAbsoluteAll(self, position): msgs = self.command(0, 20, position, 2) if isinstance(msgs, type(None)): logging.warning( 'ZaberTMM warning in MoveAbsoluteAll : no return msgs') for msg in msgs: if msg.data == position: self.position.dev_coordinates = position elif msg.data != position: logging.warning( 'ZaberTMM warning in MoveAbsoluteAll : motor {0} not @{1} position' .format(msg.device_number, position)) def GetPosition(self): while True: msgs = self.command(0, 60, 0, 2) if isinstance(msgs, type(None)): logging.warning( 'ZaberTMM warning in GetPositions : no return msgs') pos = [None, None] for msg in msgs: pos[msg.device_number - 1] = msg.data if not type(None) in [type(i) for i in pos]: break self.position.dev_coordinates = pos return pos def DisablePotentiometer(self): current = self.command(0, 53, 40, 2)[0].data msgs = self.command(0, 40, current + 8) ####################################################### # Commands for individual devices ####################################################### def MoveAbsoluteX(self, position): msgs = self.command(self.devx, 20, position, 1) if isinstance(msgs, type(None)): logging.warning( 'ZaberTMM warning in MoveAbsoluteX : no return msgs') for msg in msgs: if msg.device_number == self.devx: if isinstance(msg.data, int): self.position.x = msg.data elif msg.device_number == self.devy: if isinstance(msg.data, int): self.position.y = msg.data if self.position.x != position: logging.warning( 'ZaberTMM warning in MoveAbsoluteX : motor {0} not @{1} position' .format(self.devx, position)) def MoveAbsoluteY(self, position): msgs = self.command(self.devy, 20, position, 1) if isinstance(msgs, type(None)): logging.warning( 'ZaberTMM warning in MoveAbsoluteY : no return msgs') for msg in msgs: if msg.device_number == self.devx: if isinstance(msg.data, int): self.position.x = msg.data elif msg.device_number == self.devy: if isinstance(msg.data, int): self.position.y = msg.data if self.position.y != position: logging.warning( 'ZaberTMM warning in MoveAbsoluteY : motor {0} not @{1} position' .format(self.devy, position)) def HomeX(self): msgs = self.command(self.devx, 1, 0, 1) if isinstance(msgs, type(None)): logging.warning('ZaberTMM warning in HomeX : no return msgs') for msg in msgs: if msg.data == -62000: self.position.x = -62000 elif msg.data != -62000: logging.warning( 'ZaberTMM warning in HomeX : motor {0} not @home position'. format(msg.device_number)) def HomeY(self): msgs = self.command(self.devy, 1, 0, 1) if isinstance(msgs, type(None)): logging.warning('ZaberTMM warning in HomeY : no return msgs') for msg in msgs: if msg.data == -62000: self.position.y = -62000 elif msg.data != -62000: logging.warning( 'ZaberTMM warning in HomeY : motor {0} not @home position'. format(msg.device_number)) def MoveAbsoluteXNoWait(self, position): self.command(self.devx, 20, position, 0) def MoveAbsoluteYNoWait(self, position): self.command(self.devy, 20, position, 0) def GetPositionX(self): msgs = self.command(self.devx, 60, 0, 1) if isinstance(msgs, type(None)): logging.warning( 'ZaberTMM warning in GetPositionX : no return msgs') return np.nan self.position.x = msgs[0].data return msgs[0].data def GetPositionXMemory(self): return self.position.x def GetPositionY(self): msgs = self.command(self.devy, 60, 0, 1) if isinstance(msgs, type(None)): logging.warning( 'ZaberTMM warning in GetPositionY : no return msgs') return np.nan self.position.y = msgs[0].data return msgs[0].data def GetPositionYMemory(self): return self.position.y def ReadDeviceModeX(self): msg = self.command(self.devx, 53, 40, 1) bits = [int(d) for d in bin(msg[0].data)[2:]][::-1] return bits def ReadDeviceModeY(self): msg = self.command(self.devx, 53, 40, 1) bits = [int(d) for d in bin(msg[0].data)[2:]][::-1] return bits def DisablePotentiometerX(self): current = self.command(self.devx, 53, 40, 1)[0].data msgs = self.command(self.devx, 40, current + 8) def DisablePotentiometerY(self): current = self.command(self.devy, 53, 40, 1)[0].data msgs = self.command(self.devy, 40, current + 8) def ReadTargetSpeedX(self): return self.command(self.devx, 53, 42, 1)[0].data def ReadTargetSpeedY(self): return self.command(self.devy, 53, 42, 1)[0].data def ReadAccelerationX(self): return self.command(self.devx, 53, 43, 1)[0].data def ReadAccelerationY(self): return self.command(self.devy, 53, 43, 1)[0].data ####################################################### # Sweep Mirror ####################################################### def Sweep(self, sweepname): with h5py.File('drivers/' + self.coordinates_fname, 'r') as f: coordinates = f[sweepname][()] if self.running_sweep: warning = 'Sweep: Currently sweeping mirror' self.CreateWarning(warning) logging.warning( 'ZaberTMM warning in Sweep: Currently sweeping mirror') else: self.sweep_thread = MirrorSweep(self, coordinates, self.sweep_start_position) self.sweep_thread.start() def SweepRectangle(self, sweep_params=None): if isinstance(sweep_params, type(None)): sweep_params = self.sweep_square_params if self.running_sweep: warning = "SweepRectangle: Currently sweeping mirror" self.CreateWarning(warning) logging.warning( 'ZaberTMM warning in SweepRectangle: Currently sweeping mirror' ) else: self.sweep_thread = MirrorSweepRectangle(self, **sweep_params) self.sweep_thread.start() def StopSweep(self): if self.running_sweep: self.sweep_thread.stop() self.sweep_thread = None self.running_sweep = False else: warning = 'StopSweep: No sweep running' self.CreateWarning(warning) logging.warning("ZaberTMM warning in StopSweep: No sweep running") def setupStepRectangle(self, sweep_params=None): if isinstance(sweep_params, type(None)): sweep_params = self.sweep_square_params self.step_rectangle = StepRectangle(self, **sweep_params) def nextStep(self): if not self.step_rectangle is None: self.step_rectangle.next() else: logging.warning( "ZaberTMM warning in nextStep: No rectangle defined") def randomStep(self): if not self.step_rectangle is None: self.step_rectangle.randomNext() else: logging.warning( "ZaberTMM warning in nextStep: No rectangle defined")
def connect(self): self.comport = BinarySerial(self.port) self.x_axis = BinaryDevice(self.comport,1) self.y_axis = BinaryDevice(self.comport,2) self.rot_axis = BinaryDevice(self.comport,3)
## Input Data horizontalDist = 1 #horizontal distance between nodes verticalDist = 1 #verticle distance between nodes nrow = 5 #Number of rows ncol = 5 #Number of columns (maximum) in a row matrixOffset = 0 #If rows are offset type 0, if rows are inline type 1. # This program assumes it's halfway between each column ## Import functions from src.moveRow import moveRow from src.moveCol import moveCol from zaber.serial import BinarySerial, BinaryDevice from src.home import home ##hardware and OS setup with BinarySerial("/dev/ttyUSB0") as port: # Linux # with BinarySerial("COM3") as port: # Windows # Get a handle for device #1 on the serial chain. This assumes you have a # device already in Binary 9,600 baud mode at address 1 on your port. device1 = BinaryDevice(port, 1) # motor on x axis device2 = BinaryDevice(port, 2) # motor on y axis device3 = BinaryDevice(port, 3) # motor on z axis ## Home all devices # Home the device and check the result. home(device1) home(device2) home(device3)
def test_constructor_fails_when_not_passed_a_string(): with pytest.raises(TypeError): BinarySerial(1)
# Here's an area where you can do code testing with out it impacting the rest of the functions! Enjoy! # go here for help: https://www.rose-hulman.edu/class/csse/csse120/201920/ # preparations have videos # nrow = 5 # ncol = 5 from zaber.serial import BinarySerial, BinaryDevice, BinaryCommand # , BinaryReply import time # Assume that our serial port can be found at COM1 port = BinarySerial( "COM13" ) # be mindful of which COM port to use; check device manager; may need to restart port # with BinarySerial("COM13") as port: # Device number 0, command number 1. 1 is Home. 0 is Reset, move absolute is 20, relative is 21, 23 is stop #max relative move is 20,000, 42 sets speed, can be changed during a move; calculate spd w/ https://www.zaber.com/documents/ZaberSpeedSetting.xls command = BinaryCommand(0, 1) #command = BinaryCommand(0, 20, 0) #Goes at least to 50,000. Assume moving 10,000 = moving 0.01in #command = BinaryCommand(0, 21, 20000) #Can use negative distances with relative #devicenum = 0 #distance = 20000 #command = BinaryCommand(devicenum, 21, distance) #command = BinaryCommand(0, 21, 20000) # note: Binary motor commands are blocking. Syntax: BinaryCommand(device#, command#, dataValue) # List of command #s can be found at: https://www.zaber.com/wiki/Manuals/Binary_Protocol_Manual#Command_Reference port.write(command)