Source code for instruments.StepMotor_KST_ZST
# Step Motor Class
# - wraps around Motor
from Motor_KST_ZST import Motor_KST_ZST as Motor, hexString, int2hexStr
#import serial
import logging
import time
from struct import unpack
STEPS_PER_MM = 2184533.33 # 136533.33
LIMIT_SWITCH = 13
BACKLASH_STEPS = 43691
# DEBUG
Constructor_Counter = 0
Home_Counter = 0
[docs]class StepMotor_KST_ZST(Motor):
def __init__(self, ser):
'''
Constructor
ser (Serial): the Serial object that corresponds to the port
the motor is connected to
'''
###
global Constructor_Counter
Constructor_Counter += 1
###
self.ser = ser
self.moving = False
Motor.__init__(self, ser)
self.ext['ClassName'] = 'StepMotor'
self.home() # home motor
self._set_backlash(0) # set 0 backlash correction
self.mm_pos = 0 # position of motor, in millimieters
self.mm_zeros = 0 # the origin, in millimeters
[docs] def home(self):
'''
Puts the motor to backward limit position, so that the
position markers make sense
'''
###
global Home_Counter
Home_Counter += 1
###
self.moving = True
self.logger.debug('Homing...', extra=self.ext)
# save that change with < MGMSG_MOT_SET_EEPROMPARAMS >
self.ser.write(hexString('B9 04 04 00 D0 01'))
self.ser.write(hexString('01 00')) # chanel id
self.ser.write(hexString('FE 04')) # the specific message we want to save
# call < MGMSG_MOT_SET_TSTACTUATORTYPE > first
# to specify that we are using the ZFS 13mm actuator => 0x41
# FE, 04, 41, 00, 50, 01
self.ser.write(hexString('FE 04 41 00 50 01'))
# home motor on the correct limit switch
# < MGMSG_MOT_REQ_HOMEPARAMS >
self.ser.write(hexString('41 04 01 00 50 01'))
home_response = self.ser.read(20)
if home_response[0:2] != hexString('42 04'):
self.logger.error('problem reading data from controller while homing', extra=self.ext)
exit()
# < MGMSG_MOT_SET_HOMEPARAMS >
self.ser.write(hexString('40 04 0E 00 D0 01')) # header
self.ser.write(hexString('01 00')) # chan-ident
self.ser.write(int2hexStr(1, 2)) # Home Dir
self.ser.write(int2hexStr(1, 2)) # Limit Switch
self.ser.write(home_response[12:16]) # Home Velocity
self.ser.write(home_response[16:20]) # Offset Distance
# MGMSG_MOT_MOVE_HOME
self.ser.write(hexString('43 04 01 00 50 01'))
self.ser.reset_input_buffer()
response = self.ser.read(6)
if response != hexString('44 04 01 00 01 50'): # MGMSG_MOT_MOVE_HOMED
self.logger.error('problem homing', extra=self.ext)
exit()
self.logger.info('homed successfully.', extra=self.ext)
self.moving = False
[docs] def get_info(self):
'''
Get information back form the controller
Used for debugging purposes
'''
# MGMSG_HW_REQ_INFO
self.ser.write(hexString('05 00 00 00 50 01'))
response = self.ser.read(90)
print response
def _set_backlash(self, backlash_distance):
'''
Set the backlash correction distance for backwards motor
movement
backlash_distance (int): in encoder steps
'''
# change backlash value
self.ser.write(hexString('3A 04 06 00 D0 01')) # header
self.ser.write(hexString('01 00')) # chanel id
self.ser.write(int2hexStr(backlash_distance, 4)) # backlash dist
# request backlash data
self.ser.write(hexString('3B 04 01 00 50 01'))
# confirm backlash distance value
res = self.ser.read(12)
back_dist_r = unpack('<l', res[8:12])[0]
if back_dist_r != backlash_distance:
self.logger.error('Problem setting backlash distance [{}]'.format(backlash_distance), extra=self.ext)
[docs] def delta_transl(self, dist): #, m_callback = None, params = ()):
'''
Relative translation on the motor
dist (float): the millimeters of translation (negative -> backwards)
m_callback (function): (Optional) a function that will run while the motor
will be in motion. (e.g. show camera)
This callback's last parameter must be a callback itself,
named 'callback'
params (tuple): the callback's parameters
'''
self.moving = True
# check whether we are within limits
if self.mm_pos + dist > LIMIT_SWITCH or self.mm_pos + dist < 0:
self.logger.error('Out of bounds error (dist:{}, pos:{})'.format(dist, self.mm_pos), extra=self.ext)
self.moving = False
return False
self.mm_pos += dist
# convert millimeters to steps
steps = int(round(dist * STEPS_PER_MM))
if steps < 0:
Motor.delta_move(self, -(steps - BACKLASH_STEPS))
# manual backlash correction
Motor.delta_move(self, -BACKLASH_STEPS)
else:
Motor.delta_move(self, -steps)
self.moving = False
return True
[docs] def check_abs_transl(self,dist):
'''
Check wether a move to position 'dist' is in range
'''
if dist > LIMIT_SWITCH or dist < 0:
return False
else:
return True
[docs] def abs_transl(self, dist):
'''
Absolute translation on the motor
dist (float): the millmeters of rotation (negative -> backwards)
'''
self.moving = True
# check weather we are within limits
if dist > LIMIT_SWITCH or dist < 0:
self.logger.error('Out of bounds error (abs_pos:{})'.format(dist), extra=self.ext)
self.moving = False
return
# convert degrees to steps
steps = int(round(dist * STEPS_PER_MM))
# manual backlash correction
if dist - self.mm_pos < 0:
Motor.abs_move(self, -(steps - BACKLASH_STEPS))
Motor.delta_move(self, -BACKLASH_STEPS)
else:
Motor.abs_move(self, -steps)
self.mm_pos = dist
self.moving = False
[docs] def get_mm_pos(self):
'''
return the motors current position, in millimeters
'''
return self.mm_pos
[docs] def set_as_zero(self, zer_mm):
'''
change the origin (zero)
'''
n_zero = int(round(zer_mm / STEPS_PER_MM))
Motor.set_as_zero(self, n_zero)
self.mm_zeros = zer_mm
self.mm_pos -= zer_mm
def __str__(self):
'''
<For Debugging Purposes>
gives information relevant to the motor state
'''
return 'StepMotor({})\n'.format(self.ser.port) + ' position(millimeters): ' + str(self.mm_pos) + '\n zeros-position(millimeters): ' + str(self.mm_zeros)
'''
Copyright (C) 2017 Robert Polster
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
'''