% Use the HP 4284A to generate a CV curve
clear all
Vbstart = -2;         %V
Vbstop = 0.8;        %V
Vbstep = 0.01;       %V
mag = 0.005;            %V - magnitude of sine wave (.005 = min)
freq = 0.01;           %MHz - frequency - maximum is 1MHz
pse = 0.0;         %How long to pause in between points (sec)
Vvec_up = Vbstart:Vbstep:Vbstop;
Vvec_down = Vbstop:-Vbstep:Vbstart;
meterGPIB = 27;

%initialize LCR meter
meter=gpib('ni', 0, meterGPIB);
fopen(meter);
fprintf(meter, '*RST; *CLS')    %resets and clears state
fprintf(meter, 'FORM ASCII')    %set output format to ASCII text
fprintf(meter, 'TRIG:SOUR BUS') %set trigger source to GPIB (HPIB) bus
fprintf(meter, 'ABORT; :INIT')  %stop whatever it's doing and start new measurement
fprintf(meter, 'FUNC:IMP CSD')  %set measurement mode to Cparallel/D (p. 264 of manual)
if freq>=1
    fprintf(meter, 'FREQ %dMHZ', freq)
elseif freq>=0.001
    fprintf(meter, 'FREQ %dKHZ', freq*1e3);
elseif freq>=1e-6
    fprintf(meter, 'FREQ %dHZ', freq*1e6);
end
fprintf(meter, 'BIAS:STATE ON')
fprintf(meter, 'VOLT %f', mag)

figure(1)
clf(1)
for i=1:length(Vvec_up)
    fprintf(meter, 'BIAS:VOLT %f', Vvec_up(i));
    fprintf(meter, 'TRIG; *WAI');
    pause(pse);
    fprintf(meter, 'FETC?');
    holder = str2num(fscanf(meter));
    Cs(i) = holder(1);
    D(i) = holder(2);
    %disp(holder)
    if(mod(i,10)==1)
        pause(0.2);
    end
    Rs = D./(2*pi*freq*Cs);
    subplot(211)
    semilogy(Vvec_up(1:i), Cs);
    subplot(212)
    plot(Vvec_up(1:i), Rs);
end
% Rs = D./(2*pi*freq*Cs);
% plotyy(Vvec_up, Cs, Vvec_up, Rs);
%clean plots
badpoints = Cs>1;       %Cs isn't >1F, no matter how badly you mess up
Cs_new = Cs.*(~badpoints);
Rs_new = Rs.*(~badpoints);
subplot(211)
[AX H]=plotyy(Vvec_up, Cs_new, Vvec_up, Rs_new);
set(AX(1), 'YScale', 'log')
set(AX(1), 'YTickLabel', num2str(get(AX(1), 'YTick')'));
subplot(212)
plot(Vvec_up, 1./(Cs_new.^2));

%set back to continuous scan mode
fprintf(meter, 'BIAS:VOLT %f', Vvec_up(10));
fprintf(meter, 'TRIG:SOUR INT') %set trigger source to GPIB (HPIB) internal

fclose(meter)
clear meter

uisave()