function data = Diode_IV( diodeCurrent, fileName, varargin)
%function data = Diode_IV( diodeCurrent, fileName, <Parameters>)
%
%Collects and logs data for the diode I-V measurement. The diode response
%voltage is recorded as a function of inputted current and diode temperature. 
%
%
%INPUTS
%
%diodeCurrent       Applied current across diode (in amperes)
%                   Vector of nonnegative values (forward bias)
%                   Suggested values: 0:1e-3:1e-1
%
%fileName           File name for output data file
%                   Data file is a comma delimited .csv file containing the data
%                   with the following order of columns
%                       temperature A
%                       temperature B 
%                       average temperature
%                       applied current
%                       diode voltage
%
%
%OPTIONAL PARAMETERS
%
%SaveFolder         Folder to save output data .csv file.
%                   Default: [pwd]/Data_[YYYYmmDD]/
%
%Units              Units of sensor (either temperature or raw resistance)
%                   Expected: 'K' or 'Ohm'
%                   Default: 'K'
%
%Delay              Delay between measurements in seconds
%                   Default: 0.1
%
%Compliance         Max voltage compliance for keithley (the maximum voltage in 
%                       its attempt to source the programmed current)
%                   Default: 105
%
%OUTPUTS
%
%data               N x 5 matrix
%                   Contains data in 5 columns:
%                       temperature A
%                       temperature B 
%                       average temperature
%                       applied current
%                       diode voltage  
%
%
%NOTES
%
%If the program exits with errors, call delete(instrfind) at the command
%prompt to reset the hardware connections.
%
%
%ACKNOWLEDGEMENTS
%
%Inspired by diode_gpib.m written by Benjamin Nachumi (peripatetic1@yahoo.com).
%
%
%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
%X Author:          Sky Cheung                                                X
%X Date Created:    24 Feb 2015                                               X
%X Last Modified:   10 Apr 2015                                               X
%XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
%

%Input Parsing
p = inputParser;

%Defaults
defaultSaveFolder = sprintf('%s\\Data_%s', pwd, datestr(now,'YYYY-mm-DD') );
defaultUnits = 'K';
defaultDelay = 0.1;
defaultCompliance = 105;



%Parsing Conditions for Required Arguments
addRequired(p, 'diodeCurrent', @(x) validateattributes( x, ... 
    {'numeric'}, {'vector', 'nonnegative'} ) );
addRequired(p, 'fileName', @(x) validateattributes( x, ...
     {'char'}, {'nonempty'} ) );

%Parsing Conditions for Optional Parameters
addParameter(p, 'SaveFolder', defaultSaveFolder, @(x) validateattributes( x, ... 
    {'char'}, {'nonempty'} ) );
addParameter(p, 'Units', defaultUnits, @(x) any( validatestring( x, ...
    expectedUnits) ) );
addParameter(p, 'Delay', defaultDelay, @(x) validateattributes( x, ...
    {'numeric'}, {'nonempty','scalar','nonnegative'} ) );
addParameter(p, 'Compliance', defaultCompliance, @(x) validateattributes( x, ...
    {'numeric'}, {'nonempty','scalar','nonnegative'} ) );

%Parsing Inputs
parse(p, diodeCurrent, fileName, varargin{:});

%Getting proper inputs
diodeCurrent = p.Results.diodeCurrent;
fileName = p.Results.fileName;
saveFolder = p.Results.SaveFolder;
units = p.Results.Units;
delay = p.Results.Delay;
compliance = p.Results.Compliance;

%Delete Stucture
clear p;

%Constants
%NOTE: do not change these or some data might be lost in transit
%Sufficient Delay
deltaDelay = 0.1;

%Enable pausing
pause on



keithleyI = visa('ni','gpib0::13::INSTR');
fopen(keithleyI);
fprintf(keithleyI,'*IDN?');
keithleyIName = fscanf(keithleyI);
%Removing Trailing Whitespace
keithleyIName = strtrim(keithleyIName);

keithleyV = visa('ni','gpib0::14::INSTR');
fopen(keithleyV);
fprintf(keithleyV,'*IDN?');
keithleyVName = fscanf(keithleyV);
%Removing Trailing Whitespace
keithleyVName = strtrim(keithleyVName);

%Preparing Cleanup function to ensure proper disconnection
finishUp = onCleanup(@() Disconnect_Ports( keithleyI, keithleyV ) );

%Echoing names
fprintf('Successfully connected to:\n%s\n%s\n', ...
    keithleyIName, ...
    keithleyVName );

%Initialize the 6220&2182
fprintf(keithleyI,'*RST');
fprintf(keithleyI,'SOUR:CURR:COMP %e', compliance);
fprintf(keithleyI,'SOUR:CURR:RANG:AUTO ON');
fprintf(keithleyI,'OUTP ON');

fprintf(keithleyV,'*RST');	
fprintf(keithleyV,'*CLS');

fprintf(keithleyV,'SAMP:COUN 1');
fprintf(keithleyV,'READ?');
testVolts=fscanf(keithleyV,'%e');
fprintf('%.4f V\n', testVolts);

%start heater and begin logging data points
fprintf('Strike any key to start logging data...\n');
pause;

%Preparing output file
if ~isdir(saveFolder)
    mkdir(saveFolder);
end
fName = sprintf('%s\\%s.txt', saveFolder, fileName);
numColumns = 5;

%Holding plot
hold on;

%Axis Labels
xlabel('Diode Voltage (V)');
ylabel('Applied Current (A)');


%Preallocation
numCurrent = length(diodeCurrent);
data = zeros( numCurrent, numColumns);

%Begin loop over current
for j = 1:numCurrent
    %Set current on Keithley Current Source
    fprintf( keithleyI,'SOUR:CURR %e', diodeCurrent(j) );

    
    %Pause to stablize
    pause(deltaDelay);
    
    %Obtain voltage
    fprintf( keithleyV,'READ?');
    diodeVolt = fscanf( keithleyV,'%e');
    
    %Adding data entry
    data(j,:) = [diodeCurrent(j), diodeVolt];
    
    %Write new data to file
    dlmwrite( fName, data(j,:), ...
        'delimiter', ',', ...
        'newline', 'pc', ...
        'precision', '%.6e', ...
        '-append');

    %Update Plot
    plot(diodeVolt, diodeCurrent(j), 'r+' );

    %Delay
    pause(delay);
    
end %End of looping over current

%Overlay plot with blue diamonds
plot(data(:,5), data(:,4),'bd');

end %End of Diode_IV.m

%Disconnect upon completion
function Disconnect_Ports(keithleyI, keithleyV)
    %Keithley Current
    fprintf('Removing Keithley Current Source connection.\n');  
    %Disarming Keithley
    fprintf(keithleyI,'SOUR:SWE:ABOR');
    fprintf(keithleyI,'TRAC:CLE');
    fclose(keithleyI);
    
    %Keithley Voltage
    fprintf('Removing Keithley Voltmeter connection.\n');  
    %Disarming Keithley
    fprintf(keithleyV,'SOUR:SWE:ABOR');
    fprintf(keithleyV,'TRAC:CLE');
    fclose(keithleyV);
    
    fprintf('Disconnecting ports.\n');  
    delete(instrfind);
    
    fprintf('Successfully disconnected.\n');  
end %End of Disconnect_Ports
