#%TITLE% piezo_serial.MAC
#%NAME%
# Macros to control a piezo cristal connected via serial line. Version 2.0
#%DESCRIPTION%
# This macro file allows to connect a piezo to a pseudo motor in SPEC.
# Derived from dac.mac
#%DL%
#%DT% History:
#%DT% 2.0 31.3.2000 Multiple channels per controller handled properly.
#%XDL%
#
#%EXAMPLE%
#%DL%
#%DT% mv pzo1 5.3 %DD% Value of 5.3 (unit um) set in piezo pzo1.
#%DT% ascan pzo2 0 10 10 1 %DD%
# (scan pzo2 from 0 to 10 in 10 steps and count for 1 second)
#%DT% a2scan pzo1 0 20 opti 0 5 10 1 %DD%
# (scan the optical table stepper motor from
# 0 to 5 degrees and scan at the same time the pzo1 from 0 to 20 micr.)
#%XDL%
#%END%
#%UU% [No of pzos] [pzo1 motor name] [pzo1 device name] ...
#%MDESC% Adds the given piezos to the already defined pzos
#
global PZOSER_ON PZOSER_LIST PZOSER_A_OLD PZOSER_DIRTY
list_test PZOSER_LIST
#%IU% pzo-mnemonic serial_id channel_nr servo_val
#%MDESC%
# Add definitions for a piezo pseudomotor
def pzoseradd 'pzoser_add("$1", $2, "$3", $4)'
#%IU% (pzo-mnemonic, serial_id, channel_nr, servo_val)
#%MDESC%
# Add definitions for a piezo pseudomotor
def pzoser_add(mne, dev, nr, serv) '{
if (motor_num(mne) == -1) {
printf("Motor \"%s\" does not exist, exit\n", mne)
exit
}
if ((nr != "A") && (nr != "B") && (nr != "C") && (nr != "D")) {
printf("Channel must be A, B, C or D exit\n")
exit
}
pzoseroff
list_add(PZOSER_LIST, mne)
list_setpar(PZOSER_LIST, mne, "dev", dev)
list_setpar(PZOSER_LIST, mne, "nr", nr)
if (serv == 0)
list_setpar(PZOSER_LIST, mne, "serv", 0)
else
list_setpar(PZOSER_LIST, mne, "serv", 1)
pzoseron
setup_tail("pzoser", sprintf("pzoser_%s %s", mne, mne))
}'
#%IU% (pzo-mnemonic)
#%MDESC%
# Delete definitions for one PZO mnemonic
#
def pzoserunsetup '{
pzoserdel("$2")
}'
#%IU% (pzo-mnemonic)
#%MDESC%
# Delete definitions for one PZO mnemonic
#
def pzoserdel(mne) '{
list_remove(PZOSER_LIST, mne)
cdef("", "", mne, "delete")
}'
#%UU%
#%MDESC%
# Reset internal lists.
def pzoserreset '
pzoseroff
list_init PZOSER_LIST
'
#%UU%
#%MDESC%
# Shows current PZO pseudomotors definition.
#
def pzosershow '{
local pzono mne
if (pzono = list_n(PZOSER_LIST)) {
printf("\nPIEZO pseudomotors are \"%s\"\n\n",PZOSER_ON?"ACTIVE":"NOT ACTIVE")
printf("\t Motor Device Channel Servo Config\n")
printf("\t------------------------------------------------------\n")
for (i=1; i<=pzono; i++) {
mne = list_item(PZOSER_LIST, i)
printf("\t%8s %15s %7s %5d", mne, \
list_getpar(PZOSER_LIST, mne, "dev"),\
list_getpar(PZOSER_LIST, mne, "nr"), \
list_getpar(PZOSER_LIST, mne, "serv"))
if (motor_num(mne) < 0)
printf(" %11s\n","NOT DEFINED")
else
printf(" %11s\n","OK")
}
printf("\n")
} else
printf("Nothing defined for PIEZO\n")
}'
#%UU%
#%MDESC%
# Deactivates definitions for PZO pseudomotors.
def pzoseroff '
{
local pzono
pzono = list_n(PZOSER_LIST)
for (i = 1; i <= pzono; i++) {
cdef("", "", list_item(PZOSER_LIST, i), "delete")
}
PZOSER_ON=0
}'
#%UU%
#%MDESC%
# Activates definitions for PZO pseudomotors.
#
def pzoseron '
{
local pzono num mne dev nr serv
pzono = list_n(PZOSER_LIST)
for (i=1; i <= pzono; i++) {
num = motor_num(mne = list_item(PZOSER_LIST, i))
if (num != -1 ) {
dev = list_getpar(PZOSER_LIST, mne, "dev")
nr = list_getpar(PZOSER_LIST, mne, "nr")
serv = list_getpar(PZOSER_LIST, mne, "serv")
# set controller in ONLINE mode
ser_put(dev, "ONL 1\n")
sleep(0.1)
# set step size parameters
ser_put(dev, sprintf("SPA %s7 1\n", nr))
ser_put(dev, sprintf("SPA %s8 0\n", nr))
ser_put(dev, sprintf("SPA %s9 100\n", nr))
ser_put(dev, sprintf("SPA %s10 0\n", nr))
# set servo mode
ser_put(dev, sprintf("SVO %s%d\n", nr, serv))
sleep(0.1)
# moving by position
cdef("user_checkall", sprintf("_pzoser_move %s\n", mne), mne, 0x01)
cdef("user_getpangles", sprintf("_pzoser_getpos %s\n", mne), mne, 0x01)
# force reading first time
PZOSER_DIRTY[num] = 1
}
}
PZOSER_ON=1
setup_tail("pzoser", sprintf("pzoser_%s %s", mne, mne))
# position control
printf("PIEZO pseudomotors are now ACTIVE\n")
}'
#%IU%
#
def pzoser_force_read '{
local mne val
mne = "$1"
val = $2
list_setpar(PZOSER_LIST, mne, "read", val)
}'
#%IU%
#
def _pzoser_move '{
local mne num dev nr serv
mne = "$1"
num = motor_num(mne)
if ( A[num] != PZOSER_A_OLD[num] ) {
dev = list_getpar(PZOSER_LIST, mne, "dev")
nr = list_getpar(PZOSER_LIST, mne, "nr")
serv = list_getpar(PZOSER_LIST, mne, "serv")
ser_par(dev, "flush", 2)
if (serv)
ser_put(dev, sprintf("MOV %s%g\n", nr, A[num]))
else
ser_put(dev, sprintf("SVA %s%g\n", nr, A[num]))
PZOSER_DIRTY[num] = 1
}
}'
#%IU%
#
def _pzoser_getpos '{
local mne num dev nr serv aux
mne = "$1"
num = motor_num(mne)
force_read = list_getpar(PZOSER_LIST, mne, "read")
if (( PZOSER_DIRTY[num] == 1 ) || (force_read > 0)) {
dev = list_getpar(PZOSER_LIST, mne, "dev")
nr = list_getpar(PZOSER_LIST, mne, "nr")
serv = list_getpar(PZOSER_LIST, mne, "serv")
ser_par(dev, "flush", 2)
niter = 0
# try several times to solve timeouts
while (niter < 5) {
if (serv)
ser_put(dev, sprintf("POS? %s\n", nr))
else
ser_put(dev, sprintf("SVA? %s\n", nr))
aux = ser_get(dev, "\n")
if (aux != "") break
niter += 1
}
PZOSER_A_OLD[num] = aux + 0.0
PZOSER_DIRTY[num] = 0
}
A[num] = PZOSER_A_OLD[num]
}'
#%UU%
#%MDESC%
# set servo mode
def pzoser_setserv '{
local mne serv dev nr
mne = "$1"
serv = $2
dev = list_getpar(PZOSER_LIST, mne, "dev")
nr = list_getpar(PZOSER_LIST, mne, "nr")
list_setpar(PZOSER_LIST, mne, "serv", serv)
ser_put(dev, sprintf("SVO %s%d\n", nr, serv))
}'
def pzoser_geterr '{
ser_put(dev, sprintf("ERR? %s%d\n", nr, serv))
printf("PZOSER ERROR : |%s|\n", ser_get(dev))
}'
#%UU%
#%MDESC%
# set limit
def pzoser_setlim '{
local mne serv dev nr
mne = "$1"
limp = $2
limm = $3
dev = list_getpar(PZOSER_LIST, mne, "dev")
nr = list_getpar(PZOSER_LIST, mne, "nr")
serv = list_getpar(PZOSER_LIST, mne, "serv")
if (serv) {
ser_put(dev, sprintf("PMA %s%g\n", nr, limp))
ser_put(dev, sprintf("PMI %s%g\n", nr, limm))
} else {
ser_put(dev, sprintf("VMA %s%g\n", nr, limp))
ser_put(dev, sprintf("VMI %s%g\n", nr, limm))
}
}'
#%UU%
#%MDESC%
# set limit
def pzoser_readlim '{
local mne serv dev nr
mne = "$1"
dev = list_getpar(PZOSER_LIST, mne, "dev")
nr = list_getpar(PZOSER_LIST, mne, "nr")
serv = list_getpar(PZOSER_LIST, mne, "serv")
if (serv) {
ser_put(dev, sprintf("PMA? %s\n", nr))
printf("\"%s\" upper limit %g (microns)\n", mne, ser_get(0)+0)
ser_put(dev, sprintf("PMI? %s\n", nr))
printf("\"%s\" lower limit %g (microns)\n", mne, ser_get(0)+0)
} else {
ser_put(dev, sprintf("VMA? %s\n", nr))
printf("\"%s\" upper limit %g (V)\n", mne, ser_get(0)+0)
ser_put(dev, sprintf("VMI? %s\n", nr))
printf("\"%s\" lower limit %g (V)\n", mne, ser_get(0)+0)
}
}'
def pzoser_read_param '{
local mne serv dev nr
mne = "$1"
dev = list_getpar(PZOSER_LIST, mne, "dev")
nr = list_getpar(PZOSER_LIST, mne, "nr")
serv = list_getpar(PZOSER_LIST, mne, "serv")
# set step size parameters
ser_put(dev, sprintf("SPA? %s7\n", nr))
sleep(0.1)
printf("motor \"%s\" 7: %g\n", mne, ser_get(dev))
ser_put(dev, sprintf("SPA? %s8\n", nr))
sleep(0.1)
printf("motor \"%s\" 8: %g\n", mne, ser_get(dev))
ser_put(dev, sprintf("SPA? %s9\n", nr))
sleep(0.1)
printf("motor \"%s\" 9: %g\n", mne, ser_get(dev))
ser_put(dev, sprintf("SPA? %s10\n", nr))
sleep(0.1)
printf("motor \"%s\" 10: %g\n", mne, ser_get(dev))
}'
#%MACROS%
#%IMACROS%
#%DEPENDENCIES%
# To use a piezo as a motor the following conditions have to be fulfilled:
#%UL%
#%LI% The file piezo_gpib.mac has to be read in done by: startup s.
# (this file needs: pseudo.mac , stchanges.mac)
#%LI% the piezo motors have to be configured done by: SPECADM
# (Controller NONE, mnemonic as in startupscript)
#%LI% setup the piezos ( with pzosetup ) done by: startup s.
#%XUL%
#%AUTHOR% Holger
#%TOC%
|