#!/usr/bin/perl -w
#
# hp5370b-hp3456a.pl
# version 0.9 --  3 September 2005
#
# Record frequency readings from HP 5370B counter and simultaneous
# 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 $device1 = "hp5370b";
my $device2 = "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:g:n:s:f:t:';

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

usage: $0 [-h] [-a samples to average] [-g gate time] 
	[-n nominal frequency] [-s scale frequency] -f logfile

-a      : samples to average -- default 1
-g      : gate time (GT1, GT2, GT3, GT4)
-h      : this (help) message
-n      : nominal frequency; readings will be normalized against this
-s      : scale frequency; readings will be divided by this
-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 $gate = "GT4";
if ($opt{g}) {
        $gate = $opt{g};
        }

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

my $nominal = 0;
if ($opt{n}) {
	$nominal = $opt{n};
	}

my $scale = 0;
if ($opt{s}) {
	$scale = $opt{s};
	}
	 
my $logfile = $opt{f};

#----------
# initialize variables
my $counter;
my $sum1;
my $sum2;
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
if ($gate eq "GT4") {
	select(LOG), $| = 1;
	}


#----------
# initialize devices
my $brd = LinuxGpib::ibfind($board);
my $dev1 = LinuxGpib::ibfind($device1);
my $dev2 = LinuxGpib::ibfind($device2);

# clear
LinuxGpib::ibclr($dev1);
usleep(1000000);
LinuxGpib::ibclr($dev2);
usleep(1000000);

# initialize 5370B
$command = "FN3" . $gate . "MD4";
LinuxGpib::ibwrt($dev1,$command,length($command));
usleep(1000000);

# intialize 3456A:
# DCV, autorange, local trigger lockout, autozero on, filter off,
# plc integration 10, ascii output, display 6 digits.
$command = "F1R1T4Z1FL0G6I10";
LinuxGpib::ibwrt($dev2,$command,length($command));
usleep(1000000);

#----------

# 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 "# Frequency from $device1, gate $gate, voltage from $device2.\n";
print LOG "# Average by $samples.";
if ($nominal) {
	print LOG "  Nominal frequency is $nominal.";
	}
else {
	if ($scale) {
		print LOG " Scaled from $scale."
		}
	}
print LOG "\n";
	


#----------
my $last_avg_value1 = 0;
my $last_avg_value2 = 0;
$sum1 = 0;
$sum2 = 0;

sub dolog {
	my $avg_value1 = $sum1/$samples;
	my $avg_value2 = $sum2/$samples;
	if ($nominal) {
		$avg_value1= $avg_value1- $nominal;
		}
	if ($scale) {
		$avg_value1= $avg_value1/$scale;
		}
	if ($samples <= 10) {
		print LOG logline($tags,12,
			round(13,$avg_value1),round(6,$avg_value2));
		}
	else {
		print LOG logline($tags,14,
			round(15,$avg_value1),round(7,$avg_value2));
		}
	
	$last_avg_value1 = $avg_value1;
	$last_avg_value2 = $avg_value2;
}

$counter = 1;
my $result1 = 0;
my $result2 = 0;

# main loop
$command = "MR";
LinuxGpib::ibwrt($dev1,$command,length($command));
while (1) {

        if (checkSRQ($brd)) {
		# get the frequency and retrigger
                $result1 = substr(substr(squash(trim(serviceSRQ($dev1))),1),3);
		usleep(5000);
                $command = "MR";
                LinuxGpib::ibwrt($dev1,$command,length($command));
		usleep(5000);

		# get the voltage
		LinuxGpib::ibtrg($dev2);
		usleep(5000);
                LinuxGpib::ibrd($dev2,$result2,14);
		$result2 = squash(trim($result2));

		$sum1 += $result1;
		$sum2 += $result2;

		if ($counter == $samples) {
			dolog;
			$sum1 = 0;
			$sum2 = 0;
			$counter = 1;
		} else {
			$counter++;	
			}
	}
	usleep(200000);
}	

#----------

exit 0;
