#!/usr/bin/perl -w
#
# hp3586c.pl
# version 0.5 -- 13 September 2003
#
# Record frequency readings from HP 5370b counter
# 
# Copyright 2003 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;

#----------
# 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:i:f:';

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

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

-a	: samples to average -- default 1
-i	: logging interval (seconds); minimum is 10
-h	: this (help) message
-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 $interval;
my $samples;
my $logfile;

# there's a five second sleep with each reading, so subtract that
# from the measured interval.
if ($opt{i}) {
	$interval = $opt{i} - 6;
	}
else {
	$interval = 4;
	}

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

$logfile = $opt{f};

#----------

# device name from /etc/gpib.conf
my $device = "hp3586c";

#----------
# initialize variables
my $reading;
my $val;
my $bytecount;
my $counter;
my $badcount;
my $sum;
my $command;

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

#----------
# initialize counter
my $dev = LinuxGpib::ibfind($device);
# clear
LinuxGpib::ibclr($dev);
# set for cal off,wideband, auto entry, 10dB range,averaging
$command = "CA0";
LinuxGpib::ibwrt($dev,$command,length($command));
sleep(1);
$command = "F1A1R1WB";
LinuxGpib::ibwrt($dev,$command,length($command));
sleep(1);
$command = "WB";
LinuxGpib::ibwrt($dev,$command,length($command));
sleep(1);
# trigger a cal, just to settle things down
$command = "CA1";
LinuxGpib::ibwrt($dev,$command,length($command));
sleep(4);
#----------
# main loop
while (1) {
	$command = "CA1TR";
	LinuxGpib::ibwrt($dev,$command,length($command));
	# sleep for calibration plus measurement time, minus
	# a bit for the computation time
	usleep(4850000);
	LinuxGpib::ibrd($dev,$reading,11);
	chomp($reading);
	chomp($reading);

	if (substr($reading,0,1) eq "N") {
		$val = substr($reading,1,8);
		}
	else {
		$val = "ERROR";
	}

	if ($val ne "ERROR") {
		my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst)
	  		= gmtime;
		printf LOG 
	  		"%4.4u-%2.2u-%2.2uT%2.2u:%2.2u:%2.2u %s\n",
  			$year+1900,$mon+1,$mday,$hour,$min,$sec,$val;
	}

	# interval is set to about one second too short; the usleep
	# makes it easier to fine-tune the adjustment for processing
	# time to keep the logged interval accurate
	sleep ($interval);
	usleep 700000;

}	
#----------

exit 0;
