kopia lustrzana https://github.com/Hamlib/Hamlib
Support for the SPID Rot2Prog rotator controller, by Norvald H. Ryeng, LA6YKA
git-svn-id: https://hamlib.svn.sourceforge.net/svnroot/hamlib/trunk@2699 7ae35d74-ebe9-4afe-98af-79ac388436b8Hamlib-1.2.10
rodzic
38b3425646
commit
4776b181f6
4
AUTHORS
4
AUTHORS
|
@ -192,6 +192,9 @@ M: Rob Frohne, KL7NA
|
||||||
[rotorez]
|
[rotorez]
|
||||||
M: Nate Bargmann, N0NB
|
M: Nate Bargmann, N0NB
|
||||||
|
|
||||||
|
[spid]
|
||||||
|
M: Norvald H. Ryeng, LA6YKA
|
||||||
|
|
||||||
|
|
||||||
[Frontend]
|
[Frontend]
|
||||||
M: Stephane Fillod, F8CFE
|
M: Stephane Fillod, F8CFE
|
||||||
|
@ -260,3 +263,4 @@ Steve Conklin, AI4QR, <steve (at) conklinhouse.com>
|
||||||
Martin Ewing, AA6E, <aa6e (at) arrl.net>
|
Martin Ewing, AA6E, <aa6e (at) arrl.net>
|
||||||
Terry Embry, KJ4EED, <mrtembry (at) users.sourceforge.net>
|
Terry Embry, KJ4EED, <mrtembry (at) users.sourceforge.net>
|
||||||
Alessandro Zummo, IZ1PRB <alessandro.zummo (at) towertech.it>
|
Alessandro Zummo, IZ1PRB <alessandro.zummo (at) towertech.it>
|
||||||
|
Norvald H. Ryeng, LA6YKA <norvald (at) ryeng.name>
|
||||||
|
|
|
@ -18,7 +18,7 @@ DIST_SUBDIRS = macros include lib libltdl src c++ bindings tests doc \
|
||||||
icom kenwood aor yaesu dummy pcr alinco uniden tentec kachina jrc \
|
icom kenwood aor yaesu dummy pcr alinco uniden tentec kachina jrc \
|
||||||
rpcrig winradio easycomm fodtrack rpcrot drake rotorez \
|
rpcrig winradio easycomm fodtrack rpcrot drake rotorez \
|
||||||
flexradio sartek lowe rft rs tapr kit skanti wj racal tuner \
|
flexradio sartek lowe rft rs tapr kit skanti wj racal tuner \
|
||||||
gs232a heathkit
|
gs232a heathkit spid
|
||||||
|
|
||||||
rpm: Makefile
|
rpm: Makefile
|
||||||
make dist
|
make dist
|
||||||
|
|
|
@ -229,7 +229,7 @@ AC_SUBST(RIGMATRIX)
|
||||||
|
|
||||||
|
|
||||||
BACKEND_LIST="icom kenwood aor yaesu dummy pcr alinco uniden tentec kachina jrc drake lowe rft rs kit skanti tapr flexradio wj racal tuner"
|
BACKEND_LIST="icom kenwood aor yaesu dummy pcr alinco uniden tentec kachina jrc drake lowe rft rs kit skanti tapr flexradio wj racal tuner"
|
||||||
ROT_BACKEND_LIST="dummy easycomm fodtrack gs232a heathkit kit rotorez sartek"
|
ROT_BACKEND_LIST="dummy easycomm fodtrack gs232a heathkit kit rotorez sartek spid"
|
||||||
BINDINGS=""
|
BINDINGS=""
|
||||||
BINDING_ALL=""
|
BINDING_ALL=""
|
||||||
BINDING_CHECK=""
|
BINDING_CHECK=""
|
||||||
|
@ -496,6 +496,7 @@ easycomm/Makefile
|
||||||
fodtrack/Makefile
|
fodtrack/Makefile
|
||||||
gs232a/Makefile
|
gs232a/Makefile
|
||||||
heathkit/Makefile
|
heathkit/Makefile
|
||||||
|
spid/Makefile
|
||||||
sartek/Makefile
|
sartek/Makefile
|
||||||
rpcrig/Makefile
|
rpcrig/Makefile
|
||||||
rpcrot/Makefile
|
rpcrot/Makefile
|
||||||
|
|
|
@ -166,6 +166,16 @@
|
||||||
#define ROT_BACKEND_HEATHKIT "heathkit"
|
#define ROT_BACKEND_HEATHKIT "heathkit"
|
||||||
#define ROT_MODEL_HD1780 ROT_MAKE_MODEL(ROT_HEATHKIT, 1)
|
#define ROT_MODEL_HD1780 ROT_MAKE_MODEL(ROT_HEATHKIT, 1)
|
||||||
|
|
||||||
|
/*! \def ROT_MODEL_SPID
|
||||||
|
* \brief A macro that returns the model number of the SPID backend.
|
||||||
|
*
|
||||||
|
* The SPID backend can be used with rotators that support the SPID
|
||||||
|
* protocol.
|
||||||
|
*/
|
||||||
|
#define ROT_SPID 9
|
||||||
|
#define ROT_BACKEND_SPID "spid"
|
||||||
|
#define ROT_MODEL_SPID ROT_MAKE_MODEL(ROT_SPID, 1)
|
||||||
|
|
||||||
/*! \typedef typedef int rot_model_t
|
/*! \typedef typedef int rot_model_t
|
||||||
\brief Convenience type definition for rotator model.
|
\brief Convenience type definition for rotator model.
|
||||||
*/
|
*/
|
||||||
|
@ -188,6 +198,7 @@ typedef int rot_model_t;
|
||||||
{ ROT_GS232A, ROT_BACKEND_GS232A }, \
|
{ ROT_GS232A, ROT_BACKEND_GS232A }, \
|
||||||
{ ROT_KIT, ROT_BACKEND_KIT }, \
|
{ ROT_KIT, ROT_BACKEND_KIT }, \
|
||||||
{ ROT_HEATHKIT, ROT_BACKEND_HEATHKIT }, \
|
{ ROT_HEATHKIT, ROT_BACKEND_HEATHKIT }, \
|
||||||
|
{ ROT_SPID, ROT_BACKEND_SPID }, \
|
||||||
{ 0, NULL }, /* end */ \
|
{ 0, NULL }, /* end */ \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = hamlib-spid.la
|
||||||
|
hamlib_spid_la_SOURCES = spid.c
|
||||||
|
hamlib_spid_la_LDFLAGS = -no-undefined -module -avoid-version
|
||||||
|
hamlib_spid_la_LIBADD = $(top_builddir)/src/libhamlib.la
|
||||||
|
|
||||||
|
noinst_HEADERS = spid.h
|
|
@ -0,0 +1,294 @@
|
||||||
|
/*
|
||||||
|
* Hamlib Rotator backend - SPID Rot2Prog
|
||||||
|
* Copyright (c) 2009 by Norvald H. Ryeng, LA6YKA
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library 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 Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_CONFIG_H
|
||||||
|
#include "config.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
|
#include "hamlib/rotator.h"
|
||||||
|
#include "serial.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "register.h"
|
||||||
|
|
||||||
|
#include "spid.h"
|
||||||
|
|
||||||
|
#define TOK_AZRES 1
|
||||||
|
#define TOK_ELRES 2
|
||||||
|
|
||||||
|
struct spid_priv_data {
|
||||||
|
int az_resolution;
|
||||||
|
int el_resolution;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int spid_rot_init(ROT *rot)
|
||||||
|
{
|
||||||
|
struct spid_priv_data *priv;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s called\n", __FUNCTION__);
|
||||||
|
|
||||||
|
if (!rot || !rot->caps)
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
|
||||||
|
priv = (struct spid_priv_data*)malloc(sizeof(struct spid_priv_data));
|
||||||
|
if (!priv) {
|
||||||
|
return -RIG_ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
rot->state.priv = (void*)priv;
|
||||||
|
|
||||||
|
priv->az_resolution = 0;
|
||||||
|
priv->el_resolution = 0;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spid_rot_cleanup(ROT *rot)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s called\n", __FUNCTION__);
|
||||||
|
|
||||||
|
if (!rot)
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
|
||||||
|
if (rot->state.priv)
|
||||||
|
free(rot->state.priv);
|
||||||
|
rot->state.priv = NULL;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spid_get_conf(ROT *rot, token_t token, char *val)
|
||||||
|
{
|
||||||
|
struct spid_priv_data *priv = (struct spid_priv_data*)rot->state.priv;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s called %d\n", __FUNCTION__, token);
|
||||||
|
|
||||||
|
switch(token) {
|
||||||
|
case TOK_AZRES:
|
||||||
|
sprintf(val, "%d", priv->az_resolution);
|
||||||
|
break;
|
||||||
|
case TOK_ELRES:
|
||||||
|
sprintf(val, "%d", priv->el_resolution);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spid_set_conf(ROT *rot, token_t token, const char *val)
|
||||||
|
{
|
||||||
|
struct spid_priv_data *priv = (struct spid_priv_data*)rot->state.priv;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s called %d %s\n", __FUNCTION__, token, val);
|
||||||
|
|
||||||
|
switch(token) {
|
||||||
|
case TOK_AZRES:
|
||||||
|
priv->az_resolution = atoi(val);
|
||||||
|
break;
|
||||||
|
case TOK_ELRES:
|
||||||
|
priv->el_resolution = atoi(val);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return -RIG_EINVAL;
|
||||||
|
}
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spid_rot_set_position(ROT *rot, azimuth_t az, elevation_t el)
|
||||||
|
{
|
||||||
|
struct rot_state *rs;
|
||||||
|
rs = &rot->state;
|
||||||
|
struct spid_priv_data *priv = (struct spid_priv_data*)rs->priv;
|
||||||
|
int retval;
|
||||||
|
int retry_read = 0;
|
||||||
|
char cmdstr[13];
|
||||||
|
unsigned int u_az, u_el;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s called: %f %f\n", __FUNCTION__, az, el);
|
||||||
|
|
||||||
|
if (!priv->az_resolution || !priv->el_resolution) {
|
||||||
|
do {
|
||||||
|
retval = write_block(&rs->rotport, "\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\x20", 13);
|
||||||
|
if (retval != RIG_OK) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(cmdstr, 0, 12);
|
||||||
|
retval = read_block(&rs->rotport, cmdstr, 12);
|
||||||
|
} while (retval < 0 && retry_read++ < rot->state.rotport.retry);
|
||||||
|
if (retval < 0)
|
||||||
|
return retval;
|
||||||
|
} else {
|
||||||
|
cmdstr[5] = priv->az_resolution; /* PH */
|
||||||
|
cmdstr[10] = priv->el_resolution; /* PV */
|
||||||
|
}
|
||||||
|
|
||||||
|
u_az = cmdstr[5]*(360 + az);
|
||||||
|
u_el = cmdstr[10]*(360 + el);
|
||||||
|
|
||||||
|
cmdstr[0] = 0x57; /* S */
|
||||||
|
cmdstr[1] = 0x30 + u_az/1000; /* H1 */
|
||||||
|
cmdstr[2] = 0x30 + (u_az % 1000) / 100; /* H2 */
|
||||||
|
cmdstr[3] = 0x30 + (u_az % 100) / 10; /* H3 */
|
||||||
|
cmdstr[4] = 0x30 + (u_az % 10); /* H4 */
|
||||||
|
|
||||||
|
cmdstr[6] = 0x30 + u_el / 1000; /* V1 */
|
||||||
|
cmdstr[7] = 0x30 + (u_el % 1000) / 100; /* V2 */
|
||||||
|
cmdstr[8] = 0x30 + (u_el % 100) / 10; /* V3 */
|
||||||
|
cmdstr[9] = 0x30 + (u_el % 10); /* V4 */
|
||||||
|
|
||||||
|
cmdstr[11] = 0x2F; /* K */
|
||||||
|
cmdstr[12] = 0x20; /* END */
|
||||||
|
|
||||||
|
retval = write_block(&rs->rotport, cmdstr, 13);
|
||||||
|
if (retval != RIG_OK) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spid_rot_get_position(ROT *rot, azimuth_t *az, elevation_t *el)
|
||||||
|
{
|
||||||
|
struct rot_state *rs;
|
||||||
|
rs = &rot->state;
|
||||||
|
int retval;
|
||||||
|
int retry_read = 0;
|
||||||
|
char posbuf[12];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s called\n", __FUNCTION__);
|
||||||
|
|
||||||
|
do {
|
||||||
|
retval = write_block(&rs->rotport, "\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x1F\x20", 13);
|
||||||
|
if (retval != RIG_OK) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(posbuf, 0, 12);
|
||||||
|
retval = read_block(&rs->rotport, posbuf, 12);
|
||||||
|
} while (retval < 0 && retry_read++ < rot->state.rotport.retry);
|
||||||
|
if (retval < 0)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
*az = posbuf[1] * 100;
|
||||||
|
*az += posbuf[2] * 10;
|
||||||
|
*az += posbuf[3];
|
||||||
|
*az += posbuf[4] / 10.0;
|
||||||
|
*az -= 360;
|
||||||
|
|
||||||
|
*el = posbuf[6] * 100;
|
||||||
|
*el += posbuf[7] * 10;
|
||||||
|
*el += posbuf[8];
|
||||||
|
*el += posbuf[9] / 10.0;
|
||||||
|
*el -= 360;
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s: (az, el) = (%.1f, %.1f)\n",
|
||||||
|
__FUNCTION__, *az, *el);
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int spid_rot_stop(ROT *rot)
|
||||||
|
{
|
||||||
|
struct rot_state *rs;
|
||||||
|
int retval;
|
||||||
|
rs = &rot->state;
|
||||||
|
int retry_read = 0;
|
||||||
|
char posbuf[12];
|
||||||
|
|
||||||
|
rig_debug(RIG_DEBUG_TRACE, "%s called\n", __FUNCTION__);
|
||||||
|
|
||||||
|
do {
|
||||||
|
retval = write_block(&rs->rotport, "\x57\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0F\x20", 13);
|
||||||
|
if (retval != RIG_OK) {
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(posbuf, 0, 12);
|
||||||
|
retval = read_block(&rs->rotport, posbuf, 12);
|
||||||
|
} while (retval < 0 && retry_read++ < rot->state.rotport.retry);
|
||||||
|
if (retval < 0)
|
||||||
|
return retval;
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct confparams spid_cfg_params[] = {
|
||||||
|
{ TOK_AZRES, "az_resolution", "Azimuth resolution", "Number of pulses per degree, 0 = auto sense",
|
||||||
|
"0", RIG_CONF_NUMERIC, { .n = { 0, 0xff, 1 } }
|
||||||
|
},
|
||||||
|
{ TOK_ELRES, "el_resolution", "Eleveation resolution", "Number of pulses per degree, 0 = auto sense",
|
||||||
|
"0", RIG_CONF_NUMERIC, { .n = { 0, 0xff, 1 } }
|
||||||
|
},
|
||||||
|
{ RIG_CONF_END, NULL, }
|
||||||
|
};
|
||||||
|
|
||||||
|
const struct rot_caps spid_rot_caps = {
|
||||||
|
.rot_model = ROT_MODEL_SPID,
|
||||||
|
.model_name = "Rot2Prog",
|
||||||
|
.mfg_name = "SPID",
|
||||||
|
.version = "0.1",
|
||||||
|
.copyright = "LGPL",
|
||||||
|
.status = RIG_STATUS_UNTESTED,
|
||||||
|
.rot_type = ROT_TYPE_OTHER,
|
||||||
|
.port_type = RIG_PORT_SERIAL,
|
||||||
|
.serial_rate_min = 600,
|
||||||
|
.serial_rate_max = 1200,
|
||||||
|
.serial_data_bits = 8,
|
||||||
|
.serial_stop_bits = 1,
|
||||||
|
.serial_parity = RIG_PARITY_NONE,
|
||||||
|
.serial_handshake = RIG_HANDSHAKE_NONE,
|
||||||
|
.write_delay = 0,
|
||||||
|
.post_write_delay = 0,
|
||||||
|
.timeout = 400,
|
||||||
|
.retry = 3,
|
||||||
|
|
||||||
|
.min_az = -180.0,
|
||||||
|
.max_az = 540.0,
|
||||||
|
.min_el = -20.0,
|
||||||
|
.max_el = 210.0,
|
||||||
|
|
||||||
|
.cfgparams = spid_cfg_params,
|
||||||
|
.get_conf = spid_get_conf,
|
||||||
|
.set_conf = spid_set_conf,
|
||||||
|
|
||||||
|
.rot_init = spid_rot_init,
|
||||||
|
.rot_cleanup = spid_rot_cleanup,
|
||||||
|
.get_position = spid_rot_get_position,
|
||||||
|
.set_position = spid_rot_set_position,
|
||||||
|
.stop = spid_rot_stop,
|
||||||
|
};
|
||||||
|
|
||||||
|
DECLARE_INITROT_BACKEND(spid)
|
||||||
|
{
|
||||||
|
rig_debug(RIG_DEBUG_VERBOSE, "%s called\n", __FUNCTION__);
|
||||||
|
|
||||||
|
rot_register(&spid_rot_caps);
|
||||||
|
|
||||||
|
return RIG_OK;
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
/*
|
||||||
|
* Hamlib Rotator backend - SPID Rot2Prog
|
||||||
|
* Copyright (c) 2009 by Norvald H. Ryeng, LA6YKA
|
||||||
|
*
|
||||||
|
* $Id$
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library 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 Library General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Library General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _ROT_SPID_H
|
||||||
|
#define _ROT_SPID_H 1
|
||||||
|
|
||||||
|
extern const struct rot_caps spid_rot_caps;
|
||||||
|
|
||||||
|
#endif /* _ROT_SPID_H */
|
|
@ -0,0 +1,208 @@
|
||||||
|
SPID Rot2Prog Protocol
|
||||||
|
======================
|
||||||
|
|
||||||
|
This is an attempt at documenting the protocol of the Rot2Prog rotator
|
||||||
|
controller from SPID Elektronik (spid@alpha.pl). The protocol is
|
||||||
|
supposed to be similar on Rot1Prog and Rot2Prog, but the specification
|
||||||
|
in this document has only been tested on Rot2Prog.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
GENERAL INFO
|
||||||
|
------------
|
||||||
|
|
||||||
|
The SPID protocol supports 3 commands: stop, status and set. The stop
|
||||||
|
command stops the rotator in its current position. The status command
|
||||||
|
returns the current position of the rotator, and the set command tells
|
||||||
|
the rotator to rotate to a given position.
|
||||||
|
|
||||||
|
The rotator controller communicates with the PC using a serial
|
||||||
|
port. Communication parameters are 600 bps, 8 bits, no parity and 1
|
||||||
|
stop bit. (Rot1Prog uses 1200 bps.)
|
||||||
|
|
||||||
|
All commands are issued as 13 byte packets, and responses are received
|
||||||
|
as 12 byte packets.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
COMMAND PACKETS
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Command packets are 13 byte long.
|
||||||
|
|
||||||
|
Byte: 0 1 2 3 4 5 6 7 8 9 10 11 12
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
Field: | S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | K | END |
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
Value: 57 3x 3x 3x 3x 0x 3x 3x 3x 3x 0x xF 20 (hex)
|
||||||
|
|
||||||
|
|
||||||
|
S: Start byte. This is always 0x57 ('W')
|
||||||
|
|
||||||
|
H1-H4: Azimuth as ASCII characters 0-9
|
||||||
|
|
||||||
|
PH: Azimuth resolution in pulses per degree (ignored!)
|
||||||
|
|
||||||
|
V1-V4: Elevation as ASCII characters 0-9
|
||||||
|
|
||||||
|
PV: Elevation resolution in pulses per degree (ignored!)
|
||||||
|
|
||||||
|
K: Command (0x0F=stop, 0x1F=status, 0x2F=set)
|
||||||
|
|
||||||
|
END: End byte. This is always 0x20 (space)
|
||||||
|
|
||||||
|
|
||||||
|
Positions are encoded as number of pulses in ASCII numbers
|
||||||
|
'0000'-'9999' (see set command for formula).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
RESPONSE PACKETS
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Response packets are 12 byte long.
|
||||||
|
|
||||||
|
Byte: 0 1 2 3 4 5 6 7 8 9 10 11
|
||||||
|
-------------------------------------------------------------
|
||||||
|
Field: | S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | END |
|
||||||
|
-------------------------------------------------------------
|
||||||
|
Value: 57 3x 3x 3x 3x 0x 3x 3x 3x 3x 0x 20 (hex)
|
||||||
|
|
||||||
|
|
||||||
|
S: Start byte. This is always 0x57 ('W')
|
||||||
|
|
||||||
|
H1-H4: Azimuth as byte values
|
||||||
|
|
||||||
|
PH: Azimuth resolution in pulses per degree (controller setting)
|
||||||
|
|
||||||
|
V1-V4: Elevation as byte values
|
||||||
|
|
||||||
|
PV: Elevation resolution in pulses per degree (controller setting)
|
||||||
|
|
||||||
|
END: End byte. This is always 0x20 (space)
|
||||||
|
|
||||||
|
|
||||||
|
Positions are decoded using the following formulas:
|
||||||
|
|
||||||
|
az = H1 * 100 + H2 * 10 + H3 + H4 / 10 - 360
|
||||||
|
|
||||||
|
el = V1 * 100 + V2 * 10 + V3 + V4 / 10 - 360
|
||||||
|
|
||||||
|
|
||||||
|
The PH and PV values in the response packet reflect the settings of
|
||||||
|
the rotator controller. The Rot2Prog supports the following
|
||||||
|
resolutions (always the same for azimuth and elevation):
|
||||||
|
|
||||||
|
1 pulse/deg: PH=0x01, PV=0x01
|
||||||
|
0.5 pulse/deg: PH=0x02, PV=0x02
|
||||||
|
0.25 pulse/deg: PH=0x04, PV=0x04
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
STOP COMMAND
|
||||||
|
------------
|
||||||
|
|
||||||
|
The stop command stops the rotator immediately in the current
|
||||||
|
position and returns the current position. (The position returned does
|
||||||
|
not seem to be entirely correct, often off by a degree or two.)
|
||||||
|
|
||||||
|
The H1-H4, PH, V1-V4 and PV fields are ignored, so only the S, K and
|
||||||
|
END fields are used. E.g.:
|
||||||
|
|
||||||
|
Command:
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
| S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | K | END |
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
| 57| 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 0F| 20 | (hex)
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
Rotator stops
|
||||||
|
|
||||||
|
Response:
|
||||||
|
-------------------------------------------------------------
|
||||||
|
| S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | END |
|
||||||
|
-------------------------------------------------------------
|
||||||
|
| 57| 03 | 07 | 02 | 05 | 02 | 03 | 09 | 04 | 00 | 02 | 20 | (hex)
|
||||||
|
-------------------------------------------------------------
|
||||||
|
az=372.5-360=12.5, el=394.0-360=34.0
|
||||||
|
PH=PV=0x02 (pulse for each 0.5 deg)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
STATUS COMMAND
|
||||||
|
--------------
|
||||||
|
|
||||||
|
The status command returns the current position of the antenna.
|
||||||
|
|
||||||
|
The H1-H4, PH, V1-V4 and PV fields are ignored, so only the S, K and
|
||||||
|
END fields are used. E.g.:
|
||||||
|
|
||||||
|
Command:
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
| S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | K | END |
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
| 57| 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 00 | 1F| 20 | (hex)
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
Response:
|
||||||
|
-------------------------------------------------------------
|
||||||
|
| S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | END |
|
||||||
|
-------------------------------------------------------------
|
||||||
|
| 57| 03 | 07 | 02 | 05 | 02 | 03 | 09 | 04 | 00 | 02 | 20 | (hex)
|
||||||
|
-------------------------------------------------------------
|
||||||
|
az=372.5-360=12.5, el=394.0-360=34.0
|
||||||
|
PH=PV=0x02 (pulse for each 0.5 deg)
|
||||||
|
|
||||||
|
|
||||||
|
Status commands can be issued while the rotator is moving and will
|
||||||
|
always return the current position.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SET COMMAND
|
||||||
|
-----------
|
||||||
|
|
||||||
|
The set command tells the rotator to turn to a specific
|
||||||
|
position. The controller does not send a response to this command.
|
||||||
|
|
||||||
|
Azimuth and elevation is calculated as number of pulses, with a +360
|
||||||
|
degree offset (so that negative position can be encoded with positive
|
||||||
|
numbers).
|
||||||
|
|
||||||
|
H = PH * (360 + az)
|
||||||
|
|
||||||
|
V = PV * (360 + el)
|
||||||
|
|
||||||
|
H1-H4 and V1-V4 are these numbers encoded as ASCII (0x30-0x39,
|
||||||
|
i.e. '0'-'9').
|
||||||
|
|
||||||
|
E.g., when pointing to azimuth 123.5, elevation 77.0 when the rotator
|
||||||
|
sends one pulse per 0.5 degree (PH=PV=2):
|
||||||
|
|
||||||
|
|
||||||
|
H = 2 * (360 + 123.5) = 967
|
||||||
|
|
||||||
|
V = 2 * (360 + 77.0) = 874
|
||||||
|
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
| S | H1 | H2 | H3 | H4 | PH | V1 | V2 | V3 | V4 | PV | K | END |
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
| 57| 30 | 39 | 36 | 37 | 02 | 30 | 38 | 37 | 34 | 02 | 2F| 20 | (hex)
|
||||||
|
-----------------------------------------------------------------
|
||||||
|
|
||||||
|
The PH and PV values sent are ignored. The values used by the rotator
|
||||||
|
control unit are set by choosing resolution in the setup
|
||||||
|
menu. Luckily, these values can be read using the status command.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
SEE ALSO
|
||||||
|
--------
|
||||||
|
http://alfaradio.ca/downloads/program_info/
|
||||||
|
|
||||||
|
|
||||||
|
AUTHOR
|
||||||
|
------
|
||||||
|
|
||||||
|
Norvald H. Ryeng, LA6YKA
|
||||||
|
norvald@ryeng.name
|
||||||
|
2009-05-21
|
Ładowanie…
Reference in New Issue