#%TITLE% ELMETER.MAC
#$Revision: 2.17 $
#%NAME%
# %B%ELMETER.MAC%B% - Macros for %B%electrometer%B% control.
#
#%DESCRIPTION%
# This macro set provides the possibility to read electrometers
# with automatic gain adujustement.
#
#%PRE%
#
#Three types of electrometers are supported for the moment:
#
#%UL%
#%LI%Type 0: ADC reading with three input lines with all bit combinations for gain adjustment. Eight posible gain values are posible.
#
#%LI%Type 1: ADC reading with three input lines with exclusive values. Only three gain values are posible.
#
#%LI%Type 2: Other type. The macros do not read the counter value but other macros or SPEC itself take care of that. The min/max thresholds are normalized with counting time. For the moment, in this case only three mutually exclusive input lines are used for gain adjustment.
#
#Electrometers are seen in SPEC as counters and must be defined as such in SPEC config.
#
#%LI%Type 3: ID11 electrometers. Like type 1 only that the gains can vary in elmeteradd you need to supply ( not the min gain ) but the gains for the three relay positions.
#%LI%Type 4: Like type 3 but with a vmeadc linux device server madc
#%LI%Type 5: Novelec on a WAGO box. First trial 25.1.2005
#%LI%Type 6: Novelec on a WAGO box. Value is read with icv150 (petitdem).
#%LI%Type 7: gain + adc control by wago (petitdem).
#%XUL%
#
#%BR%
#%UL%
#%SETUP%
#Use the setup command:
#%LI%Start electrometer definition with a line containing %B%elmeterinit%B%
#Use %B%elmeteradd%B% to configure a new electrometer.
#%LI%To setup several electrometers, use %B%elmeteradd%B% several times.
#Without parameters elmeteradd allows keyboard entry for setup.
#
#%XUL%
#
#%END%
#%HISTORY%
#$Log: elmeter.mac,v $
#Revision 2.17 2017/03/09 15:18:09 ohlsson
#Just a small bug in the debug - the wago readout was not displayed
#
#Revision 2.16 2017/02/10 15:44:21 witsch
#between version 2.15 and 2.16, only the order of the elmeter gain cells
#were reversed. version 2.15 has been deleted from the packages, as they
#can't work correctly.
#
#Revision 2.15 2017/01/19 15:26:30 witsch
#and beautify the code a little.
#
#Revision 2.14 2016/11/18 13:48:46 witsch
#Adapt type 5 to the use of wagocore macros, avoid esrf_io(), so that
#both tango and taco device servers can be used.
#
#Also arguments 3, 4 and 5 have been eliminated from the arguments
#treatment, as they are not needed for type 5 electrometers.
#
#
#Revision 2.13 2012/05/03 16:24:27 petitdem
#add type 7 gain + adc control by wago
#
#Revision 2.12 2011/07/28 13:00:44 beteva
#added channel to be read in elmeteradd; type 6 to be madc
#
#Revision 2.11 2011/07/25 14:18:30 beteva
#Change type 4 to read MADC instead of Icvadc
#
#Revision 2.10 2011/02/22 15:46:23 witsch
#instead of count_em use tcount, in order to avoid prepcount to call a
#
#all the other devices' prepcount.
#
#Revision 2.9 2010/09/17 11:29:54 petitdem
#correct some bugs for type 6 (Wagi + IcvADC)
#
#Revision 2.8 2010/09/01 15:13:08 petitdem
#add type 6 it's a mix with type 5 and type 3: gain is control with Wago and value is read with icv150
#
#Revision 2.5 2005/03/31 14:36:37 witsch
#Added type 5 quite similar to type 2 for the use with a Wago box for the gain
#whereas the electrometer is still read through the VCT6.
#
#Revision 2.4 2004/08/27 11:31:33 claustre
#Added type 4 quit similar to type 3 but has to be used with Linux IcvADC and Relay device server
#
#Revision 2.3 2003/02/10 10:51:28 witsch
#take out the cdef for user_pollcount, as it causes a loop at execution.
#
#Revision 2.2 2002/04/29 15:33:21 witsch
#Enter changes made by Laurent to make sure that the data collector
#entry is present when the first elmeter_set() is done. Apart from that
#a few cosmetic changes.
#
#Revision 2.1 2002/04/11 15:29:19 witsch
#The macro elmeteradd now accepts an argument more, which decides on the
#use of the data collector for storing the gain. The argument must be true
#to use the DC and false to omit the DC use.
#
#revision 2.0
#date: 2002/02/27 08:26:35; author: witsch; state: Exp; lines: +27 -18
#After a long time of searching, a bug in elmeter_mread was found. The
#COUNT_TIME wasn't taken into account when using type 2 kind of elmeters.
#This made that for short counting times the count was low and the automatic
#gain adjustment didn't work.
#Apart from that we have a little cosmetic work..
#----------------------------
#revision 1.2
#date: 2002/02/27 08:14:29; author: witsch; state: Exp; lines: +30 -28
#branches: 1.2.1;
#Move saved gain value from data base to the associative array
#which holds all the info about the elmeters.
#----------------------------
#revision 1.1
#date: 2002/02/27 08:10:45; author: rey; state: Exp;
#Initial revision
#%END%
if (!(whatis("__elmeterdebug") & 2)) rdef __elmeterdebug \'#$*\'
#%UU%
#%MDESC% toggle debug mode for the present macros.
def elmeter_debug '{
if ((whatis("__elmeterdebug")>>16) <= 5) { # just a # sign -> off
rdef __elmeterdebug "eprint"
print "elmeter debug is ON"
} else {
rdef __elmeterdebug \'#$*\'
print "elmeter debug is OFF"
}
}
'
#%UU% mne type icv150name icv150channel icv196name icv1596channel lowthresh highthresh [gain1 gain2 gain3|lowgain] usedatacoll
#%MDESC% Attention: different number of arguments for different types of electrometers.
def elmeteradd '{
local mne adcdev channel reldev relfirst type
local vmin vmax gmin
gmin = 1; dcaccess = 0
if (!(whatis("ELM_LIST") & 0x01000000)) elmeterinit
if (!$#) {
mne = getval("Mnemonic for Electrometer counter", "")
type = getval("\tElectrometer type (0=ADC 3bit/1= ADC 3bit excl/2=Other/3=ID11/4=Linux ADCds/5=Wago Novelec)", 0)
if (type == 1 || type == 3) {
adcdev = getval("\tICV150 Device name", "")
channel = getval("\tICV150 Channel", 0)
reldev = getval("\tICV196 Device root name", "")
relfirst = getval("\tICV196 First channel", 0)
} else if (type == 4) {
adcdev = getval("\tLinux ICV150 Device name", "")
reldev = getval("\tICV196 Device root name", "")
relfirst = getval("\tICV196 First channel", 0)
} else if (type == 5 || type == 6 || type == 7) {
# reldev = getval("\tWAGO device name", "")
reldev = getval("\tWago signal name for gain", "")
if(type == 6)
{
adcdev = getval("\tICV150 Device name", "")
channel = getval("\tICV150 Channel", 0)
}
else if(type == 7)
{
adcdev = getval("\tWago device name", "")
channel = getval("\tWago signal name to read adc value", "")
}
}
vmin = getval("\tLow value threshold ", 0.8)
vmax = getval("\tHigh value threshold", 9)
if (type == 3 || type == 4) {
gain1 = getval("\t1st gain", 7)
gain2 = getval("\t2nd gain", 8)
gain3 = getval("\t3rd gain", 9)
} else {
gmin = getval("\tLower gain", 4)
}
dcaccess = yesno("\tUse the data collector to store the gain", "")
} else {
mne = "$1"
type = $2
if (type == 1 || type ==3 || type ==4 || type == 6 || type == 7) {
adcdev = "$3"
channel = "$4"
} else if (type == 2) {
adcdev = "bidon"
channel = 0
}
reldev = "$5"
relfirst = $6
if (type == 5 || type == 6 || type == 7) {
# skipt arguments 3 and 4, they`re not needed
# reldev = "$5" # wago resource name, set above
vmin = $7
vmax = $8
gmin = $9
dcaccess = "$10"
} else {
vmin = $7
vmax = $8
if (type == 3 ||type == 4) {
gain1 = $9
gain2 = $10
gain3 = $11
dcaccess= $12
} else {
gmin = $9
dcaccess= $10
}
}
}
#
# Init and dccsetup
#
list_add(ELM_LIST, mne)
list_setpar(ELM_LIST, mne, "adcdev", adcdev)
list_setpar(ELM_LIST, mne, "channel", channel)
list_setpar(ELM_LIST, mne, "reldev", reldev)
list_setpar(ELM_LIST, mne, "relfirst", relfirst)
list_setpar(ELM_LIST, mne, "type", type)
list_setpar(ELM_LIST, mne, "cntnum", cnt_num(mne))
list_setpar(ELM_LIST, mne, "vmin", vmin)
list_setpar(ELM_LIST, mne, "vmax", vmax)
list_setpar(ELM_LIST, mne, "gmin", gmin)
if (dcaccess) {
local dname
dname = sprintf("%s/elmeter/%s", SPECBL, mne)
list_setpar(ELM_LIST, mne, "dcaccess", dname)
esrf_dc(dname, "create", "DevRead", "D_LONG_TYPE")
} else {
list_setpar(ELM_LIST, mne, "dcaccess", 0)
}
if (type == 3 || type == 4) {
list_setpar(ELM_LIST, mne, "gain1", gain1)
list_setpar(ELM_LIST, mne, "gain2", gain2)
list_setpar(ELM_LIST, mne, "gain3", gain3)
list_setpar(ELM_LIST, mne, "gmin", gain1)
gain = list_getpar(ELM_LIST, mne, "gain")
if (gain == 0 ) {
list_setpar(ELM_LIST, mne, "gain", gain1)
}
elmeter_set(mne, gain1)
if (type == 5) {
local gain
gain = _wago_elmeter_read(mne)
list_setpar(ELM_LIST, mne, "gain", gain)
} else {
list_setpar(ELM_LIST, mne, "gain", gmin)
}
setup_tail("elmeter", "$1")
}'
#%UU%
#%MDESC%
# Sets all electrometers to minimum gain
#
def elmetermin '{
local gain
for (i=0;i<ELM_LIST[0];i++) {
mne = ELM_LIST[i+1]
type = list_getpar(ELM_LIST, mne, "type")
if (type == 3 || type == 4) {
gain = list_getpar(ELM_LIST, mne, "gain1")
} else {
gain = list_getpar(ELM_LIST, mne, "gmin")
}
elmeter_set(mne, gain)
}
}'
#%IU%
#%MDESC%
# Use with blmenu
#
def elmeterbody(mode) '{
if (mode == 1) {
if (ELM_ON) {
elmeteroff
} else {
elmeteron
}
}
if (mode == 2) {
elmetershow
}
return(ELM_ON?"On":"Off")
}'
#%IU%
#%MDESC%
#
def elmeterinit '{
global ELM_LIST
list_init ELM_LIST
blmenuadd("Electrometers", "Elmeter show", "elmeterbody", "_elmeter_")
if (whatis("ELM_ON") & 0x8000000 ) elmeteron
}'
#%IU%
#%MDESC%
#
def elmeterunsetup '{
elmeterdel("$1")
}'
#%UU% <counter mne>
#%MDESC% deletes from setup an electrometer.
#
def elmeterdel(mne) '{
list_remove(ELM_LIST, mne)
}'
#%UU%
#%MDESC% shows the currently defined electrometers in setup.
#
def pindiode 'elmetershow '
def elmetershow '{
local i j elmno mne
local adcdev channel reldev relfirst type dcaccess
local cntnum cntstate tmpgainNow gainnow vmin vmax gmin gmax cnum
elmno = ELM_LIST[0]
if (elmno) {
for (i=0; i<elmno; i++) {
mne[i] = ELM_LIST[i+1]
type[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "type")
if (type[i] != 2) {
adcdev[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "adcdev")
channel[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "channel")
} else {
cnum = cnt_num(mne[i])
if (cnum != -1 ) {
adcdev[i] = counter_par(cnum, "controller")
channel[i] = counter_par(cnum, "channel")
} else {
adcdev[i] = "Not config"
channel[i] = 0
}
}
reldev[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "reldev")
relfirst[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "relfirst")
cntnum[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "cntnum")
cntstate[i] = (cntnum[i]==-1)?"No":"Yes"
vmin[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "vmin")
vmax[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "vmax")
if ( type[i] == 3 ) {
gmin[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "gain1")
gmax[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "gain3")
} else {
gmin[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "gmin")
gmax[i] = (type[i])?(gmin[i]+2):(gmin[i]+7)
}
gainnow[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "gain")
if (type[i] == 5) { # read real value from wago
gainnow[i] = _wago_elmeter_read(ELM_LIST[i+1])
}
#~ if(tmpgainNow < gmin[i])
#~ tmpgainNow += 6 #~ not sure, what that was for !
dcaccess[i] = list_getpar(ELM_LIST, ELM_LIST[i+1], "dcaccess")
__elmeterdebug "wago_readch:", mne[i], gainnow[i], x[0], x[1], x[2]
}
elmpr("Mnemonic", mne, elmno)
elmpr("Defined", cntstate, elmno)
elmpr("Type", type, elmno)
printf("GAIN:\n")
elmpr("Min", gmin, elmno)
elmpr("Set", gainnow, elmno)
elmpr("Max", gmax, elmno)
printf("THRES:\n")
elmpr("Low", vmin, elmno)
elmpr("High", vmax, elmno)
printf("DEV:\n")
elmpr("CTRL", adcdev, elmno)
elmpr("Channel", channel, elmno)
elmpr("Relay", reldev, elmno)
elmpr("R.1st Ch", relfirst, elmno)
printf("DC:\n")
elmpr("dcaccess", dcaccess, elmno)
} else {
printf("No electrometer defined\n")
}
}'
#%IU%
#%MDESC%
#
def elmpr(label, var, n) '{
local j
printf("%10s: ", label)
for (j=0;j<n;j++) {
printf(" %12.12s", var[j])
}
printf("\n")
}'
#%IU%
#%MDESC% Enables all electrometer counters
#
def elmeteron '{
global ELM_AVER ELM_NOREAD ELM_ON ELM_GAIN
global ELM_UPDATING
local i elmno
ELM_ON = 1
cdef("user_prepcount", "elmeter_prepcount;", "elmeter")
cdef("user_getcounts", "elmeter_getcounts;", "elmeter")
elmno = ELM_LIST[0]
for (i=0; i<elmno; i++) {
local num mne
mne = ELM_LIST[i+1]
num = cnt_num(mne)
if (num != -1) counter_par (num, "disable", 0)
}
}'
#%UU%
#%MDESC% Disables all electrometer counters
#
def elmeteroff '{
local elmno i
ELM_ON = 0
cdef("", "", "elmeter", "delete")
elmno = ELM_LIST[0]
for (i=0; i<elmno; i++) {
local num mne
mne = ELM_LIST[i+1]
num = cnt_num(mne)
if (num != -1) counter_par(num, "disable", 1)
}
}'
#%IU%
#%MDESC%
#
def elmeter_prepcount '{
local i elmno gain, type
elmno = ELM_LIST[0]
elmupdate
for (i=0; i<elmno; i++) {
ELM_AVER[i] = 0
ELM_NOREADS[i] = 0
}
ELM_UPDATING=0
if (COUNT_TIME < 0) {
if (cnt_mne(MON) > 0) {
gain = list_getpar(ELM_LIST, cnt_mne(MON), "gain")
type = list_getpar(ELM_LIST, cnt_mne(MON), "type")
if (type == 5) {
gain = _wago_elmeter_read(cnt_mne(MON))
list_setpar(ELM_LIST, mne, "gain", gain)
}
COUNT_TIME = COUNT_TIME * exp10(gain)
COUNT_TIME /= exp10(10)
}
}
}'
#%IU%
#%MDESC%
#
def elmeter_getcounts '{
local i elmno type
elmno = ELM_LIST[0]
# next macro OK for type 0 and 1 also after count
# for type 2 exit is done from elmeter_mread
# for type 2 get counts automatically?
elmeter_mread
for (i=0; i<elmno; i++) {
local num mne
mne = ELM_LIST[i+1]
num = cnt_num(mne)
if (num == -1 || counter_par(num, "disable") == 1) continue
# for type 2 exit is done here
type = list_getpar(ELM_LIST, mne, "type")
#
# For type 0 and 1. Just show average.
#
if (type != 2 && type != 5) {
if (num != -1 ) {
S[num] = ELM_AVER[i] * counter_par(num, "scale") / ((ELM_NOREADS[i]==0)?1:ELM_NOREADS[i]);
} else {
printf("Wrong counter number. Internal macro error\n")
}
} else {
if (!ELM_UPDATING) {
gain = list_getpar(ELM_LIST, mne, "gain")
# type 5, gain has been read in user_prepcount
__elmeterdebug "original value", mne, S[num], "to be devided with exp10(" gain - 1 ")", exp10(gain - 1)
S[num] /= exp10(gain - 1)
}
}
}
}'
#%IU%
#%MDESC% For ADC type electrometers (type 0 and 1), since read/gain corrected
# during counting
#
def elmeter_mread '{
local val i ell elmno iter num
elmno = ELM_LIST[0]
for (ell=0; ell<elmno; ell++) {
local inloop mne chan adcdev
local vmin vmax gmin gmax type
local gain num
mne = ELM_LIST[ell+1]
num = cnt_num(mne)
if (num == -1 || counter_par(num, "disable") == 1) continue
vmin = list_getpar(ELM_LIST, mne, "vmin")
vmax = list_getpar(ELM_LIST, mne, "vmax")
type = list_getpar(ELM_LIST, mne, "type")
if (type == 3 || type == 4) {
gmin = list_getpar(ELM_LIST, mne, "gain1")
gain2 = list_getpar(ELM_LIST, mne, "gain2")
gmax = list_getpar(ELM_LIST, mne, "gain3")
} else if(type == 6 || type == 7){
gmin = 1
gmax = 3
} else {
gmin = list_getpar(ELM_LIST, mne, "gmin")
gmax = (type)?(gmin+2):(gmin+7)
}
gain = list_getpar(ELM_LIST, mne, "gain")
if (type == 5) {
gain = _wago_elmeter_read(mne)
}
if ((num = cnt_num(mne)) == -1) continue
inloop = 1
iter = 0
while (inloop) {
if (type == 2 || type == 5) {
# HW20020214 begin
# The counter will deliver a count, which already takes
# the scaling factor into account. To get the real value, we
# have to multiply the given value with the scaling factor.
# However the longer you read the more counts you get!
# Devide by count_time
# HW20020214 end
val=S[num] * counter_par(num, "scale")
val /= COUNT_TIME
} else {
val = _adc_read(mne)
if (val == -1) { break }
}
if (ELM_FIXED) { break }
if ( fabs(val) < vmin ) {
if ( gain < gmax ) {
if ( type == 3 || type == 4) {
if ( gain == gmin ) {
gain = gain2
} else if ( gain != gmin ) {
gain = gmax
}
} else {
gain++
}
elmeter_set( mne , gain)
} else {
inloop = 0
}
} else {
if ( fabs(val) > vmax ) {
if ( gain > gmin ) {
if ( type == 3 || type == 4) {
if ( gain == gmax ) {
gain = gain2
} else if ( gain != gmax ) {
gain = gmin
}
} else {
gain--
}
elmeter_set(mne, gain)
} else {
inloop = 0
}
} else {
inloop = 0
}
}
if (iter++ > 10) inloop = 0
if (inloop == 1 && (type == 2 || type == 5)) {
__elmeterdebug "inloop elmeter_mread"
elmeter_prepcount
tcount(COUNT_TIME)
# -- count_em COUNT_TIME
waitcount
getcounts
}
}
gain = list_getpar(ELM_LIST, mne, "gain")
if ( type == 3 || type == 4) {
coeff = 9 - gain
val *= exp10(coeff)
} else if(type == 6 || type == 7) {
coeff = (6 + gain) * -1
val *= exp10(coeff)
} else {
val /= exp10(gain)
val *= exp10(9)
val /= 2.0
}
# 258199 = overflow
if (ESRF_ERR == 0 || ESRF_ERR == 258199) {
if (type != 2 && type != 5) {
ELM_AVER[ell] += val
ELM_NOREADS[ell]++;
}
}
if (type == 2 || type == 5) {
ELM_AVER[ell] == val;
ELM_NOREADS[ell] == 1;
}
}
}'
#%UU%
#%MDESC%
# For interactive use
#
def elmeterfix '{
global ELM_FIXED
printf("Electrometer gains were ")
tty_cntl("md")
printf("%s", ELM_FIXED?"Fixed":"Not fixed")
tty_cntl("me")
printf(". Now they are ")
if (ELM_FIXED) {
ELM_FIXED=0
} else {
ELM_FIXED=1
}
tty_cntl("md")
printf("%s\n", ELM_FIXED?"Fixed":"Not fixed")
tty_cntl("me")
}'
#%IU%
#%MDESC%
# For interactive use
#
def elmetergain '{
if ($# == 2) {
elmeter_set("$1", $2)
} else if ($# == 1) {
local gain mne, type
mne = cnt_mne($1)
type = list_getpar(ELM_LIST, mne, "type")
gain = list_getpar(ELM_LIST, mne, "gain")
if (type == 5) {
gain = _wago_elmeter_read(mne)
}
print "Elmeter gain for counter", mne, "is", gain
} else
elmetershow
}'
#%IU%
#%MDESC%
#
def elmeter_set(mne, gain) '{
printf("counter %s: gain -> %d\n", mne, gain)
local k el_old dcaccess
local type gmin gmax reldev relroot relfst
# print " <ELMETER> Setting gain on " cnt_mne(mne) " to " gain
type = list_getpar(ELM_LIST, mne, "type")
if (type == 3 || type == 4) {
gain1 = list_getpar(ELM_LIST, mne, "gain1")
gain2 = list_getpar(ELM_LIST, mne, "gain2")
gain3 = list_getpar(ELM_LIST, mne, "gain3")
} else {
gmin = list_getpar(ELM_LIST, mne, "gmin")
}
relroot = reldev = list_getpar(ELM_LIST, mne, "reldev")
relfst = list_getpar(ELM_LIST, mne, "relfirst")
if ( type == 0) {
setval = gmin - gain + 7
for (k=0;k<3;k++) {
reldev = sprintf("%s/%.2d", relroot, relfst+k)
esrf_io(reldev , setval&(1<<k)?"DevClose":"DevOpen")
}
}
if (type == 1 || type == 2) {
setval = gmin - gain + 2
for (k=0;k<3;k++) {
reldev = sprintf("%s/%.2d", relroot, relfst+k)
esrf_io(reldev, (setval == k)?"DevClose":"DevOpen")
}
} else if ( type == 3 || type == 4) {
if ( gain == gain1 ) {
setval = 0
} else if ( gain == gain2 ) {
setval = 1
} else if ( gain == gain3 ) {
setval = 2
} else {
print " Wrong gain for type 3"
print " Only values " gain1", " gain2 " and " gain3 " are allowed."
notok=1
}
if (!notok) {
for (k=0;k<3;k++) {
if (type == 4)
reldev = sprintf("%s%.2d", relroot, relfst+k)
else
reldev = sprintf("%s/%.2d", relroot, relfst+k)
esrf_io(reldev, (setval == k)?"DevOpen":"DevClose")
}
}
} else if (type == 5 || type == 6 || type == 7) {
if ( gain >= 1 && gain <= 3 )
{
local x[]
x[0] = x[1] = x[2] = 0 # set all zero
x[3 - gain] = 1 # set the one element
__elmeterdebug "wago_writech:", mne, gain, x[0], x[1], x[2]
wago_writech(reldev, x)
}
else
eprint "Values for wago gain must be (1, 2 or 3)"
}
list_setpar(ELM_LIST, mne, "gain", gain)
dcaccess= list_getpar(ELM_LIST, mne, "dcaccess")
if (dcaccess) {
esrf_dc(dcaccess, "put", gain)
}
}'
def elmget '{
if ($#) {
elmeter_gainadj($1)
} else {
elmeter_gainadj(1)
}
}'
#%IU%
#%MDESC%
# Adjusts the gains for all electrometers
#
def elmeter_gainadj(ctime) '{
local i elmno
local mne
local k el_old
local type gmin gmax vmin vmax
local inloop
elmno = list_n(ELM_LIST)
#
# Now take care of type 2 electrometers
#
iter = 0
inloop = 1
while(inloop) {
iter++
#
# Count and wait for "ctime" seconds
#
count_em ctime
waitcount; ELM_UPDATING=1; get_counts
elm2no = 0
elmok = 0
for (i=0; i<elmno; i++) {
local num ctnorm
mne = list_item(ELM_LIST, i+1)
type = list_getpar(ELM_LIST, mne, "type")
if (type == 5) {
gain = _wago_elmeter_read(mne)
list_setpar(ELM_LIST, mne, "gain", gain)
}
if (type != 2 && type != 5) continue
vmin = list_getpar(ELM_LIST, mne, "vmin")
vmax = list_getpar(ELM_LIST, mne, "vmax")
gmin = list_getpar(ELM_LIST, mne, "gmin")
gain = list_getpar(ELM_LIST, mne, "gain")
gmax = gmin + 2
num = cnt_num(mne)
if ( num == -1 ) continue
elm2no++
ctnorm = S[num]/ctime
if ( fabs(ctnorm) < vmin ) {
if ( gain < gmax ) {
gain++
elmeter_set(mne , gain )
} else {
elmok++
}
} else if ( fabs(ctnorm) > vmax ) {
if ( gain > gmin ) {
gain--
elmeter_set( mne, gain )
} else {
elmok++
}
} else {
elmok++
}
}
if (elmok == elm2no) { inloop = 0 }
if (iter > 10) inloop = 0
}
}'
# this is an enigma. What`s that for? Reading the data collector and
# writing it into the array ?
def elmupdate '{
elmno = list_n(ELM_LIST)
for (i=0; i<elmno; i++) {
local num mne ctnorm
mne = list_item(ELM_LIST, i+1)
num = cnt_num(mne)
if (num == -1 || counter_par(num, "disable") == 1) continue
dcaccess= list_getpar(ELM_LIST, mne, "dcaccess")
if (dcaccess) {
gain = esrf_dc(dcaccess, "DevRead")
if (gain != -1 ) {
list_setpar(ELM_LIST, mne, "gain", gain)
}
}
}
}'
#%IU%
#%MDESC%
# Adjusts the gain for ONLY ONE electrometer
#
def elmetergainadj1 '{
local mne num ctime
local type gmin gmax vmin vmax ctnorm
local inloop iter
if ($# != 2) {
print "Usage: elmtergainadj1 elmeter-mnemonics counting-time-in-seconds"
exit
}
mne = "$1"
ctime = $2
num = cnt_num(mne)
if (num == -1) {
printf("Mnemonics %s does not correspond to any of electrometers\n", mne)
exit
}
# get electrometer type
type = list_getpar(ELM_LIST, mne, "type")
if ((type == 0) || (type == 1)) {
# for elmeters type 0 and 1 (read in ADC), all is done in
# elmeter_mread inside user_pollcounts and user_getcounts
count_em ctime
waitcount; get_counts
} else if (type == 2 || type == 5) {
iter = 0
inloop = 1
while(inloop) {
iter++
# Count and wait for "ctime" seconds
count_em ctime
waitcount
ELM_UPDATING=1
get_counts
vmin = list_getpar(ELM_LIST, mne, "vmin")
vmax = list_getpar(ELM_LIST, mne, "vmax")
gmin = list_getpar(ELM_LIST, mne, "gmin")
gain = list_getpar(ELM_LIST, mne, "gain")
if (type == 5) {
gain = _wago_elmeter_read(mne)
list_setpar(ELM_LIST, mne, "gain", gain)
}
gmax = gmin + 2
ctnorm = S[num]/ctime
if ( fabs(ctnorm) < vmin ) {
if ( gain < gmax ) {
gain++
elmeter_set( mne , gain )
} else {
inloop = 0
}
} else if ( fabs(ctnorm) > vmax ) {
if ( gain > gmin ) {
gain--
elmeter_set( mne, gain )
} else {
inloop = 0
}
} else {
inloop = 0
}
if (iter > 10) inloop = 0
} # end of while loop
} else {
print "Unkown type of electrometer"
exit
} # end of cases over elmeter types
}'
#%IU% (mne)
#%MDESC% Read the appropriate adc device.
def _adc_read(mne) '{
local adcdev chan val adc_data adctype key
chan = list_getpar(ELM_LIST, mne, "channel")
adcdev = list_getpar(ELM_LIST, mne, "adcdev")
adctype = list_getpar(ELM_LIST, mne, "type")
if (adctype == 1) {
val = esrf_io(adcdev, "DevReadChannel", chan)
} else if (adctype == 2){
val = esrf_io(adcdev, "DevReadValue")
} else if ((adctype == 4) || (adctype == 6)) {
val = esrf_io(adcdev, "DevReadSigValues", adc_data)
if (val > 0)
val = adc_data[chan]
} else {
if(adctype == 7)
{
local id
id = esrf_io(adcdev, "DevName2Key", chan)
chan = id
}
val = esrf_io(adcdev, "DevReadNoCachePhys", chan, adc_data)
if(val == 1) {
val = adc_data[0]
}
}
return (val)
}'
#%IU% (mne)
#%MDESC% Read the appropriate adc device.
def _wago_elmeter_read(mne) '{
local tmpgainNow, type, reldev, j, x[]
type = list_getpar(ELM_LIST, ELM_LIST[mne], "type")
reldev = list_getpar(ELM_LIST, ELM_LIST[mne], "reldev")
tmpgainNow = 0
wago_readch(reldev, x)
for (j = 0; j < 3; j++) {
tmpgainNow += x[2 - j]? j+1: 0
}
return tmpgainNow
}
'
#%MACROS%
#%IMACROS%
#%AUTHOR% V. Rey to start, H. Witsch recently
# ELMETER.MAC - ICNTL - 10/96
#$Revision: 2.17 $, $Date: 2017/03/09 15:18:09 $
#%TOC%
|