#%NAME% LOCKIN.MAC - Stanford Research SR830 Lockin-Amplifier
#%DESCRIPTION%
# These macros allow you to read out the Stanford Research SR830
# Lockin-Amplifier via GPIB interface and to define its two channels
# as "software counters".
#%SETUP%
# Configure SPEC for GPIB:
# Make sure that the GPIB-ENET software is correctly installed.
# Run the diagnostics program "/usr/bin/ibtsta". %BR%
# In "config", press "c" to go to the "Interface Configuration" menu.
# Under GPIB enter "y" for YES. Under TYPE press "+" and choose
# "Nat Inst GPIB-ENET (shared)" for the menu. DEVICE should be "gpib0".
# After saving with "w" and exiting with "Control-C" you shoud se the message
# "Using National Instruments GPIB."
# %BR%
# Define a new counter in "config". Type "c" until you to get to the
# "Scaler (Counter) Configuration" menu. Increment "Number of counters" by 1
# and rename "counter n" by "adc1". "Device" should be NONE, "Unit" and
# "Chan" 0, "Ase As" should be "counter" and "Scale factor" 1.
# %BR%
# After exiting the "config" editor type "setup" and include into your setup
# file a line like the following:
#%PRE%
# lockin_define gpib=8 channel=1 adc1
#%PRE%
# The factory preset GPIB address is 8. You can chage it via the SETUP button
# on the front panel.
#%UU% gpib=n channel=1|2 counter
#%MDESC% associates a SPEC counter mnemonic to one of the channels channels
# A or B of the ADC module.
# %BR%
# Use this macro in your "setup" file.
def lockin_define '{
global LOCKIN_PAR[]
local usage aux1 aux2 address average
local cnts ncnts tcnts[] ii radix
local lockin_cnt[] mne
LOCKIN_PAR[1] = "X"
LOCKIN_PAR[2] = "Y"
LOCKIN_PAR[3] = "R"
LOCKIN_PAR[4] = "th"
LOCKIN_PAR[5] = "in1"
LOCKIN_PAR[6] = "in2"
LOCKIN_PAR[7] = "in3"
LOCKIN_PAR[8] = "in4"
LOCKIN_PAR[9] = "freq"
LOCKIN_PAR[10] = "tr1"
LOCKIN_PAR[11] = "tr2"
LOCKIN_PAR[12] = "tr3"
LOCKIN_PAR[13] = "tr4"
aux1 = "usage: $0 gpib=n average=yes|no counters=i,j.. cnt_radix"
aux2 = "\"counters\" parameter is a list of integer separated by coma (see manual p. 6-23)"
usage = sprintf("%s\n\n%s\n", aux1, aux2)
if ($# != 4) { print usage; exit }
if (sscanf("$1","gpib=%s",address) != 1) { print usage; exit }
if (sscanf("$2","average=%s",average) != 1) { print usage; exit }
if (sscanf("$3","counters=%s",cnts) != 1) { print usage; exit }
if (! (average == "yes" || average == "no")) { print usage; exit }
radix = "$4"
ncnts = split(cnts,tcnts,",")
for (ii=0 ; ii<ncnts ; ii++) {
if ((tcnts[ii] < 1) && (tcnts[ii] > 13)) {
print usage
exit
} else {
mne = sprintf("%s_%s", radix, LOCKIN_PAR[tcnts[ii]])
if (cnt_num(mne) == -1) {
printf("$0: Define \"%s\" as a counter in \"config\"\n",mne)
exit
}
lockin_cnt[ii]["index"] = tcnts[ii]
lockin_cnt[ii]["mne"] = mne
}
}
lockin_delcnt
LOCKIN_PAR["address"] = address
LOCKIN_PAR["average"] = average
LOCKIN_PAR["counters"] = cnts
LOCKIN_PAR["ncnt"] = ncnts
for (ii=0 ; ii<LOCKIN_PAR["ncnt"] ; ii++) {
LOCKIN_PAR[ii]["index"] = lockin_cnt[ii]["index"]
LOCKIN_PAR[ii]["mne"] = lockin_cnt[ii]["mne"]
LOCKIN_PAR[ii]["value"] = 0
LOCKIN_PAR[ii]["count"] = 0
}
}'
#%UU%
#%MDESC% clear lockin parameter structure
def lockin_delcnt '{
local ii
for (ii=0 ; ii<LOCKIN_PAR["ncnt"] ; ii++) {
delete LOCKIN_PAR[ii]["index"]
delete LOCKIN_PAR[ii]["mne"]
delete LOCKIN_PAR[ii]["value"]
delete LOCKIN_PAR[ii]["count"]
}
LOCKIN_PAR["ncnt"] = 0
}'
#%UU%
#%MDESC% print status info
def lockin_info '{
local ii c disabled
if (LOCKIN_PAR["ncnt"] != 0)
print "\nStanford Research SR830 lock-in amplifier\n\n"
else
print "no lock-in amplifier software counters are currently defined"
printf("GPIB address : %s\n", LOCKIN_PAR["address"])
printf("COUNTERS :\n")
for (ii=0 ; ii<LOCKIN_PAR["ncnt"] ; ii++) {
c = cnt_num(LOCKIN_PAR[ii]["mne"])
disabled = counter_par(c,"disable")
printf(" \"%s\" %s\n", LOCKIN_PAR[ii]["mne"], disabled?"(disabled)":"")
}
}'
#%IU% counter
#%MDESC% Hook macro for "reconfig"
#%BR%
#checks whether device is accessible on the GPIB bus and clears the error
# status, if necessary.
def lockin_check '{
local c address HDW_ERR n
address = LOCKIN_PAR["address"]
if (address) {
HDW_ERR = -1 # do not abort macro on hardware error
n = gpib_put(address,"\r")
# With a shared GPIB-ENET the error condition "Not CIC or lost CIC during
# command" occurs frequently. In this case the error code is 4 (=transient).
if (HDW_ERR == 4) {
HDW_ERR = -1
n = gpib_put(address,"\r")
}
if (n > 0) {
delete LOCKIN_PAR["error"]
} else {
LOCKIN_PAR["error"] = 1
printf("RS850 Lock-In Amplifier (GPIB=%d) is unusable.", address)
for (ii=0 ; ii<LOCKIN_PAR["ncnt"] ; ii++) {
c = cnt_num(LOCKIN_PAR[ii]["mne"])
if (c != -1) {
S[c] = 0
counter_par(c,"disable",1)
}
}
}
}
}'
#%UU%
#%MDESC% undo "lockin_define"
def lockin_undefine '{
local ii c
cdef ("","","lockin","delete")
for (ii=0 ; ii<LOCKIN_PAR["ncnt"] ; ii++) {
c = cnt_num(LOCKIN_PAR[ii]["mne"])
if (c != -1) {
S[c] = 0
counter_par(c,"disable",1)
}
}
unglobal LOCKIN_PAR
}'
#%UU%
#%MDESC% disable all Lock-in amplifier software counters
def lockin_off '{
local ii c
cdef ("","","lockin","delete")
for (ii=0 ; ii<LOCKIN_PAR["ncnt"] ; ii++) {
c = cnt_num(LOCKIN_PAR[ii]["mne"])
if (c != -1) {
S[c] = 0
counter_par(c,"disable",1)
}
}
}'
#%UU%
#%MDESC% undo "lockin_off" - re-enable all Lock-in amplifier software counters
def lockin_on '{
local ii c
cdef("user_getpangles", "lockin_getpangles\n", "lockin")
cdef("user_checkall", "lockin_checkall\n", "lockin")
cdef("user_precount", "lockin_precount\n", "lockin")
cdef("user_getcounts", "lockin_getcounts\n", "lockin")
cdef("user_pollcounts", "lockin_getcounts\n", "lockin")
cdef("config_mac","lockin_check\n","lockin")
for (ii=0 ; ii<LOCKIN_PAR["ncnt"] ; ii++) {
c = cnt_num(LOCKIN_PAR[ii]["mne"])
if (c != -1)
counter_par(c,"disable",0)
}
}'
#%IU%
#%MDESC% hook macro for "user_getpangles"
def lockin_getpangles '{
local n
local motnum
motnum = motor_num("lkf")
if (motnum >= 0){
n=gpib_put(LOCKIN_PAR["address"], "freq ?\n")
A[motnum]= gpib_get(LOCKIN_PAR["address"])
}
motnum = motor_num("lkp")
if (motnum >= 0){
n=gpib_put(LOCKIN_PAR["address"], "phas ?\n")
A[motnum]= gpib_get(LOCKIN_PAR["address"])
}
motnum = motor_num("lks")
if (motnum >= 0){
n=gpib_put(LOCKIN_PAR["address"], "sens ?\n")
A[motnum]= gpib_get(LOCKIN_PAR["address"])
}
motnum = motor_num("lko")
if (motnum >= 0){
n=gpib_put(LOCKIN_PAR["address"], "oflt ?\n")
A[motnum]= gpib_get(LOCKIN_PAR["address"])
}
motnum = motor_num("lka")
if (motnum >= 0){
n=gpib_put(LOCKIN_PAR["address"], "slvl ?\n")
A[motnum]= gpib_get(LOCKIN_PAR["address"])
}
}'
#%IU%
#%MDESC% hook macro for "user_checkall"
def lockin_checkall '{
local n
local motnum
motnum = motor_num("lkf")
if (motnum >= 0){
n=gpib_put(LOCKIN_PAR["address"], sprintf("freq %.3f\n", A[motnum]))
}
motnum = motor_num("lkp")
if (motnum >= 0){
n=gpib_put(LOCKIN_PAR["address"], sprintf("phas %.4f\n", A[motnum]))
}
motnum = motor_num("lks")
if (motnum >= 0){
n=gpib_put(LOCKIN_PAR["address"], sprintf("sens %d\n", A[motnum]))
}
motnum = motor_num("lko")
if (motnum >= 0){
n=gpib_put(LOCKIN_PAR["address"], sprintf("oflt %d\n", A[motnum]))
}
motnum = motor_num("lka")
if (motnum >= 0){
n=gpib_put(LOCKIN_PAR["address"], sprintf("slvl %.4f\n", A[motnum]))
}
}'
#%IU% counter
#%MDESC% hook macro for "user_precount" ,
# called implicitly when you use "ct", "count" or a scan macro.
# Initialize Reads the lock-in amplifier output via GPIB. %BR%
def lockin_precount '{
local ii
if (LOCKIN_PAR["average"] == "yes") {
for (ii=0 ; ii<LOCKIN_PAR["ncnt"] ; ii++) {
LOCKIN_PAR[ii]["value"] = 0
LOCKIN_PAR[ii]["count"] = 0
}
}
}'
#%IU% counter
#%MDESC% hook macro for "user_getcounts" ,
# called implicitly when you use "ct", "count" or a scan macro.
# Reads the lock-in amplifier output via GPIB. %BR%
# The result is stored in the global array S in S[counter].
def lockin_getcounts '{
local comm aux ii mne n tval[] val
if (!LOCKIN_PAR["error"]) {
for (ii=0 ; ii<LOCKIN_PAR["ncnt"] ; ii++) {
comm = sprintf("OUTP?%d", LOCKIN_PAR[ii]["index"])
val = lockin_read(comm)
if (isNaN(val))
val = 0
mne = cnt_num(LOCKIN_PAR[ii]["mne"])
val *= counter_par(mne,"scale")
if (LOCKIN_PAR["average"] == "yes") {
LOCKIN_PAR[ii]["value"] += val
LOCKIN_PAR[ii]["count"] += 1
if (LOCKIN_PAR[ii]["count"] != 0)
S[mne] = LOCKIN_PAR[ii]["value"] / LOCKIN_PAR[ii]["count"]
} else {
S[mne] = val
}
}
}
}'
#%IU% (gpib_address,channel)
#%MDESC% Reads the lock-in amplifier output via GPIB and returns the result.
# Channel can be "A" or "B".
# Which parameter is read (X,Y,R,theta) is detemined by the front panel settings.
# The result can be a voltage in units of V, a current in units of A or a phase
# in deg.
# If an error occurrs NaN (not a number) is returned.
def lockin_read(comm) '{
local HDW_ERR query n ret
HDW_ERR = -1 # do not reset to command prompt on error
query = sprintf("%s\n", comm)
n = gpib_put(LOCKIN_PAR["address"],query)
# With a shared GPIB-ENET the error condidtion "Not CIC or lost CIC during
# command" occurs frequently. In this case try again.
if (HDW_ERR == 4 )
n = gpib_put(LOCKIN_PAR["address"],query)
if (n == -1)
return(NaN)
ret = gpib_get(LOCKIN_PAR["address"])
if (ret == "")
return(NaN)
delete LOCKIN_PAR["error"]
return(ret)
}'
#%IU% %MDESC% "Not a Number" - placeholder for invalid numeric value
def NaN '(1e1000/1e1000)'
#%IU% (x)
#%MDESC% check whether x is an ivalid numeric value, "Not a Number"
def isNaN(x) '{return(x+1e1000==x)}'
def lockin_talk '{
local comm addr n query ret
if ($# != 2) {
p "Usage : lockin_talk [GPIB addr] [command]"
exit
}
addr = "$1"
comm = "$2"
query = sprintf("%s\n", comm)
n = gpib_put(addr,query)
printf("Send command .. : %s\n",comm)
if (index(comm, "?") != 0) {
ret = gpib_get(addr)
printf("Return value . : %s\n", ret)
}
}'
def lockin_scan_on '{
cdef("measure0", "lockin_scan_start\n", "lockin_scan")
cdef("measure1", "lockin_scan_read\n", "lockin_scan")
}'
def lockin_scan_off '{
cdef("", "", "lockin_scan", "delete")
}'
def lockin_scan_setup '{
local addr
if ($# != 3) {
p "Usage : lockin_scan_setup [scan time] [sample time] [sleep time]"
exit
}
LOCKIN_PAR["time"] = $1
LOCKIN_PAR["sample"] = $2
LOCKIN_PAR["wait_time"] = $3
addr = LOCKIN_PAR["address"]
gpib_put(addr, sprintf("SLEN%d\n", LOCKIN_PAR["time"]))
gpib_put(addr, sprintf("SRAT%d\n", LOCKIN_PAR["sample"]))
gpib_put(addr, "SEND0\n")
}'
def lockin_getparam '{
local addr res_str fname
ct
getE
temp=hc_over_e/LAMBDA
addr = LOCKIN_PAR["address"]
fname = sprintf("%s.lockin", DATAFILE)
res_str = "#PAR "
res_str = sprintf("%sI0=%g ", res_str, S[37])
res_str = sprintf("%sNRJ=%g ", res_str, temp)
open(fname)
fprintf(fname, "\n%s", res_str)
close(fname)
res_str = "#PAR "
gpib_put(addr, "IGAN?\n")
res_str = sprintf("%sIGAN=%g ", res_str, gpib_get(addr))
gpib_put(addr, "ICPL?\n")
res_str = sprintf("%sICPL=%g ", res_str, gpib_get(addr))
gpib_put(addr, "FMOD?\n")
res_str = sprintf("%sFMOD=%g ", res_str, gpib_get(addr))
gpib_put(addr, "FREQ?\n")
res_str = sprintf("%sFREQ=%g ", res_str, gpib_get(addr))
gpib_put(addr, "RSLP?\n")
res_str = sprintf("%sRSLP=%g ", res_str, gpib_get(addr))
gpib_put(addr, "SLVL?\n")
res_str = sprintf("%sSLVL=%g ", res_str, gpib_get(addr))
open(fname)
fprintf(fname, "\n%s\n", res_str)
close(fname)
res_str = "#PAR "
gpib_put(addr, "SENS?\n")
res_str = sprintf("%sSENS=%g ", res_str, gpib_get(addr))
gpib_put(addr, "RSRV?\n")
res_str = sprintf("%sRSRV=%g ", res_str, gpib_get(addr))
gpib_put(addr, "OFLT?\n")
res_str = sprintf("%sOFLT=%g ", res_str, gpib_get(addr))
gpib_put(addr, "OFSL?\n")
res_str = sprintf("%sOFSL=%g ", res_str, gpib_get(addr))
open(fname)
fprintf(fname, "%s\n", res_str)
close(fname)
}'
def lockin_scan '{
local fname
#$#
if ($# == 2) {
mne = "$1"
ct_time = $2
if (cnt_num(mne) == -1) {
printf("Counter \"%s\" not define, exit !!!\n")
exit
}
}
# lockin_getparam
if ($# == 2) {
waitcount ; get_counts
count_em ct_time
waitcount ; get_counts
fname = sprintf("%s.lockin", DATAFILE)
open(fname)
fprintf(fname, "\n#I0 %s=%g time=%g\n", mne, S[cnt_num(mne)], ct_time)
close(fname)
}
lockin_scan_start
lockin_scan_read
if ($# == 2) {
waitcount ; get_counts
count_em ct_time
waitcount ; get_counts
fname = sprintf("%s.lockin", DATAFILE)
open(fname)
fprintf(fname, "\n#I0 %s=%g time=%g\n", mne, S[cnt_num(mne)], ct_time)
close(fname)
}
}'
def lockin_scan_start '{
local addr
addr = LOCKIN_PAR["address"]
LOCKIN_PAR["start_time"] = time()
gpib_put(addr, "REST\n")
gpib_put(addr, "STRT\n")
}'
def lockin_scan_read '{
local sleep_time nbp str_aux stp beg rep_str[] parnum ii fname
local par1[] par2[] par3[] par4[]
fname = sprintf("%s.lockin", DATAFILE)
open(fname)
fprintf(fname, "\n#S %d\n", ++LOCKIN_PAR["SCAN_N"])
fprintf(fname, "#ASPEC %d %d\n", SCAN_N, NPTS)
fprintf(fname, "#PAR SCAN_TIME=%g SAMPLE_RATE=%d POLARIZATION=%g",\
LOCKIN_PAR["time"], LOCKIN_PAR["sample"], \
_nhq204m_get())
close(fname)
lockin_getparam
open(fname)
sleep_time = LOCKIN_PAR["time"] \
- (time()-LOCKIN_PAR["start_time"]) \
+ LOCKIN_PAR["wait_time"]
if(sleep_time>0)
sleep(sleep_time)
addr = LOCKIN_PAR["address"]
gpib_put(addr, "SPTS?1\n")
nbp = gpib_get(addr)
fprintf(fname, "#P %d\n", nbp)
fprintf(fname, "#C X Y R Theta\n")
for (parnum=1 ; parnum<=4 ; parnum++) {
for(rep_str[parnum]="",stp=30,beg=0,i=int(nbp/stp)+1 ; i ; i--) {
gpib_put(addr, sprintf("TRCA?%d,%d,%d", parnum, beg,(i!=1)?stp:(nbp%stp)))
str_aux = gpib_get(addr)
if (substr(str_aux, length(str_aux), 1) == ",\n") {
print "ERROR: unable to get "stp" values from LOCKIN"
print "giving up (hint: try to request less values)"
exit
}
rep_str[parnum] = sprintf("%s%s", rep_str[parnum], str_aux)
beg+=stp
}
}
split(rep_str[1], par1, ",")
split(rep_str[2], par2, ",")
split(rep_str[3], par3, ",")
split(rep_str[4], par4, ",")
for (ii=0 ; ii<nbp ; ii++)
fprintf(fname, "%g %g %g %g\n", par1[ii], par2[ii], par3[ii], par4[ii])
close(fname)
}'
#%MACROS% %IMACROS%
#%INTERNALS%
# The following GPIB command is used:
#%DL%
#%DT% OUTR?i
#%DD% Read the value of the CH1 or CH2 display. The parameter i selects the
# display (i=1 or 2). Values are returned as ASCII floating point numbers
# with units of the display.
#%XDL%
#%BR%
#%AUTHOR% Friedrich Schotte, 29 Mar 2000
|