#!/usr/bin/perl

use lib 'd:/Programs/Perl/lib';
use lib 'd:/Programs/Perl/lib2.0';
use lib '.';

use strict;

use MyApplication2;
use Device::Device;
use Device::Keithley6517A;
use Device::Cornerstone130;
use Device::Lockinamp7265;
use Device::ArcLamp;
use Device::SteppingmotorD92;


$SIG{INT} = \&ctrl_c_handler;
BEGIN {
	open (STDERR, ">&STDOUT");
}


#===============================================
# 測定関係変数
#===============================================
#データファイルの名前
my $DataFileName = "Test2.csv";

# 測定前のWait
my $WaitBefore = 1.0;
my $WaitForMeasurement = 2.0;
my $WaitForAutoPhase =2.0;

#電圧源リミッターの設定
my $VSourceLimit = 10.0;

# 平均を取る回数
my $nAverage = 10;

#Keuthley6517A ZeroCheck
my $ZeroCheck = 'on';


#Cornerstone130の測定波長の範囲
my $WStart = 600;
my $WEnd   = 200;
my $WStep  = -5.0;


my $Who = 'Tsukamoto';
my $Today = Utils::BuildDateString(time());



#===============================================
# Applicationオブジェクト作成
#===============================================
my $App = new MyApplication2;
$App->SetOutputMode("auto");
my $ProgramPath = $App->SpeculateProgramPath($0, "");
my $IniFile = $App->OpenIniFile($ProgramPath, 1);
$App->AddIniFileVariable("\\Preferences\\DeviceName", "DeviceName", "Keithley2000");
$App->AddIniFileVariable("\\Preferences\\Port",       "Port",       "GPIB17");
$App->ReadSetting();



#================================================================
# Test
#================================================================

#if(0) {

my $SteppingmotorD92 =OpenDevice("SteppingmotorD92" , "GPIB10");

my $p = $SteppingmotorD92->GetPosition();
print "pos=$p\n";
$SteppingmotorD92->SetPresentPosition();
$p = $SteppingmotorD92->GetPosition();
print "pos=$p\n";


while(1) {
	print "Input position>";
	my $line = <>;
	last if($line =~ /bye/i);
#	Utils::DelSpace($line);
#	$SteppingmotorD92->print("$line\r\n");
	$line = $line + 0;
	$SteppingmotorD92->SetX($line);
}


exit;

#}



#================================================================
# Deviceオブジェクト作成
#================================================================
my $K6517A         = OpenDevice("Keithley6517A", "GPIB27");
my $Cornerstone130 = OpenDevice("Cornerstone130", "COM1");
my $Lockinamp7265  = OpenDevice("Lockinamp7265" , "GPIB12");
#my $ArcLamp        = Opendevice("ArcLamp" , "GPIB6");
#my $SteppingmotorD92 =OpenDevice("SteppingmotorD92" , "GPIB10")


#Keithley6517Aの初期化
$K6517A->Initialize();
$K6517A->SetDCCurrentMode($ZeroCheck);
$K6517A->SetVSourceLimit($VSourceLimit);
$K6517A->SetAutoRangeForCurrent("on");

#Lockinamp7265の設定
$Lockinamp7265->SetAutoPhase();



#================================================================
# 測定開始
#================================================================
my $nWStep = int( ($WEnd - $WStart) / $WStep + 1.000000001 );
 
Utils::sleep($WaitBefore);

$K6517A->SetVSourceOutput("on");
$Cornerstone130->GoWave($WStart);
$Cornerstone130->Shutter("0");      #シャッター開


#回折格子の波長が設定されたら、人間がENTERキーを押して次の作業に進む
print "\nPress ENTER if ready>";
<>;


#ファイル書込み
if(-w $DataFileName) { print "Can write to [$DataFileName]\n"; }
my $out = new JFile;
if(!$out->Open($DataFileName, "w")) {
	print "Error: Can not write to [$DataFileName]\n";
	exit;
}



