]> jspc29.x-matter.uni-frankfurt.de Git - daqtools.git/commitdiff
users/mainz: Added powercycling and tested psu.pl
authorAndreas Neiser <neiser@kph.uni-mainz.de>
Fri, 12 Apr 2013 20:18:22 +0000 (22:18 +0200)
committerAndreas Neiser <neiser@kph.uni-mainz.de>
Fri, 12 Apr 2013 20:18:22 +0000 (22:18 +0200)
users/mainz_kph_a2/psu.pl

index b5297251fb324d39f4b227cbd684d56e78613b79..3465537f6763cc26cb51876d239ff837de11ce10 100755 (executable)
@@ -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";
+  }
 }