#%TITLE% MKS_PR4000.MAC
#%NAME%
# Macros for controlling MKS PR4000 dual channel power supply
# and readout for flow and pressure.
#
# The communication is done through a serial line that has to
# configured in SPEC config first.
#
# Currently multi controllers are not supported.
#
constant MKS_EOC "\r"
global MKS_SL
#%UU% serial_line
#%MDESC%
# Select the SPEC serial line to use.
#
def mks_setup '{
if($# != 1) {
print "Usage: $0 serial_line"
print "Ex: $ 1"
exit
}
MKS_SL = int($1)
if(_mks_cmd("?ID") == "") {
print "Error: no MKS PR4000 found"
MKS_SL = -1
exit
}
# switch on remote mode
mks_remonteon
}'
#%UU%
#%MDESC%
# Switch on remote control, disable controller front panel
#
def mks_remoteon '{
_mksremote(1)
}'
#%UU%
#%MDESC%
# Switch off remote control, enable controller front panel
#
def mks_remoteoff '{
_mksremote(0)
}'
#%IU%(action)
#%MDESC%
# Switch remote control on or off, depending if action
# given is 1 or 0.
# Can be called without any action.
# Returns non null if remote control is on
#
def _mks_remote(action) '{
if(!(whatis("action") & 0x08000000)) {
_mks_cmd(sprintf("RT,%s",action?"ON":"OFF"))
}
return (index(_mks_cmd("?RT"), "ON") ? 1 : 0)
}'
#%UU% channel [value]
#%MDESC%
# Change the setpoint on the given channel
#
def mks_setpoint '{
local ch
local sp
local val
if($# < 1) {
print "Usage: $0 channel [value]"
print "Ex: $0 1 1.2"
exit
}
ch = int($1)
_mks_checkchannel(ch)
if($# == 2) {
sp = $2
val = _mks_setpoint(ch, sp)
} else {
val = _mks_setpoint(ch)
}
printf("current setpoint: %f\n", val)
}'
#%IU%(channel, value)
#%MDESC%
# Change the setpoint on the given channel.
# Can be called without any value.
# Returns the current setpoint.
#
def _mks_setpoint(ch, sp) '{
local ans
local val
_mks_checkchannel(ch)
if(!(whatis("sp") & 0x08000000)) {
_mks_cmd(sprintf("SP%d,%f", ch, sp))
}
ans = _mks_cmd(sprintf("?SP%d", ch))
if(sscanf(ans, "%f", val) != 1) {
print "Error: unable to parse setpoint"
exit
}
return val
}'
#%UU% channel
#%MDESC%
# Print the current flow rate on the given channel
#
def mks_read '{
local ch
local val
if($# < 1) {
print "Usage: $0 channel"
print "Ex: $0 1"
exit
}
ch = int($1)
_mks_checkchannel(ch)
val = _mks_read(ch)
printf("current flow : %f\n", val)
}'
#%IU%(channel)
#%MDESC%
# Returns the current flow rate on the given channel.
#
def _mks_read(ch) '{
local ans
local val
_mks_checkchannel(ch)
ans = _mks_cmd(sprintf("AV%d", ch))
if(sscanf(ans, "%f", val) != 1) {
print "Error: unable to parse current flow rate"
exit
}
return val
}'
#%UU% channel
#%MDESC%
# Wait until the current flow rate is at least 90% of the setpoint
# WARNING: no timeout, use <cltr-c>
#
def mks_wait '{
local ch
if($# < 1) {
print "Usage: $0 channel"
print "Ex: $0 1"
exit
}
ch = int($1)
_mks_wait(ch, 1)
}'
#%IU%(channel)
#%MDESC%
# Returns the current flow rate on the given channel.
#
def _mks_wait(ch, verbose) '{
local ans
local val
local sp
_mks_checkchannel(ch)
sp = _mks_setpoint(ch)
if(verbose) { printf("current setpoint: %f\n", sp) }
sp *= 0.9
if(verbose) { printf("waiting...") }
while(1) {
val = _mks_read(ch)
if(val > sp) {
break
}
if(verbose) { printf(".") }
sleep(.1)
}
}'
#%UU% channel
#%MDESC%
# Close the valve on the given channel
#
def mks_valveclose '{
if($# != 1) {
print "Usage: $0 channel"
print "Ex: $0 1"
}
mks_valve $1 CLOSE
}'
#%UU% channel
#%MDESC%
# Open the valve on the given channel
#
def mks_valveopen '{
if($# != 1) {
print "Usage: $0 channel"
print "Ex: $0 1"
}
mks_valve $1 OPEN
}'
#%UU% channel [OPEN|CLOSE]
#%MDESC%
# Control the valve on the given channel
#
def mks_valve '{
local ch
local action
local val
local sta
if($# < 1) {
print "Usage: $0 channel [OPEN|CLOSE]"
print "Ex: $0 1 OPEN"
}
ch = int($1)
_mks_checkchannel(ch)
if($# == 2) {
action = "$2"
if((action != "OPEN") && (action != "CLOSE")) {
print "Error: action must be \"OPEN\" or \"CLOSE\""
exit
}
val = (action == "OPEN") ? 1 : 0
sta = _mks_valve(ch, val)
} else {
sta = _mks_valve(ch)
}
printf("valve is: %s\n", (sta ? "OPEN" : "CLOSED"))
}'
#%IU%(channel, action)
#%MDESC%
# Change the valve state on the given channel.
# Can be called without any action.
# Returns non null if the valve is open.
#
def _mks_valve(ch, action) '{
_mks_checkchannel(ch)
if(!(whatis("action") & 0x08000000)) {
_mks_cmd(sprintf("VL%d,%s", ch, (action?"ON":"OFF")))
}
return (index(_mks_cmd(sprintf("?VL%d", ch)), "ON") ? 1 : 0)
}'
#%IU%(channel)
#%MDESC%
#
def _mks_checkchannel(ch) '{
if((ch != 1) && (ch != 2)) {
print "Error: invalid chanel, must be 1 or 2"
exit
}
}'
#%IU%(cmd)
#%MDESC%
# Send the given command to the controller and returns its
# answer or ".error."
#
def _mks_cmd(cmd) '{
local sl
local ans
local len
sl = MKS_SL
if((sl == -1) || (whatis("MKS_SL") & 0x08000000)) {
print "Error: missing serial line initialization"
print "Hint: use \"mkssetup\""
return ".error."
}
ser_par(sl, "flush")
if(index(cmd, MKK_EOC) == 0) {
cmd = sprintf("%s%s", cmd, MKS_EOC)
}
ser_put(sl, cmd)
ans = ser_get(sl, MKS_EOC)
len = length(ans)
if(substr(ans, len) == MKS_EOC) {
ans = substr(ans, 0, len-1)
}
return ans
}'
#%IU%
#%MDESC%
# MACRO COUNTER:
# Called by spec after reading the config file
#
def mks_sp_config(num,type,p1,p2,p3) '{
if(type=="ctrl") {
MKS_SL = mks_sp_ADDR
return
}
if(type=="cnt") {
return
}
}'
#%IU%
#%MDESC%
# MACRO COUNTER:
# Called by spec on counter operation.
#
def mks_sp_cmd(num,key,p1,p2) '{
local mne
local ch
if (key == "counts") {
mne = cnt_mne(num)
ch = counter_par(num, "channel")
S[num]=_mks_setpoint(ch)
}
}'
#%IU%
#%MDESC%
# MACRO COUNTER:
# Called by spec after reading the config file
#
def mks_read_config(num,type,p1,p2,p3) '{
if(type=="ctrl") {
MKS_SL = mks_sp_ADDR
return
}
if(type=="cnt") {
return
}
}'
#%IU%
#%MDESC%
# MACRO COUNTER:
# Called by spec on counter operation.
#
def mks_read_cmd(num,key,p1,p2) '{
local mne
local ch
if (key == "counts") {
mne = cnt_mne(num)
ch = counter_par(num, "channel")
S[num]=_mks_read(ch)
}
}'
#%MACROS%
#%IMACROS%
#%AUTHOR% MP BLISS (Original Apr/2015).
# %BR%$Revision: 1.1 $ / $Date: 2015/06/02 05:25:21 $
#%TOC%
|