#!/usr/bin/perl -w
#
# freq-logger.pl
# version 0.5 -- 5 February 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 pause);
use Getopt::Std;
use Time::HiRes qw(usleep setitimer ITIMER_REAL);
use DateTime;
use LinuxGpib;
use n8ur qw(trim round);
use n8ur_gpib;

# frequencies to scan in MHz and comma-separated
my @freqs = (162.400,162.425,162.450,162.475,162.500,162.525,162.550);

# default interval to run (seconds)
my $interval = 300;

# device name from /etc/gpib.conf
my $device = "hp8920b";
my $dev = LinuxGpib::ibfind($device);

#----------
# display usage
my $opt_string = 'dhi:f:';

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

usage: $0 [-dh] [-i interval] -f logfile

-d	: run as daemon
-h	: this (help) message
-i	: interval for measurements, in seconds (>=60
-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};

# run as daemon?
&daemonize if $opt{d};

# override interval
if ($opt{i}) {
	$interval = $opt{i};
	}

# log file
my $logfile = $opt{f};
open (LOG, ">>$logfile") || die "Can't open logfile $logfile!\n";


#----------
# 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';
#----------
# daemonize
sub daemonize {
	chdir '/' or die "Can't chdir to /: $!";
	umask 0;
	open STDIN, '/dev/null' or die "Can't read /dev/null: $!";
	open STDOUT, '>/dev/null' or die "Can't write to /dev/null: $!";
	open STDERR, '>/dev/null' or die "Can't write to /dev/null: $!";
	defined(my $pid = fork) or die "Can't fork: $!";
	exit if $pid;
	setsid or die "Can't start a new session: $!";
}
#-----------
# for pause routine
# signal handler is empty
$SIG{ALRM} = sub { };
setitimer(ITIMER_REAL, 1, $interval);
#----------

sub get_readings {
	my $command = "";
	my $set_freq; 
	my $results = "";
	my $reading = 0;
	my @freq_array = @freqs;

	foreach (@freq_array) {
		$set_freq = $_;
		$command = "SAN:CFR $set_freq MHZ";
		LinuxGpib::ibwrt($dev,$command,length($command));

		$command = "SAN:TRACE:MHOLD 'Avg 10'";
		LinuxGpib::ibwrt($dev,$command,length($command));

		sleep 8;

		$command = "MEAS:SAN:MARK:LEV?";
		LinuxGpib::ibwrt($dev,$command,length($command));
		LinuxGpib::ibrd($dev,$reading,128) || die "Nothing read!\n";

		$command = "SAN:TRACE:MHOLD 'Off'";
		LinuxGpib::ibwrt($dev,$command,length($command));
		usleep(100000);

		$results .= sprintf "%.1F ",round(1,trim($reading));

	}
	trim($results);
}

#----------
# initialize device
my $command = "*RST";
LinuxGpib::ibwrt($dev,$command,length($command));
$command = "DISP SAN";
LinuxGpib::ibwrt($dev,$command,length($command));
$command = "SAN:INPUT 'Ant'";
LinuxGpib::ibwrt($dev,$command,length($command));
$command = "SAN:RLEV -40DBM";
LinuxGpib::ibwrt($dev,$command,length($command));
$command = "SAN:SPAN 50KHZ";
LinuxGpib::ibwrt($dev,$command,length($command));
$command = "*WAI";
LinuxGpib::ibwrt($dev,$command,length($command));
#----------

my $work;

# write header line
my $dt = DateTime->now;
my $iso_time = $dt->ymd('-') . 'T' . $dt->hms(':');
my $mjd_time = $dt->mjd;
printf LOG "# Run started at %s (MJD %11.6F), interval %d seconds.\n",
	$iso_time,round(6,$mjd_time),$interval;
print LOG "# Logging signal strength in dBm of these frequencies (MHz):\n";
print LOG "# ";
foreach (@freqs) {
	printf LOG "%.3F ",$_;
	}
print LOG "\n";
	
while (1) {
	pause;
	$work = get_readings;
	$dt = DateTime->now;
	$mjd_time = round(6,$dt->mjd);
	printf LOG "%11.6F %s\n",$mjd_time,$work;
}
exit 0;
