#!/usr/bin/perl
#
# soltron
# a modified script to communicate with a Keithley SourcMeter
# and get I-V data for PV cells specifically in text and graphical form
#
# Charles Miller and Breanden O'Shaugnessy, 2009
#
# see readme for great justice
#
print "soltron will start in\n";
sleep(1);#so single operator has time to move
print"5\n";
sleep(1);
print"4\n";
sleep(1);
print"3\n";
sleep(1);
print"2\n";
sleep(1);
print"1\n";
sleep(1);



open(MEOUT, ">>/dev/ttyUSB0");  
open(MEIN, "</dev/ttyUSB0");
open(TEX, "<soltron.tex");
@tex=<TEX>;

#grab commandline args, define 
$start = $ARGV[0]; 	#start voltage
$end=$ARGV[1];		#end voltage
$steps=$ARGV[2];	#number of measurements
$output=$ARGV[4];	#name of output .csv and .png files desi2
$area=$ARGV[3];		#area of the cell
$stepsize=($end-$start)/$steps;
$integral=0;		#area under curve
$power=0;		#maximum power measu2
$Isc=0;				
$FF=0;
$powervolts;		#volts at $maxpower
$powercurrent;		#current ....
$maxpower;		#highest observed power

print "removing $output.csv and $output.png...\n\nsweeping voltage from $start\ volts to $end\ volts in $steps steps of $stepsize\ volts each\n\nwriting data to $output.csv\n\n(ignore any annoying error messages or horrific wailing from the SourceMeter)\n\n";

`rm gnup.scr`;			#remove previous gnuplot script; I'm not saving these.
#`touch $output.csv`; 		#create new output data file for perl to use

open(MECSV, ">$output.csv");
open(METXT, ">$output.txt");


#setup shit
print MEOUT "*rst\n";
print MEOUT "outp on\n";
print MEOUT ":sens:func 'curr'\n";
print MEOUT ":sour:func volt\n";
print MEOUT ":sens:curr:prot 1\n";
print MEOUT ":trig:coun 1\n";
print MEOUT ":form:elem curr\n";



print MEOUT ":sour:volt 0\n";
print "waiting for current to stabilize\n\n";
sleep(2);				#get I_sc
print MEOUT ":read?\n";
$Isc = <MEIN>;
$Isc = -$Isc;


print "meansuring I-V data\n";
#loop for making the I-V plot
for($volts=$start; $volts <= $end; $volts += $stepsize){

print MEOUT ":sour:volt $volts\n";
print MEOUT ":read?\n";
$datum = <MEIN>;
$flipdatum=$datum;
$datum = -$datum;
chomp $datum;

$integral+=$datum*$stepsize;#this is unused but still cool

$power=$datum*$volts; 

print MECSV "$volts, $datum, $power, $flipdatum\n"; 		#not robust since it assumes we are writing voltage 
							#to the machine correctly, but it should be obvious if it fails.


	if($maxpower<=$power){		#grab the sample that corresponds to the highest power in the plot
		$maxpower=$power;
		$powervolts=$volts;
		$powercurrent=$datum;
		}


if($datum < 0)  #stop curve once V_oc is reached
{
	$volts = $end+1;
}


}   #end loop for making the I-V plot



print MEOUT ":sens:func 'volt'\n";
print MEOUT ":sour:func curr\n";
print MEOUT "output on\n";
print MEOUT ":form:elem volt\n";
print MEOUT ":sour:curr 0\n";
print "waiting for voltage to stabilize\n";
sleep(2);					#get V_oc
print MEOUT ":read?\n";
$Voc = <MEIN>;
print MEOUT "output off\n";




$FF=$maxpower/($Voc*$Isc);				#get FF

$eta=$maxpower/($area);



print METXT "integral value, $integral\n";		#write data file for great justice
print METXT "fill factor, $FF\n";
print METXT "Open circuit voltage, $Voc, volts\n";
print METXT "Short Circuit current, $Isc, amps\n";
print METXT "max power produced, $maxpower, watts\n";
print METXT "Point of max power, $powervolts,\n";
print METXT "Point of max power, $powercurrent, amps\n";
print METXT "power efficiency, $eta, NA\n";
print METXT "measured cell area, $area, m^2\n";


open (SCR, ">>gnup.scr");

chomp $Voc;
chomp $Isc;
print SCR "# gnuplot script for '$output.csv'\n";
print SCR "set xrange [0 to $Voc]\n"; #make gnuplot script
print SCR "set xlabel 'Voltage, V'\n";
print SCR "set ylabel 'Current/Power'\n";
print SCR "set arrow from $Voc,0 to $Voc,$Isc nohead ls 4 \n";
print SCR "set arrow from $powervolts,0 to $powervolts,$powercurrent nohead ls 3 \n";
print SCR "set arrow from 0, $powercurrent to $powervolts,$powercurrent nohead ls 3 \n";
print SCR "set arrow from 0, $Isc to $Voc,$Isc nohead ls 4 \n";
print SCR "set arrow from 0,0 to $Voc,0 nohead\n";
print SCR "set terminal png size 800,600\n";
print SCR "set output '$output.png'\n";
print SCR "f(x)=$maxpower\n";
print SCR "g(x)=$Isc\n";			
print SCR "plot '$output.csv' using 1:2 with linespoints title 'Current, A', '$output.csv' using 1:3 with linespoints title 'Power, W'\n";
		
`gnuplot gnup.scr&`;            #plot and spit out a .png image

print "saving image of plot as $output.png\n\n";

#`feh $output.png &`; 	#having gnuplot output a png means it doesn't also create a window. 

`convert $output.png $output.eps`;

open (texout, ">$output.tex"); 

foreach (@tex){

    	$_ =~ s/xxFF/$FF/;
	$_ =~ s/xxVoc/$Voc/;			#morph latex file with current values
	$_ =~ s/xxIsc/$Isc/;
	$_ =~ s/xxETA/$eta/;
	$_ =~ s/xxArea/$area/;
	$_ =~ s/xxMPV/$powervolts/;
	$_ =~ s/xxMPC/$powercurrent/;
	$_ =~ s/xxMP/$maxpower/;
	$_ =~ s/lena.eps/$output.eps/;
	$_ =~ s/xxFilename/$output/;

	print texout $_;
	
}


print "test completed. Check $output.csv and $output.txt for data\n";


`latex $output.tex`;
`dvipdf $output.dvi`;
`rm $output.eps $output.log $output.dvi $output.aux $output.tex`;
`mkdir $output`;
`mv -b $output.* $output`;

`evince $output/$output.pdf &`;






