#%NAME%
#%DESCRIPTION%
#Control of the Brucker BEC1 magnet power supply, using serial line:
#%BR%- 9600 bauds
#%BR%- 8 data bits
#%BR%- 1 start and 1 stop bits
#%BR%- no parity
#%BR% the CTS and RTS signals must be connected together.
#%BR% The field is expressed in gauss.
#%BR% The user can control via macromotor or pseudomotor
#%BR%- if macromotor, then the controller is set in the spec config as 'bec1'.
#%BR%the macromotor must define a parameter 'serial' with the serial line index.
#%END%
global BEC1_mne BEC1_ser BEC1 BEC1ON BEC1_MV BEC1_OLD BEC1_msl BEC1_sleep BEC1_field BEC1_debug
BEC1_sleep=0.2
#%UU%(mne)
#%MDESC% set <remote>-<reset errors>-<power on>-<field regulation>
def bec1on'{
########## uses BEC1_ser
#remote mode
p "BEC1: setting remote mode"
ser_put(BEC1_ser,"REM=1\r\n");sleep(BEC1_sleep);p ser_get(BEC1_ser)
#reset errors
p "BEC1: reset errors"
ser_put(BEC1_ser,"RST=0\r\n");sleep(BEC1_sleep);p ser_get(BEC1_ser)
#power on
p "BEC1: power on"
ser_put(BEC1_ser,"DCP=1\r\n");sleep(BEC1_sleep);p ser_get(BEC1_ser)
#set to field regulation
p "BEC1: setting to field regulation"
ser_put(BEC1_ser,"EXT=2\r\n");sleep(BEC1_sleep);p ser_get(BEC1_ser)
sync
}'
#%UU%(mne)
#%MDESC% set -<power off>-
def bec1off'{
########## uses BEC1_ser
#power off
p "BEC1: power off"
ser_put(BEC1_ser,"DCP=0\r\n");sleep(BEC1_sleep);p ser_get(BEC1_ser)
}'
#%IU%
#%MDESC%
# MACRO MOTOR:
# Called by spec after reading the config file
#
def bec1_config(num,cmd,p1,p2,p3) '{
__bec1_debug ">>> bec1_config: ",num,cmd,p1,p2,p3
# called for each macro-hardware controller
# p1:unit p2: nbchan
if(cmd=="ctrl") {
__bec1_debug ">>> new controller "
}
# called for each macro motor channel
# p1:unit p2:module p3:channel
if(cmd=="mot") {
#nothing
}
#returns nothing or .error.
}'
#%IU%
#%MDESC%
# MACRO MOTOR:
# Called by spec on motor operation. It manages:
#%BR%- position
#%BR%- start_one
#%BR%- get_status
def bec1_cmd(num,key,p1,p2) '{
local myser resp mysleep
__bec1_debug ">>> bec1_cmd: ",num, key, todo, p1, p2
if(num == "..") { return }
#myser = motor_par(num,"serial")
myser = bec1_ADDR
BEC1_ser = bec1_ADDR
__bec1_debug ">>> bec1_cmd: serial: " myser
#
# return the current position
#
if (key == "position") {
__bec1_debug ">>> bec1_cmd: position acting"
resp = bec1_readfield(myser)
if (resp == 0) {
return BEC1_field-50
}
else {
return ".error."
}
}
#
# start a motion. p1: dial abs. pos., p2: dial rel. pos.
#
if (key == "start_one") {
__bec1_debug ">>> bec1_cmd: start_one acting"
mysleep = fabs(p2) * 12 / 8000
resp = bec1_setfield(myser, p1+50, mysleep)
#returns nothing
}
#
# return motor status always ON as sleep is done inside the mv .......
# sure !! it is not clean !!!
#
if (key == "get_status") {
__bec1_debug ">>> bec1_cmd: get_status acting"
return 0
}
}'
#%UU%(serial)
#%MDESC% reads the field, and set the global variable BEC1_field
#%BR%returns: 0 (if OK), -1 (if not OK)
def bec1_readfield(ser)'{
local mystr myi myval nval vval
__bec1_debug "...BEC1_readfield: " , ser
#format should be:
#FLD/ 500.000G
ser_put(ser,"FLD/\r\n");
sleep(BEC1_sleep)
mystr = ser_get(ser)
__bec1_debug "...BEC1_readfield: reads " , mystr
myi = index(mystr,"FLD/")
if (myi == 0) {
#try once more
mystr = ser_get(ser)
__bec1_debug "...BEC1_readfield: reads2 " , mystr
myi = index(mystr,"FLD/")
if (myi == 0){
p "Brucker BEC1 unexpected answer: " mystr
return(-1)
}
}
myval = substr(mystr,myi+4)
__bec1_debug "...BEC1_readfield: field string " , myval
vval[0]=0
nval = split(myval,vval,"G")
# value should be vval[0]
if (nval == 0){
p "Brucker BEC1 unexpected field value: " myval
return(-1)
}
if ((vval[0]*10)/10 != vval[0]) {
p "Brucker BEC1 unexpected field value: " myval
return(-1)
}
BEC1_field = vval[0]
return(0)
}'
#%UU%(serial,field,sleep)
#%MDESC% set the field. Waits <sleep> seconds before continuing.
#%BR% returns 0 (1f OK) and -1 (if not OK)
def bec1_setfield(ser, vfield,mysleep )'{
local mystr myresp
__bec1_debug "...BEC1_setfield: " , ser, vfield, mysleep
mystr = sprintf("FLD=%f\r\n",vfield)
__bec1_debug "...BEC1_setfield: sends" , mystr
ser_put(ser,mystr)
sleep(BEC1_sleep)
myresp = ser_get(ser,"\n")
__bec1_debug "...BEC1_setfield: reads" , myresp
if(index(myresp,"E0") != 0) {
p "Brucker BEC1 : error (" myresp ") with command: " mystr
return(-1)
}
__bec1_debug "...BEC1_setfield: calculated ramping time: " ,mysleep
sleep(mysleep)
# more info if msl mode. should send 2 lines:
#FU tt
#UF tt
if (BEC1_msl == 1) {
myresp = ser_get(ser,"\n")
__bec1_debug "...BEC1 msl mode reads: 1: " , myresp
if ( (index(myresp,"FU tt") == 0) && (index(myresp,"UF tt") == 0) ){
p "Brucker BEC1: WARNING : did not get FU tt and UF tt"
}
else {
myresp =""
myresp = ser_get(ser,"\n")
__bec1_debug "...BEC1 msl mode reads: 2: " , myresp
if ( (index(myresp,"FU tt") == 0) && (index(myresp,"UF tt") == 0) ){
p "Brucker BEC1: WARNING : did not get FU tt and UF tt"
}
}
}
#################
# returns 0 even if WARNING.
#################
return(0)
}'
#%UU%(mne)
#%MDESC%prints the status
def bec1_status'{
########## uses BEC1_ser
ser_put(BEC1_ser,"STA/\r\n");sleep(BEC1_sleep);p ser_get(BEC1_ser)
ser_put(BEC1_ser,"REM/\r\n");sleep(BEC1_sleep);p ser_get(BEC1_ser)
ser_put(BEC1_ser,"DCP/\r\n");sleep(BEC1_sleep);p ser_get(BEC1_ser)
}'
#%UU%(mne,<1/0>)
#%MDESC%to set/remove the MSL mode
def bec1_inform'{
local inf
inf = $1
########## uses BEC1_ser
if (inf == 1) {
ser_put(BEC1_ser,"MSL=1\r\n")
BEC1_msl = 1
sleep(BEC1_sleep)
p ser_get(BEC1_ser)
}
else {
ser_put(BEC1_ser,"MSL=0\r\n")
BEC1_msl = 0
sleep(BEC1_sleep)
p ser_get(BEC1_ser)
}
}'
#%UU%
#%MDESC% toggle the debug mode
if (!(whatis("__bec1_debug") & 2)) rdef __bec1_debug \'#$*\'
def bec1_debug '{
if ((whatis("__bec1_debug")>>16) <= 3) { # macro length is 3 bytes: comment
rdef __bec1_debug "eprint"
print "bec1 macro debug mode is ON"
BEC1_debug = 1
}
else {
rdef __bec1_debug \'#\$*\'
print "bec1 macro debug mode is OFF"
BEC1_debug = 0
}
}'
#%UU%
#%MDESC% write a command
def bec1_wr(mystr)'{
local mys
########## uses BEC1_ser
mys= sprintf("%s\r\n",mystr)
p "writing: " mys
ser_put(BEC1_ser,mys)
sleep(BEC1_sleep)
p "reading: " ser_get(BEC1_ser)
}'
#####################################################################################
#
# pseudomotor handling
#
#####################################################################################
#%UU% <mne> <ser_unit>
#%MDESC%setup (if use pseudomotor)
def bec1___setup'{
if ($# != 2) {
p "usage: bec1___setup <mne> <ser>"
exit
}
BEC1_mne = "$1"
BEC1_ser = $2
BEC1_MV = 1
}'
#%UU%
#%MDESC%pseudo on (if use pseudomotor)
def bec1___on' {
cdef("user_getpangles",sprintf("bec1_wa %s %s ;",BEC1_mne, BEC1_ser),BEC1_mne,0x01)
cdef("user_checkall",sprintf("bec1_mv %s %s ;",BEC1_mne, BEC1_ser),BEC1_mne,0x11)
BEC1ON = 1
}'
#%UU%
#%MDESC%pseudo off (if use pseudomotor)
def bec1___off' {
cdef("user_getpangles","",BEC1_mne,"delete")
cdef("user_checkall","",BEC1_mne,"delete")
BEC1ON = 0
}'
#%IU%
#%MDESC% For blmenu (use blmenu.mac). (if use pseudomotor)
def bec1body(mode) '{
if (mode == 1) {
if (BEC1ON) {
bec1___off
}
else {
bec1___on
}
}
return(sprintf("%s",BEC1ON?"ON":"OFF"))
}'
#%IU% <mne> <serial nb>
#%MDESC% pseudomotor reading. (if use pseudomotor)
def bec1_wa'{
local mymne myser myval vval nval
mymne = $1
myser = $2
if (BEC1_MV == 1) {
resp = bec1_readfield(myser)
if (resp == 0) {
A[motor_num(mymne)] = BEC1_field
BEC1_OLD = BEC1_field
BEC1_MV = 0
}
#else, an error occured. message was sent.
#we decide not to exit.
}
}'
#%IU% <mne> <serial nb>
#%MDESC% pseudomotor motion (if use pseudomotor)
def bec1_mv'{
local mymne myser myresp
mymne = $1
myser = $2
if (fabs(A[motor_num(mymne)] - BEC1_OLD) > 1e-6) {
myresp = bec1_setfield(myser, A[motor_num(mymne)], BEC1_OLD, BEC1_msl)
#do not exit if an error. just a WARNING was printed
BEC1_MV = 1
}
}'
#%MACROS%
#%IMACROS%
#%LOG%
#$Revision: 1.1 $
#$Log: brucker_bec1.mac,v $
#Revision 1.1 2011/07/06 06:54:30 domingue
#Initial revision
#
#%AUTHOR% mcd july 2011
|