From: Andreas Neiser Date: Fri, 12 Apr 2013 20:18:22 +0000 (+0200) Subject: users/mainz: Added powercycling and tested psu.pl X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=eaef08c563748ca9b8fe11895ac5c89051af721d;p=daqtools.git users/mainz: Added powercycling and tested psu.pl --- diff --git a/users/mainz_kph_a2/psu.pl b/users/mainz_kph_a2/psu.pl index b529725..3465537 100755 --- a/users/mainz_kph_a2/psu.pl +++ b/users/mainz_kph_a2/psu.pl @@ -1,42 +1,88 @@ #!/usr/bin/perl use strict; use warnings; - use Device::SerialPort; +my($port,$maxU,$maxI); + &main; sub main { - my $port = setup_connection("/dev/ttyACM0"); - my($U0,$I0,$OnOff0,$U0s,$I0s)=get_current_values($port, 0); - my($U1,$I1,$OnOff1,$U1s,$I1s)=get_current_values($port, 1); - printf("Output 0: %s %06.3fV (%06.3fV) %05.3fA (%05.3fA)\n", $OnOff0 ? "On" : "OFF" , - $U0, $U0s, $I0, $I0s); - printf("Output 1: %s %06.3fV (%06.3fV) %05.3fA (%05.3fA)\n", $OnOff1 ? "On" : "OFF" , - $U1, $U1s, $I1, $I1s); - $port->close or die "failed to close port"; + setup_connection("/dev/ttyACM0"); + print_current_values(0); + print_current_values(1); + if(defined $ARGV[0] and $ARGV[0] eq "powercycle") { + die "No Channel given to powercycle" unless defined $ARGV[1]; + my $channel = $ARGV[1] eq "1" ? 1 : 0; + do_power_cycle($channel); + } + # serial connection is closed in END {} block +} + +sub do_power_cycle { + my $ch = shift; + print "Powercycling Output $ch...\n"; + # enable remote control + send_and_read("F100361010",$ch); + + # turn output off + print "Turning off Output $ch...\n"; + send_and_read("F100360100",$ch); + + # wait until voltage is low enough (<1V) + my $timeout = 100; + while(1) { + my $U = print_current_values($ch); + last if $U<1 or $timeout==0; + $timeout--; + } + + if($timeout>0) { + print "Waiting a bit more...\n"; + sleep(3); + print_current_values($ch); + print "Turning on Output $ch again...\n"; + send_and_read("F100360101",$ch); + sleep(1); + } + else { + print "Could not reach Voltage < 1 V before timeout.\n"; + } + + # disable remote control and print state again + send_and_read("F100361000",$ch); + print_current_values($ch); +} + +sub print_current_values { + my $ch = shift; + my($U,$I,$OnOff,$Us,$Is,$R)=get_current_values($ch); + printf("Output %d: %s, %06.3f V (-> %06.3f V), %05.3f A (-> %05.3f A) %d\n", + $ch, + $OnOff ? "On" : "OFF" , + $U, $Us, $I, $Is, $R); + return $U; } sub get_current_values { - my $port = shift; my $ch = shift; - my $response = send_and_read($port,"750047",$ch); + my $response = send_and_read("750047",$ch); my($status1,$status2,$U,$I,$checksum) = unpack("x3CCnnn", $response); - my $response_set = send_and_read($port,"750048",$ch); + my $response_set = send_and_read("750048",$ch); my($Uset,$Iset) = unpack("x5nnx", $response_set); # do the weird calculation to physical values (depends on device) $U = 84 * $U / 25600; $I = 5 * $I / 25600; - my $OnOff = $status2 & 0x1; - $Uset = 84 * $Uset / 25600; - $Iset = 5 * $Iset / 25600; - return ($U, $I, $OnOff, $Uset, $Iset); + my $OnOff = $status2 & 0b1; + my $Remote = $status1 &0b11; + $Uset = $maxU * $Uset / 25600; + $Iset = $maxI * $Iset / 25600; + return ($U, $I, $OnOff, $Uset, $Iset, $Remote); } sub send_and_read { - my $port = shift; my $msg = shift; # msg bytes as hex coded string (without checksum) my $channel = shift || 0; # output 0 or 1? @@ -55,7 +101,7 @@ sub send_and_read { sub setup_connection { my $portname = shift; - my $port = Device::SerialPort->new($portname) + $port = Device::SerialPort->new($portname) or die "Can't connect to $portname: $!"; # connection settings from ps2000b_programming.pdf @@ -65,7 +111,24 @@ sub setup_connection { $port->stopbits(1); $port->write_settings or die "Can't write settings"; $port->read_char_time(0); # don't wait for each character - $port->read_const_time(100); # 1 second per unfulfilled "read" call + $port->read_const_time(100); # 100 ms per unfulfilled "read" call + + # Let's get the device identifier and deduce maximum voltage/current + my $str = unpack("x3Z*", send_and_read("750000")); + if(defined $str && $str =~/^PS \d(\d)(\d\d)-(\d\d)\w$/) { + die "Single not implemented" if $1 != 3; + $maxU = $2; + $maxI = $3; + printf("Device %s found: %d V, %d A maximum\n",$str,$maxU,$maxI); + } + else { + die "Device $str not recognized"; + } +} - return $port; +END { + if(defined $port) { + # only warn here, since we're exiting anyway + $port->close or warn "Failed to close port"; + } }