From bc2f026beeba9a73d7719db9aa20dfa00406f397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Fillod=2C=20F8CFE?= Date: Mon, 21 May 2007 20:02:57 +0000 Subject: [PATCH] initial release git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@2197 7ae35d74-ebe9-4afe-98af-79ac388436b8 --- tests/rigsmtr.1 | 132 ++++++++++++++++ tests/rigsmtr.c | 395 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 527 insertions(+) create mode 100644 tests/rigsmtr.1 create mode 100644 tests/rigsmtr.c diff --git a/tests/rigsmtr.1 b/tests/rigsmtr.1 new file mode 100644 index 000000000..317b797a1 --- /dev/null +++ b/tests/rigsmtr.1 @@ -0,0 +1,132 @@ +.\" Hey, EMACS: -*- nroff -*- +.\" First parameter, NAME, should be all caps +.\" Second parameter, SECTION, should be 1-8, maybe w/ subsection +.\" other parameters are allowed: see man(7), man(1) +.TH RIGSMTR "1" "February 26, 2006" "Hamlib" +.\" Please adjust this date whenever revising the manpage. +.\" +.\" Some roff macros, for reference: +.\" .nh disable hyphenation +.\" .hy enable hyphenation +.\" .ad l left justify +.\" .ad b justify to both left and right margins +.\" .nf disable filling +.\" .fi enable filling +.\" .br insert line break +.\" .sp insert n+1 empty lines +.\" for manpage-specific macros, see man(7) +.SH NAME +rigswr \- measure S-Meter vs azimuth using Hamlib +.SH SYNOPSIS +.B rigswr +[\fIOPTION\fR]... start_freq stop_freq [freq_step] +.SH DESCRIPTION +\fBrigswr\fP uses Hamlib to control a rig to measure S-Meter vs azimuth: +.br +It scans frequencies from start_freq to stop_freq with step freq_step. +For each frequency, it transmits at 25% of total POWER during 0.5 second in CW mode +and read VSWR. +.br +Azimuth in degree and corresponding S-Meter level in dB relative to S9 are then printed on stdout. +.br +To work correctly, rigsmtr needs a rig that could measure S-Meter and a Hamlib backend that +is able to get it. +.PP +.\" TeX users may be more comfortable with the \fB\fP and +.\" \fI\fP escape sequences to invode bold face and italics, +.\" respectively. +Keep in mind that \fBHamlib\fP is still BETA level software. +A lof of stuff hasn't been tested thoroughly, and the API may change +without publicised notice. Please report bugs and feedback at +the e-mail address given in the REPORTING BUGS section. +.SH OPTIONS +This program follow the usual GNU command line syntax, with long +options starting with two dashes (`-'). +A summary of options is included below. +.TP +.B \-m, \-\-model=id +Select radio model number. See model list provided by rigctl. +.TP +.B \-r, --rig-file=device +Use \fBdevice\fP as the file name of the radio to operate on. +.TP +.B \-s, --serial-speed=baud +Set serial speed to \fBbaud\fP rate. Uses maximal rig speed as default. +.TP +.B \-c, --civaddr=id +Use \fBid\fP as the CI-V address to communicate with the rig. +Only for Icom rigs. NB: the id is in decimal, unless prefixed by \fB0x\fP, +in which case it is hexadecimal. +.TP +.B \-p, --ptt-file=device +Use \fBdevice\fP as the file name of the Push-To-Talk device to operate on. +This is only needed if the radio doesn't have legacy PTT control. +.TP +.B \-p, --ptt-type=type +Use \fBtype\fP device as the kind of the Push-To-Talk device to operate on. +Supported types are RIG, DTR, RTS, PARALLEL, NONE. +This is only needed if the radio doesn't have legacy PTT control. +.TP +.B \-C, \-\-set\-conf=parm=val[,parm=val]* +Set config parameter. See -L option of rigctl for a list. +.TP +.B \-v, \-\-verbose +Set verbose mode, cumulative (BUG, ERR, WARN, VERBOSE, TRACE). +.TP +.B \-h, \-\-help +Show summary of options and exit. +.TP +.B \-V, \-\-version +Show version of program and exit. + +.SH RETURN VALUE +rigswr exits with: +0 if all operations went fine; 1 if there was an invalid command line +option or arg; 2 if an error was returned by Hamlib; 3 if the rig +doesn't have the required capabilities. + +.SH EXAMPLE +rigswr -m 209 -r /dev/tty1 14000000 14350000 50000 > cswr + +.br +Scans frequencies between 14MHz and 14.200MHz with 50KHz step on a TS850 and +record VSWR measurements in file cswr. +.br +After completion, cswr file contains the following lines : +.br + 14000000 1.50 +.br + 14050000 1.31 +.br + 14100000 1.22 +.br + 14150000 1.07 +.br + 14200000 1.07 + +.TP +Result could then be ploted with gnuplot: +.br +gnuplot +.br +set data style linespoints +.br +set grid +.br +plot "cswr" +.SH AUTHOR +Man page written by Thierry Leconte & Stephane Fillod . +.SH BUGS +Depending on keyer/QSK setup, transmits in CW mode may not be modulated +thus giving possibly wrong result. Please report this situation if it happens. +.SH REPORTING BUGS +Report bugs to . +.SH COPYRIGHT +Copyright \(co 2004-2006 Thierry Leconte & Stephane Fillod +.br +This is free software; see the source for copying conditions. +There is NO warranty; not even for MERCHANTABILITY +or FITNESS FOR A PARTICULAR PURPOSE. +.SH SEE ALSO +.BR hamlib (3), rigctl(1) + diff --git a/tests/rigsmtr.c b/tests/rigsmtr.c new file mode 100644 index 000000000..7c81d595c --- /dev/null +++ b/tests/rigsmtr.c @@ -0,0 +1,395 @@ +/* + * rigsmtr.c - (C) Stephane Fillod + * + * This program output S-meter curve value using Hamlib. + * + * $Id: rigsmtr.c,v 1.1 2007-05-21 20:02:57 fillods Exp $ + * + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + */ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include "misc.h" + + +/* + * Prototypes + */ +static void usage(); +static void version(); +static int set_conf_rig(RIG *rig, char *conf_parms); +static int set_conf_rot(ROT *rot, char *conf_parms); + +/* + * Reminder: when adding long options, + * keep up to date SHORT_OPTIONS, usage()'s output and man page. thanks. + * NB: do NOT use -W since it's reserved by POSIX. + */ +#define SHORT_OPTIONS "m:r:s:c:C:M:R:S:N:vhV" +static struct option long_options[] = +{ + {"model", 1, 0, 'm'}, + {"rig-file", 1, 0, 'r'}, + {"serial-speed", 1, 0, 's'}, + {"civaddr", 1, 0, 'c'}, + {"set-conf", 1, 0, 'C'}, + {"rot-model", 1, 0, 'M'}, + {"rot-file", 1, 0, 'R'}, + {"rot-serial-speed", 1, 0, 'S'}, + {"rot-set-conf", 1, 0, 'N'}, + {"verbose", 0, 0, 'v'}, + {"help", 0, 0, 'h'}, + {"version", 0, 0, 'V'}, + {0, 0, 0, 0} +}; + +#define MAXCONFLEN 128 + + +int main (int argc, char *argv[]) +{ + RIG *rig; /* handle to rig (instance) */ + ROT *rot; /* handle to rotator (instance) */ + rig_model_t rig_model = RIG_MODEL_DUMMY; + rot_model_t rot_model = ROT_MODEL_DUMMY; + + int retcode; /* generic return code from functions */ + + int verbose = 0; + const char *rig_file=NULL, *rot_file=NULL; + int serial_rate = 0; + int rot_serial_rate = 0; + char *civaddr = NULL; /* NULL means no need to set conf */ + char rig_conf_parms[MAXCONFLEN] = ""; + char rot_conf_parms[MAXCONFLEN] = ""; + + int with_rot = 1; + azimuth_t azimuth; + elevation_t elevation; + + while(1) { + int c; + int option_index = 0; + + c = getopt_long (argc, argv, SHORT_OPTIONS, + long_options, &option_index); + if (c == -1) + break; + + switch(c) { + case 'h': + usage(); + exit(0); + case 'V': + version(); + exit(0); + case 'm': + if (!optarg) { + usage(); /* wrong arg count */ + exit(1); + } + rig_model = atoi(optarg); + break; + case 'r': + if (!optarg) { + usage(); /* wrong arg count */ + exit(1); + } + rig_file = optarg; + break; + case 'c': + if (!optarg) { + usage(); /* wrong arg count */ + exit(1); + } + civaddr = optarg; + break; + case 's': + if (!optarg) { + usage(); /* wrong arg count */ + exit(1); + } + serial_rate = atoi(optarg); + break; + case 'C': + if (!optarg) { + usage(); /* wrong arg count */ + exit(1); + } + if (*rig_conf_parms != '\0') + strcat(rig_conf_parms, ","); + strncat(rig_conf_parms, optarg, MAXCONFLEN-strlen(rig_conf_parms)); + break; + case 'M': + if (!optarg) { + usage(); /* wrong arg count */ + exit(1); + } + rot_model = atoi(optarg); + break; + case 'R': + if (!optarg) { + usage(); /* wrong arg count */ + exit(1); + } + rot_file = optarg; + break; + case 'S': + if (!optarg) { + usage(); /* wrong arg count */ + exit(1); + } + rot_serial_rate = atoi(optarg); + break; + case 'N': + if (!optarg) { + usage(); /* wrong arg count */ + exit(1); + } + if (*rot_conf_parms != '\0') + strcat(rot_conf_parms, ","); + strncat(rot_conf_parms, optarg, MAXCONFLEN-strlen(rot_conf_parms)); + break; + case 'v': + verbose++; + break; + default: + usage(); /* unknown option? */ + exit(1); + } + } + + rig_set_debug(verbose<2 ? RIG_DEBUG_WARN: verbose); + + rig_debug(RIG_DEBUG_VERBOSE, "rigsmtr, %s\n", hamlib_version); + rig_debug(RIG_DEBUG_VERBOSE, "Report bugs to " + "\n\n"); + + if (optind+1 >= argc) { + usage(); + exit(1); + } + + /* + * The radio + */ + rig = rig_init(rig_model); + + if (!rig) { + fprintf(stderr, "Unknown rig num %d, or initialization error.\n", + rig_model); + fprintf(stderr, "Please check with --list option.\n"); + exit(2); + } + + retcode = set_conf_rig(rig, rig_conf_parms); + if (retcode != RIG_OK) { + fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); + exit(2); + } + + if (rig_file) + strncpy(rig->state.rigport.pathname, rig_file, FILPATHLEN); + + /* FIXME: bound checking and port type == serial */ + if (serial_rate != 0) + rig->state.rigport.parm.serial.rate = serial_rate; + if (civaddr) + rig_set_conf(rig, rig_token_lookup(rig, "civaddr"), civaddr); + + + if(!rig_has_get_level(rig,RIG_LEVEL_STRENGTH)) { + fprintf(stderr,"rig backend for %s could not get S-Meter" + "or has unsufficient capability\nSorry\n", + rig->caps->model_name); + exit(3); + } + + retcode = rig_open(rig); + if (retcode != RIG_OK) { + fprintf(stderr,"rig_open: error = %s \n", rigerror(retcode)); + exit(2); + } + + if (verbose > 0) + printf("Opened rig model %d, '%s'\n", rig->caps->rig_model, + rig->caps->model_name); + + /* + * The rotator + */ + rot = rot_init(rot_model); + + if (!rot) { + fprintf(stderr, "Unknown rot num %d, or initialization error.\n", + rot_model); + fprintf(stderr, "Please check with --list option.\n"); + exit(2); + } + + retcode = set_conf_rot(rot, rot_conf_parms); + if (retcode != RIG_OK) { + fprintf(stderr, "Config parameter error: %s\n", rigerror(retcode)); + exit(2); + } + + if (rot_file) + strncpy(rot->state.rotport.pathname, rot_file, FILPATHLEN); + + /* FIXME: bound checking and port type == serial */ + if (serial_rate != 0) + rot->state.rotport.parm.serial.rate = serial_rate; + + retcode = rot_open(rot); + if (retcode != RIG_OK && rot_model != ROT_MODEL_DUMMY) { + fprintf(stderr,"rot_open: error = %s \n", rigerror(retcode)); + exit(2); + } + + if (rot_model == ROT_MODEL_DUMMY) + with_rot = 1; + + if (verbose > 0) + printf("Opened rotator model %d, '%s'\n", rot->caps->rot_model, + rot->caps->model_name); + + + /*******************************/ + /* argv[optind++] */ +#if 0 + if (optind < argc) + step=atof(argv[optind]); +#endif + fprintf(stderr,"Setting rotator to azimuth %.1f°\n",rot->state.min_az); + rot_set_position (rot, rot->state.min_az, 0); + fprintf(stderr,"Wait for rotator to move...\n"); + rot_get_position (rot, &azimuth, &elevation); + while (fabs(azimuth - rot->state.min_az) > 1.) { + rot_get_position (rot, &azimuth, &elevation); + usleep(1000000); + } + + fprintf(stderr,"Now initiating full 360° rotation...\n"); + rot_set_position (rot, rot->state.max_az, 0); + + /* TODO: check CW or CCW */ + /* disable AGC */ + + while (fabs(rot->state.max_az - azimuth) > 1.) { + value_t strength; + + rig_get_level(rig,RIG_VFO_CURR,RIG_LEVEL_STRENGTH,&strength); + + rot_get_position (rot, &azimuth, &elevation); + + printf("%.1f %d\n", azimuth, strength.i); + } + + rig_close(rig); + rot_close(rot); + + return 0; +} + + + +void version() +{ + printf("rigsmtr, %s\n\n", hamlib_version); + printf("%s\n", hamlib_copyright); +} + +void usage() +{ + printf("Usage: rigsmtr [OPTION]... [time]\n" + "Input S-Meter vs Azimuth.\n\n"); + + printf( + " -m, --model=ID select radio model number. See model list\n" + " -r, --rig-file=DEVICE set device of the radio to operate on\n" + " -s, --serial-speed=BAUD set serial speed of the serial port\n" + " -c, --civaddr=ID set CI-V address, decimal (for Icom rigs only)\n" + " -C, --set-conf=PARM=VAL set config parameters\n" + " -M, --rot-model=ID select rotator model number. See model list\n" + " -R, --rot-file=DEVICE set device of the rotator to operate on\n" + " -S, --rot-serial-speed=BAUD set serial speed of the serial port\n" + " -N, --rot-set-conf=PARM=VAL set rotator config parameters\n" + " -v, --verbose set verbose mode, cumulative\n" + " -h, --help display this help and exit\n" + " -V, --version output version information and exit\n\n" + ); + + printf("\nReport bugs to .\n"); + +} + +int set_conf_rig(RIG *rig, char *conf_parms) +{ + char *p, *q, *n; + int ret; + + p = conf_parms; + while (p && *p != '\0') { + /* FIXME: left hand value of = cannot be null */ + q = strchr(p, '='); + if (q) *q++ = '\0'; + n = strchr(q, ','); + if (n) *n++ = '\0'; + + ret = rig_set_conf(rig, rig_token_lookup(rig, p), q); + if (ret != RIG_OK) + return ret; + p = n; + } + return RIG_OK; +} + +int set_conf_rot(ROT *rot, char *conf_parms) +{ + char *p, *q, *n; + int ret; + + p = conf_parms; + while (p && *p != '\0') { + /* FIXME: left hand value of = cannot be null */ + q = strchr(p, '='); + if (q) *q++ = '\0'; + n = strchr(q, ','); + if (n) *n++ = '\0'; + + ret = rot_set_conf(rot, rot_token_lookup(rot, p), q); + if (ret != RIG_OK) + return ret; + p = n; + } + return RIG_OK; +}