#Excel用にデータを書き出す
$out->print("W,I,**********Measured by $Who, $Today,\n");

while(1) {

for(my $i = 0 ; $i < $nWStep ; $i++) {
	my $W = $WStart + $WStep * $i;


   my $Isv = 0.3e-9;
   my $kp = 1e10;
   my $Vpv = 1.0;
   my $VULimit = 10;
   my $VLLimit = 0.0;

	
    
    $Cornerstone130->GoWave($W);
    $K6517A->SetSourceVoltage($Vpv);
    Utils::sleep($WaitForMeasurement);
	print("Waiting $WaitForMeasurement s...\n");

    $Lockinamp7265->SetAutoPhase();
    Utils::sleep($WaitForAutoPhase);
	print("Waiting $WaitForAutoPhase s...\n");
	my $Ipv = $Lockinamp7265->Measure();


    my $dV = -$kp * ($Ipv - $Isv);
    $Vpv = $Vpv + $dV;

	if($Vpv > $VULimit) {
		$Vpv = $VULimit;
	}
	if($Vpv < $VLLimit) {
		$Vpv = $VLLimit;
	}
	
	
    print("W=$W    Ipv=$Ipv\n");
	$out->print("$W,$Ipv");

         }

}




#Cornerstone130シャッター閉じる
$Cornerstone130->Shutter("1");


exit;




#============================================================
#　一般関数
#============================================================
sub ctrl_c_handler{
	$App->print("CTRL+C pressed\n");
	$App->print("Input 'yes' if terminate this program.\n>>");
	my $line = <>;
	if($line =~ /^\s*yes\s*$/i) {
	   exit;
	}
	return;
}

sub OpenDevice
{
	my ($DeviceName, $Port) = @_;
	Utils::DelSpace($DeviceName);
	Utils::DelSpace($Port);

#RS232Cの設定
my $ConfFile        = '';
my $COMPort         = 'COM1';
my $UseModule       = 0;
my $BaudRate        = 9600;
my $Parity          = 'none';
my $DataBits        = 8;
my $StopBits        = 1;
my $HandShake       = 'none';
my $WriteBufferSize = 1024 * 20;
my $ReadBufferSize  = 1024 * 4;
my $ReadInterval    = 800;
my $ReadCharTime    = 400;
my $ErrorMessage    = 1;
my $UserMessage     = 1;

#GPIBの設定
my $GPIBInterface   = "ni";
my $GPIBTimeOut     = GPIB->T1s;
my $GPIBEOT         = 1;
my $GPIBEOS         = 0;

	my $dev = new Device(
			-Port               => $Port,
			-ModuleName         => $DeviceName,
			-DeviceName         => $DeviceName,
			-GPIBInterface      => $GPIBInterface,
			-GPIBTimeOut        => $GPIBTimeOut,
			-GPIBEOT            => $GPIBEOT,
			-GPIBEOS            => $GPIBEOS,
			-COMConfName        => $ConfFile,
			-COMBaudRate        => $BaudRate,
			-COMParity          => $Parity,
			-COMDataBits        => $DataBits,
			-COMStopBits        => $StopBits,
			-COMHandShake       => $HandShake,
			-COMWriteBufferSize => $WriteBufferSize,
			-COMReadBufferSize  => $ReadBufferSize,
			-COMReadInterval    => $ReadInterval,
			-COMReadCharTime    => $ReadCharTime,
			-COMErrorMessage    => $ErrorMessage,
			-COMUserMessage     => $UserMessage,
			-PrintError         => 1,
			);
	if(!defined $dev) {
		$App->print("Device can not be opened. [$DeviceName: $Port]\n");
		exit;
	}

	my $Id = $dev->GetId();
	$App->print("$DeviceName: [$dev->{ModuleName}:$dev->{Port}] (Object: $dev)\n");
	$App->print("Id: $Id\n");

	return $dev;
}

