#%TITLE% par263cyc1.mac $Revision: 1.2 $
#%NAME%
# Princeton Applied Research Potentiostat/Galvanostat model 263A and
# model VersaStatII 2532
#%DESCRIPTION%
# macro written by Frederik Golks (ID32) (18/02/2009) %BR%
# based on macro by Manuel Perez %BR%
# what it should do: %BR%
# 1.) take CVs with n cycles %BR%
# 2.) print the CV during the measurement to the screen %BR%
# 3.) safe the CV(s) afterwards to file %BR%
# 4.) keep final potential (same as starting potential) %BR%
#
#%SETUP%
#%END%
#
#%HISTORY%
#$Log: par263cyc1.mac,v $
#Revision 1.2 2012/05/14 15:03:17 claustre
#par263cycle now save data into SPECFILE
#
# modified 10/03/2009: include setE corrected CV %BR%
# modified 11/03/2009: calculate current, plot/print current vs. potential (not cts any more) %BR%
# modified 12/03/2009: include IGAIN %BR%
#
#%END%
#%IU%
#%MDESC%
def _par263cyc_plot(n,current_ranget,igaint) '{
local short array x[n]
local short array y[n]
local short array dat[2][n]
local array datnew[1][n]
local n_curve n_rd
if(n>=3072){
_par263_print(sprintf("%d higher than max 1024 allowed points",n), 1)
exit
}
#Set current range (ugly solution), Geert
if(current_ranget==-1) current_ranget=100000
if(current_ranget==-2) current_ranget=10000
if(current_ranget==-3) current_ranget=1000
if(current_ranget==-4) current_ranget=100
if(current_ranget==-5) current_ranget=10
if(current_ranget==-6) current_ranget=1
# Get I values (i.e. y axis)
_par263_write(sprintf("BD 0 %d",n))
n_rd = gpib_get(PAR263_ADDR,dat[1])
if(n != n_rd) _par263_print("Error reading I values", 1);
# Get U values (i.e. x axis)
n_curve=1024*(int((n)/1024)+1)
_par263_write(sprintf("BD %d %d",n_curve,n))
n_rd = gpib_get(PAR263_ADDR,dat[0])
if(n != n_rd) _par263_print("Error reading U values", 1);
array_op("swap",dat)
datnew=(-1*dat[1]*current_ranget/igaint)
# init plotting device & plot
plot_cntl("filter1,open")
plot_cntl("erase")
plot_cntl("lines")
plot_range("auto","auto","auto","auto")
plot_move(0,0,sprintf("CV I [nA] / E [mV], %d points",n))
array_plot(dat[0][1:n-1],datnew[1:n-1])
}'
#%IU%
#%MDESC%
def _par263cyc_print(n,filena,cmd,init_pott,down_pott,up_pott,slopet,e_stept,current_ranget,igaint, cycles, cycle_num) '{
local short array x[n]
local short array y[n]
local short array dat[2][n]
local n_curve n_rd cmd
local array datnew[1][n]
#Set current range (ugly solution), Geert
if(current_ranget==-1) current_ranget=100000
else if(current_ranget==-2) current_ranget=10000
else if(current_ranget==-3) current_ranget=1000
else if(current_ranget==-4) current_ranget=100
else if(current_ranget==-5) current_ranget=10
else if(current_ranget==-6) current_ranget=1
# Get I values (i.e. y axis)
_par263_write(sprintf("BD 0 %d",n))
n_rd = gpib_get(PAR263_ADDR,dat[1])
if(n != n_rd) _par263_print("Error reading I values", 1);
# Get U values (i.e. x axis)
n_curve=1024*(int((n)/1024)+1)
_par263_write(sprintf("BD %d %d",n_curve,n))
n_rd = gpib_get(PAR263_ADDR,dat[0])
if(n != n_rd) _par263_print("Error reading U values", 1);
array_op("swap",dat)
datnew=-1*dat[1]*current_ranget/igaint #/1000 due to range of potentiostat, *1000 due to avoiding floating data (so current in nA
# init plotting device & plot
plot_cntl("filter1,open")
plot_cntl("erase")
plot_cntl("lines")
plot_range("auto","auto","auto","auto")
plot_move(0,0,sprintf("CV I [nA] / E [mV], %d points",n))
array_plot(dat[0][1:n-1],datnew[1:n-1])
# init saving procedure
#if(filena==0){
# filena=getval("File name to dump I/E",cmd)} # for case of 1 cycle, ask for filename
#on(filena);offt
#print("#################################################\n# DATE " date())
cmd = sprintf("par263cyc %d %d %d %d %d %d %d", init_pott, down_pott, up_pott, slopet, e_stept, cycles, current_ranget)
fprintf(DATAFILE,"\n#S %d %s\n#D %s\n",++SCAN_N,cmd,date())
fprintf(DATAFILE, "#C cycle number = %d\n", cycle_num)
fprintf(DATAFILE, "#C start pot %d mV, V1 %d mV, V2 %d mV, slope %d mV/s, step width %d mV/step, current range %d uA, IGAIN %d\n", init_pott, down_pott, up_pott, slopet, e_stept, current_ranget,igaint)
fprintf(DATAFILE, "#L U/mV I/cts I/nA\n")
array_dump(DATAFILE, dat,datnew)
close(DATAFILE)
}'
#%UU%
#%MDESC%
def par263cyc '{
local init_pot up_pot final_pot down_pot slope ppsec
local init_dac up_dac final_dac down_dac tmb
local mr mr_cmd cmd
local n1 n2 n3 points
local filena
local filemode __i
if($# != 7) {
p "Usage: $0 init_pot down_pot up_pot slope e_steps cycles current_range"
p " potentials are in mV"
p " slope in mV/second"
p " number of cycles"
p " current range [-1: 100 mA"
p " -2: 10 mA"
p " -3: 1 mA"
p " -4: 100 muA"
p " -5: 10 muA"
p " -6: 1 muA"
p " -7: 100 nA]"
exit
}
# Set MODULATION RESOLUTION to 2.5muV per count
# mr = 0.0025 ; mr_cmd = 0
# Set MODULATION RESOLUTION to 25muV per count
# mr = 0.025 ; mr_cmd = 1
# Set MODULATION RESOLUTION to 250muV per count
mr = 0.250 ; mr_cmd = 2
init_pot = $1
down_pot = $2
up_pot = $3
slope = $4
e_step = $5
cycles = $6
current_range = $7
ppsec = slope/(e_step)
spp = 1
final_pot = init_pot
if(ppsec<20) {
spp = 20/ppsec }
p "\n**********************************"
p "starting potential = " init_pot
p "upper vertex = " up_pot
p "lower vertex = " down_pot
p "end potential = " final_pot
down_pot1=down_pot
up_pot1=up_pot
gpib_put(PAR263_ADDR,"READE")
tmp=gpib_get(PAR263_ADDR)
sleep(0.1)
p "setE currently = " tmp
if(tmp!=0){
init_pot=init_pot-tmp
down_pot=down_pot-tmp
up_pot=up_pot-tmp
final_pot=init_pot
}
gpib_put(PAR263_ADDR,"IGAIN")
igain=gpib_get(PAR263_ADDR)
sleep(0.1)
if(cycles==0){exit}
#cmd_name=sprintf("CV-%s-%d-%d-%d.dat",time(),down_pot1,up_pot1,slope)
if(cycles!=1){
#check if there is a valid DATAFILE
if (index(DATAFILE,"null")==0){
_par263_print(sprintf("data will be dumped to SPECFILE: %s", DATAFILE))
}else {
_par263_print("SPECFILE is null, please set it using \"newfile\"", 1)
exit
}
filena = DATAFILE
}
else{filena=0}
init_dac = int(init_pot/mr)
down_dac = int(down_pot/mr)
up_dac = int(up_pot/mr)
final_dac = int(final_pot/mr)
tmb = int(1000000/(ppsec*spp))
if((init_dac>8000) || (init_dac<-8000)) {
_par263_print( \
sprintf("init_pot %dmV out of range +/-%dmV",init_pot,8000*mr), 1)
exit
}
if((up_dac>8000) || (up_dac<-8000)) {
_par263_print(sprintf("up_pot %dmV out of range +/-%dmV",up_pot,8000*mr), 1)
exit
}
if((down_dac>8000) || (down_dac<-8000)) {
_par263_print( \
sprintf("down_pot %dmV out of range +/-%dmV",down_pot,8000*mr), 1)
exit
}
if((slope>200) || (slope<1)) {
_par263_print(sprintf("slope %dmV/s out of range [1,200]",slope), 1)
exit
}
if((tmb>50000) || (tmb<400)) {
_par263_print(sprintf("ppsec %d out of range [20,2500]",ppsec), 1)
exit
}
# calculate the number of points of each slope
n1=int(fabs(down_pot - init_pot)*(ppsec)/slope)
n2=int(fabs(up_pot - down_pot)*(ppsec)/slope) + n1
n3=int(fabs(up_pot - final_pot)*(ppsec)/slope) + n2
p "total \# points = " n3
# the number of points is fixed to 3072
points=n3
if(points>=3072) {
_par263_print( \
sprintf("too many points, decrease either E_step or increase slope",ppsec), 1)
_par263_print(sprintf("n1=%d n2=%d n3=%d\n",n1,n2,n3), 1)
exit
}
# Initializing Potentiostat
_par263_write("27")
#_par263_write("DCL") # No Default Parameters, since otherwise set E to 0 at beginning
_par263_write("FLT 65") # Filter 65, means filter on I, but not on E (check manual for more details...
_par263_write("SIE 3") # Record I and E in parallel
_par263_write("AR 0") # Auto range off for I and E, AR makes problems for low currents...
_par263_write("DCV 0") # The destination CURVE is the 1st one
_par263_write("PAM 0") # no averaging spp
cmd=sprintf("S/P %d",spp)
_par263_write(cmd) # set samples per point
_par263_write("MM 1") # Ramp modulation on (so using INITIAL and VERTEX)
_par263_write("INTRP 1") # interpolation on (regarding samples per point)
cmd=sprintf("I/E %d",current_range)
_par263_write(cmd) # Set CURRENT TO VOLTAGE CONVERTER (as specified in input)
cmd=sprintf("MR %d",mr_cmd)
_par263_write(cmd) # Set MODULATION RESOLUTION to 250muV per count
cmd=sprintf("TMB %d",tmb)
_par263_write(cmd) # Timeresolution
cmd=sprintf("LP %d",points)
_par263_write(cmd) # points=n3=total number of data points to get
# setting up experiment
cmd=sprintf("INITIAL 0 %d",init_dac)
_par263_write(cmd) # set E to E_0 @ point 0
cmd=sprintf("VERTEX %d %d",n1,down_dac)
_par263_write(cmd)
cmd=sprintf("VERTEX %d %d",n2,up_dac)
_par263_write(cmd)
cmd=sprintf("VERTEX %d %d",n3,final_dac)
_par263_write(cmd)
# Switch on the E on the CELL, if not already on
_par263_write("CELL 1")
_par263_write("P 1") #Pause for 1 sec
# setting cycling loop
for(__i=0;__i<cycles;__i++){
_par263_write("NC")
# Take curve
_par263_write("TC")
# Wait for the end of TC i.e. commands not treated
p "\nWaiting curve to finish\t cycle "(__i+1)
p "**********************************"
while (_par263_waitcurve()) {
printf("Data point: %d\t",PAR263_READ["lp"])
printf("Current: ")
_par263cyc_plot(points,current_range,igain)
if (input(-1)=="q"){
_par263_write("HC")
SET=sprintf("SETE %d",tmp)
_par263_write("NC")
_par263_write(SET)
printf("CV aborted")
exit
}
}
_par263cyc_print(points,filena,cmd_name,init_pot,down_pot,up_pot,slope,e_step,current_range,igain,cycles,__i)
}
#gpib_put(PAR263_ADDR,"READE")
#tmp=gpib_get(PAR263_ADDR)
sleep(0.5)
SET=sprintf("SETE %d",tmp)
_par263_write(SET)
#added by Francesco 2011-08-19:
_par263_write("MM 0") # set modulation off. If the MM is not set to 0 the ct command in the spec session will set the potential to an undesired value.
}'
|