#!/usr/bin/perl -w
#
# hp3456a.pl
# version 0.9 --  6 September 2005
#
# Record voltage readings from HP 3456A DMM.
# 
# Copyright 2004-2005 by John R. Ackermann  N8UR (jra@febo.com)
#
# This program may be copied, modified, distributed and used for 
# any legal purpose provided that (a) the copyright notice above as well
# as these terms are retained on all copies; (b) any modifications that 
# correct bugs or errors, or increase the program's functionality, are 
# sent via email to the author at the address above; and (c) such 
# modifications are made subject to these license terms.

use strict;
use POSIX qw(setsid);
use Getopt::Std;
use Time::HiRes qw(usleep);
use LinuxGpib;
use DateTime;
use n8ur qw(trim squash collapse round);
use n8ur_gpib qw(checkSRQ serviceSRQ logline);

##########################
my $board = "gpib1";
my $device = "hp3456a";
##########################

#----------
# handle signals and errors -- mainly to clear lockfile on termination
sub sig_handler {
	sleep 2;
	close LOG;
	exit(0);
}

# there's got to be a better way!
$SIG{'HUP'} = 'sig_handler';
$SIG{'INT'} = 'sig_handler';
$SIG{'KILL'} = 'sig_handler';
$SIG{'STOP'} = 'sig_handler';
$SIG{'TERM'} = 'sig_handler';
#----------

#----------
# display usage
my $opt_string = 'h:a:f:t:s:';

sub usage() {
print STDERR << "EOF";

usage: $0 [-h] [-a samples to average] -f logfile

-a      : samples to average -- default 1
-h      : this (help) message
-t	: timetag format (mjd|iso|none); default mjd
-f      : logfile using full pathname;
          for output to console, use "-f -"

EOF
}

#----------

getopts( "$opt_string", \my %opt ) or usage() and exit;

# print usage
usage() and exit if $opt{h};
usage() and exit if !$opt{f};

# set variables to command line params

my $samples = 1;
if ($opt{a}) {
        $samples = $opt{a};
        }

my $sm = "";
if ($opt{s}) {
        $sm = $opt{s};
        }

my $tags = "mjd";
if ($opt{t}) {
        $tags = lc($opt{t});
        }

my $logfile = $opt{f};

#----------
# initialize variables
my $sum;
my $tmp;
my $command;
my $gpib_status;

#----------
# set up logfile
open (LOG, ">>$logfile") ||
	die "Can't open logfile $logfile!\n";
# set nonbuffered mode if slower readings
select(LOG), $| = 1;


#----------
# initialize devices
my $brd = LinuxGpib::ibfind($board);
my $dev = LinuxGpib::ibfind($device);

# clear
LinuxGpib::ibclr($dev);
usleep(1000000);

# intialize 3456A:

# DCV, autorange, autozero, trigger hold
# $command = "F1 R1 Z1 T4";
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(50000);
# filter off, display 6 digits, integrate 10 PLC
#$command = "FL0 6STG 10STI";
#LinuxGpib::ibwrt($dev,$command,length($command));
#usleep(50000);
# trigger hold, set SRQ mask
$command = $sm;
print "command = $command\n";
LinuxGpib::ibwrt($dev,$command,length($command));
usleep(500000);

#----------

# write header line
my $dt = DateTime->now;
my $current_iso = $dt->ymd('-') . 'T' . $dt->hms(':');
my $current_mjd = $dt->mjd;
printf LOG "# Run started at %s (MJD %11.6F).\n",$current_iso,$current_mjd;
print LOG "# Voltage from $device.  Average by $samples.\n";

#----------
my $last_avg_value = 0;
$sum = 0;

sub dolog {
	my $avg_value = $sum/$samples;
	if ($samples <= 10) {
		print LOG logline($tags,7,
			round(6,$avg_value));
		}
	else {
		print LOG logline($tags,8,
			round(7,$avg_value));
		}
	
	$last_avg_value = $avg_value;
}

my $status;
my $device_status;
my $tries;
my $counter = 1;
my $result = 0;

$device_status = 0x00;
$status = 0x8000;

# main loop
while (1) {
LinuxGpib::ibtrg($dev);
usleep(500000);
	if (checkSRQ($brd)) {
		print "checkSRQ = true\n";
		$device_status = 0x00;
		$status = 0x8000;
		while ($status == 0x8000 && $tries < 3) {
               		if ($tries > 0) { usleep(1000) };
               		$status = LinuxGpib::ibrsp($dev,$device_status);
               		$tries++;
               	}
	}
	$result = LinuxGpib::ibrd($dev,$result,14);
	usleep(5000);
	printf "status = 0x%x device_status = 0x%x\n",$status,$device_status;
	if ($device_status & 0x1) {print "bit 0\n";}
	if ($device_status & 0x2) {print "bit 1\n";}
	if ($device_status & 0x4) {print "bit 2\n";}
	if ($device_status & 0x8) {print "bit 3\n";}
	if ($device_status & 0x10) {print "bit 4\n";}
	if ($device_status & 0x20) {print "bit 5\n";}
	if ($device_status & 0x40) {print "bit 6\n";}
	if ($device_status & 0x80) {print "bit 7\n";}
	if ($device_status & 0x100) {print "bit 8\n";}
	if ($device_status & 0x200) {print "bit 9\n";}
	if ($device_status & 0x400) {print "bit 10\n";}
	if ($device_status & 0x800) {print "bit 11\n";}
	if ($device_status & 0x1000) {print "bit 12\n";}
	if ($device_status & 0x2000) {print "bit 13\n";}
	if ($device_status & 0x4000) {print "bit 14\n";}
	if ($device_status & 0x8000) {print "bit 15\n";}
	$result = 0;
	usleep(900000);
}	

#----------

exit 0;
