2088 lines
69 KiB
C
Executable File
2088 lines
69 KiB
C
Executable File
#define ident "1A07"
|
||
#define Active_Server 1
|
||
#define Blink_On 0
|
||
|
||
#ifdef __DECC
|
||
#pragma module EL734 ident
|
||
#endif
|
||
/*
|
||
** +--------------------------------------------------------------+
|
||
** | Paul Scherrer Institute |
|
||
** | SINQ Project |
|
||
** | |
|
||
** | This software may be used freely by non-profit organizations.|
|
||
** | It may be copied provided that the name of P.S.I. and of the |
|
||
** | author is included. Neither P.S.I. nor the author assume any |
|
||
** | responsibility for the use of this software outside of P.S.I.|
|
||
** +--------------------------------------------------------------+
|
||
**
|
||
** Link_options - Here is the Linker Option File
|
||
**!$!
|
||
**!$! To build on LNSA09 ...
|
||
**!$! $ build_cc_select :== decc
|
||
**!$! $ import tasmad
|
||
**!$! $ def/job deltat_c_tlb sinq_c_tlb
|
||
**!$! $ bui ud0:[maden.motor]el734 debug
|
||
**!$!
|
||
**!$! To build on PSICL0 ...
|
||
**!$! $ build_cc_select :== decc
|
||
**!$! $ set default usr_scroot:[maden]
|
||
**!$! $ copy lnsa09::ud0:[maden.motor]el734.c []
|
||
**!$! $ copy lnsa09::tasmad_disk:[mad.lib]sinq_dbg.olb []
|
||
**!$! $ copy lnsa09::tasmad_disk:[mad.lib]sinq_c.tlb []
|
||
**!$! $ def/job sinq_olb usr_scroot:[maden]sinq_dbg.olb
|
||
**!$! $ def/job sinq_c_tlb usr_scroot:[maden]sinq_c.tlb
|
||
**!$! $ def/job deltat_c_tlb sinq_c_tlb
|
||
**!$! $ bui el734 debug
|
||
**!$!
|
||
**!$ if p1 .eqs. "DEBUG" then dbg1 := /debug
|
||
**!$ if p1 .eqs. "DEBUG" then dbg2 := _dbg
|
||
**!$ link 'dbg1'/exe=cpt:[exe]el734'dbg2'.exe sys$input/options
|
||
**! el734
|
||
**! sinq_olb/lib
|
||
**! sys$share:decw$xmlibshr12.exe/share
|
||
**! sys$share:decw$xtlibshrr5.exe/share
|
||
**!$ purge/nolog cpt:[exe]el734'dbg2'.exe
|
||
**!$ exit
|
||
**!$!
|
||
** Link_options_end
|
||
**
|
||
** Building on Alpha Digital Unix:
|
||
**
|
||
** setenv TAS_BASE ~maden/tasmad
|
||
** source $TAS_BASE/tasmad.setup
|
||
** rcp -p "lnsa09:tas_src:[utils]el734.c" \
|
||
** $TAS_SRC/utils/el734.c
|
||
** cc -std -g -o $TAS_BIN/el734 \
|
||
** -I$TAS_INC \
|
||
** $TAS_SRC/utils/el734.c \
|
||
** -L$TAS_LIB -lsinq -lXm -lXt -lX11
|
||
**+
|
||
** Resource File: decw$user_defaults:SinQ_rc.dat
|
||
** ------------- or $HOME/SinQ_rc
|
||
**
|
||
** *el734Host: Undefined <-- the name of the server
|
||
** *el734Port: 4000 <-- the port of the server
|
||
** *el734Chan: 0 <-- the RS232C channel of EL734
|
||
** *el734Motor: 1 <-- the motor number (1..12)
|
||
** plus
|
||
** EL734.msecPoll: 1000 <-- 1.0 sec updates
|
||
** EL734.scaleWidth: 800 <-- scale width
|
||
**---------------------------------------------------------------------------
|
||
** Module Name . . . . . . . . : [...MOTOR]EL734.C
|
||
**
|
||
** Author . . . . . . . . . . : D. Maden
|
||
** Date of creation . . . . . . : Nov 1994
|
||
**
|
||
** Purpose
|
||
** =======
|
||
** EL734 is a test program for using with the SINQ VME/RS-232-C
|
||
** Motor Controller, EL734.
|
||
**
|
||
** Use:
|
||
** ===
|
||
** 1) Ensure that EL734_SRV is running on the appropriate computer.
|
||
**
|
||
** 2) Define a foreign command and the workstation where the display
|
||
** is to appear via the commands:
|
||
**
|
||
** $ motor :== $cpt:[exe]el734
|
||
** $ set display /create /transport=tcpip /node=pswxxx
|
||
**
|
||
** 3) Check the resource file DECW$USER_DEFAULTS:SinQ_rc.dat on VMS or
|
||
** $HOME/SinQ_rc on Digital-UNIX for the
|
||
** required resources (or specify them as flags - see below).
|
||
**
|
||
** 4) Ensure that the Session Manager security is set up to allow windows
|
||
** to be created on one's workstation.
|
||
**
|
||
** 5) Issue the command: $ motor [-options]
|
||
**
|
||
** Options are: Equivalent Resource Name Default
|
||
** ------- ------------------------ -------
|
||
** -host <server-name> *el734Host None
|
||
** -port <port-number> *el734Port 4000
|
||
** -chan <chan-number> *el734Chan None
|
||
** -poll <poll-delay-in-msec> EL734.msecPoll 1000
|
||
** -m <motor-number> EL734.el734Motor None
|
||
** -scale <width> EL734.scaleWidth: 800
|
||
** where
|
||
** <motor-number> must be in the range 1 to 12. It is the motor which
|
||
** will be controlled.
|
||
** <width> specifies the width of the displayed scale in pixels.
|
||
**
|
||
** If specified, a flag takes precedence over the resource file.
|
||
**
|
||
** Updates:
|
||
** 1A01 20-Dec-1994 DM. Initial version.
|
||
**-
|
||
**====================================================================
|
||
*/
|
||
#include <stdlib.h>
|
||
#include <stdio.h>
|
||
#include <stdarg.h>
|
||
#include <netdb.h>
|
||
#include <errno.h>
|
||
|
||
#ifdef __VMS
|
||
#include <signal.h>
|
||
#include <unixio.h>
|
||
#else
|
||
#include <unistd.h>
|
||
#endif
|
||
|
||
#include <netinet/in.h>
|
||
#include <arpa/inet.h>
|
||
#include <math.h>
|
||
#include <sys/socket.h>
|
||
|
||
#include <X11/Intrinsic.h>
|
||
#include <Xm/Xm.h>
|
||
#include <Xm/ArrowB.h>
|
||
#include <Xm/CascadeB.h>
|
||
#include <Xm/DrawnB.h>
|
||
#include <Xm/Form.h>
|
||
#include <Xm/Frame.h>
|
||
#include <Xm/Label.h>
|
||
#include <Xm/MainW.h>
|
||
#include <Xm/PushB.h>
|
||
#include <Xm/RowColumn.h>
|
||
#include <Xm/PanedW.h>
|
||
#include <Xm/Scale.h>
|
||
#include <Xm/ScrolledW.h>
|
||
#include <Xm/Separator.h>
|
||
/*
|
||
**--------------------------------------------------------------------------
|
||
** Define global structures and constants.
|
||
*/
|
||
#include <sinq_prototypes.h>
|
||
#include <el734_def.h>
|
||
#include <rs232c_def.h>
|
||
|
||
#define TMO 50 /* Units are 0.1 secs */
|
||
#define MAX_ARGS 20
|
||
|
||
enum Menu_Type {CASCADE, PULL_DOWN, SEPARATOR};
|
||
|
||
enum CmndFmts {ONE_INT, ONE_HEX, ONE_STRING, TWO_INT, TWO_STRING, NO_MORE};
|
||
|
||
typedef struct {
|
||
int msec_timer; /* Poll rate in msec */
|
||
char* vme_motor_host; /* Name of Motor Server */
|
||
int vme_motor_port; /* Port Number of Motor Server */
|
||
int vme_motor_number; /* Motor Number of Interest */
|
||
int v24_chan; /* Motor Number of Interest */
|
||
int scale_width; /* Scale width */
|
||
} ApplicationData;
|
||
/*
|
||
**-------------------------------------------------------------
|
||
** Global Variables
|
||
*/
|
||
ApplicationData AppData;
|
||
|
||
XtAppContext App_context; /* application context; */
|
||
|
||
static XtResource Resources[] = {
|
||
{"el734Host", "El734Host", XmRString, sizeof(String),
|
||
XtOffsetOf (ApplicationData, vme_motor_host),
|
||
XmRString, "Undefined"},
|
||
{"el734Port", "El734Port", XmRInt, sizeof(int),
|
||
XtOffsetOf (ApplicationData, vme_motor_port),
|
||
XmRImmediate, (XtPointer) 0},
|
||
{"el734Chan", "El734Chan", XmRInt, sizeof(int),
|
||
XtOffsetOf (ApplicationData, v24_chan),
|
||
XmRImmediate, (XtPointer) 0xffff},
|
||
{"el734Motor", "El734Motor", XmRInt, sizeof(int),
|
||
XtOffsetOf (ApplicationData, vme_motor_number),
|
||
XmRImmediate, (XtPointer) 0},
|
||
{"scaleWidth", "ScaleWidth", XmRInt, sizeof(int),
|
||
XtOffsetOf (ApplicationData, scale_width),
|
||
XmRImmediate, (XtPointer) 800},
|
||
{"msecPoll", "MsecPoll", XmRInt, sizeof(int),
|
||
XtOffsetOf (ApplicationData, msec_timer),
|
||
XmRImmediate, (XtPointer) 1000},
|
||
};
|
||
static XrmOptionDescRec OpTable[] = {
|
||
{"-host", ".el734Host", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-port", ".el734Port", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-chan", ".el734Chan", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-m", ".el734Motor", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-motor", ".el734Motor", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-poll", ".msecPoll", XrmoptionSepArg, (XPointer) NULL},
|
||
{"-scale", ".scaleWidth", XrmoptionSepArg, (XPointer) NULL},
|
||
};
|
||
|
||
static int Motor;
|
||
static int Scale_width;
|
||
static int Msg_seq = 1234;
|
||
|
||
struct Motor_State Old_Mot_state;
|
||
struct Motor_State Mot_state;
|
||
struct RS__RespStruct Respon_buff;
|
||
|
||
int Mot_factor;
|
||
float Mot_pos_ist;
|
||
float Mot_pos_soll;
|
||
float Mot_inertia_tol;
|
||
float Mot_ref_param;
|
||
float Mot_null_pt;
|
||
float Mot_lo_lim;
|
||
float Mot_hi_lim;
|
||
|
||
float Mot_scale_middle;
|
||
int Mot_is_on_left;
|
||
|
||
int Cnct_skt = 0;
|
||
char Err_text[80];
|
||
|
||
Widget Wtop_level; /* Top window */
|
||
|
||
Widget Wquit_cascade; /* Quit CascadeButton */
|
||
Widget Wslct_cascade; /* Select CascadeButton */
|
||
Widget Whelp_cascade; /* Help CascadeButton */
|
||
|
||
Widget Wupdt_button; /* Update Push Button */
|
||
Widget Wgo_button; /* Go Push Button */
|
||
Widget Wstop_button; /* Stop Push Button */
|
||
|
||
Widget Wmot_cascade; /* Motor Selection CascadeButton */
|
||
|
||
Widget Wlbl_state; /* Status Label */
|
||
|
||
Widget Label_name;
|
||
Widget Label_lo_lim;
|
||
Widget Label_hi_lim;
|
||
Widget Label_ist;
|
||
Widget Label_soll;
|
||
Widget Scale_soll;
|
||
Widget Scale_ist;
|
||
Widget Label_msr;
|
||
Widget Label_ss;
|
||
Widget Label_stats;
|
||
Widget Label_fd;
|
||
Widget Label_fm;
|
||
Widget Label_d;
|
||
Widget Label_e;
|
||
Widget Label_f;
|
||
Widget Label_g;
|
||
Widget Label_j;
|
||
Widget Label_k;
|
||
Widget Label_l;
|
||
Widget Label_m;
|
||
Widget Label_q;
|
||
Widget Label_t;
|
||
Widget Label_w;
|
||
Widget Label_v;
|
||
Widget Label_out;
|
||
Widget Label_in;
|
||
Widget Label_z;
|
||
Widget DrawnBut, DrawnButFrame;
|
||
|
||
int Scale_is_khz;
|
||
int Scale_max;
|
||
float Thresh_cntr_thresh;
|
||
float Thresh_cntr_rate;
|
||
|
||
int Nargs; /* Argument list variables - these must .. */
|
||
Arg Args[MAX_ARGS]; /* .. only be used as temporary variables. */
|
||
|
||
enum CmndFmts Cmnd_fmt[] = {
|
||
ONE_STRING, ONE_INT, TWO_INT, TWO_INT,
|
||
ONE_STRING, ONE_INT, ONE_INT, ONE_INT,
|
||
TWO_STRING, ONE_INT, ONE_INT, ONE_INT,
|
||
ONE_INT, ONE_STRING, ONE_INT, ONE_STRING,
|
||
ONE_INT, ONE_INT, ONE_STRING, ONE_INT,
|
||
ONE_INT, ONE_INT, NO_MORE};
|
||
|
||
size_t Offsets[] = {
|
||
OffsetOf (struct Motor_State, name[0]),
|
||
OffsetOf (struct Motor_State, dec_pt),
|
||
OffsetOf (struct Motor_State, enc_factor[0]),
|
||
OffsetOf (struct Motor_State, enc_factor[1]),
|
||
OffsetOf (struct Motor_State, mot_factor[0]),
|
||
OffsetOf (struct Motor_State, mot_factor[1]),
|
||
OffsetOf (struct Motor_State, inertia_tol[0]),
|
||
OffsetOf (struct Motor_State, ramp),
|
||
OffsetOf (struct Motor_State, loop_mode),
|
||
OffsetOf (struct Motor_State, slow_hz),
|
||
OffsetOf (struct Motor_State, lims[0][0]),
|
||
OffsetOf (struct Motor_State, lims[1][0]),
|
||
OffsetOf (struct Motor_State, fast_hz),
|
||
OffsetOf (struct Motor_State, ref_mode),
|
||
OffsetOf (struct Motor_State, backlash),
|
||
OffsetOf (struct Motor_State, pos_tol),
|
||
OffsetOf (struct Motor_State, ref_param[0]),
|
||
OffsetOf (struct Motor_State, is_sided),
|
||
OffsetOf (struct Motor_State, null_pt[0]),
|
||
OffsetOf (struct Motor_State, ac_par),
|
||
OffsetOf (struct Motor_State, enc_circ),
|
||
OffsetOf (struct Motor_State, set_real[0]),
|
||
OffsetOf (struct Motor_State, ac_state),
|
||
OffsetOf (struct Motor_State, out),
|
||
OffsetOf (struct Motor_State, in)
|
||
};
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** DecodeFloats - decode the fl. pt. strings.
|
||
*/
|
||
int DecodeFloats () {
|
||
/* =============
|
||
*/
|
||
int status, i;
|
||
static int do_warn_dec_pt = True;
|
||
static int do_warn_pos_real = True;
|
||
static int do_warn_pos_set = True;
|
||
|
||
status = True; /* Assume all will be OK */
|
||
|
||
if (sscanf (Mot_state.pos_real, "%f", &Mot_pos_ist) != 1)
|
||
status = False;
|
||
if (sscanf (Mot_state.inertia_tol, "%f", &Mot_inertia_tol) != 1)
|
||
status = False;
|
||
if (sscanf (Mot_state.lims[0], "%f", &Mot_lo_lim) != 1)
|
||
status = False;
|
||
if (sscanf (Mot_state.lims[1], "%f", &Mot_hi_lim) != 1)
|
||
status = False;
|
||
if (sscanf (Mot_state.ref_param, "%f", &Mot_ref_param) != 1)
|
||
status = False;
|
||
if (sscanf (Mot_state.null_pt, "%f", &Mot_null_pt) != 1)
|
||
status = False;
|
||
if (sscanf (Mot_state.set_real, "%f", &Mot_pos_soll) != 1)
|
||
status = False;
|
||
if (Mot_lo_lim > Mot_hi_lim) {
|
||
sscanf (Mot_state.lims[1], "%f", &Mot_lo_lim);
|
||
sscanf (Mot_state.lims[0], "%f", &Mot_hi_lim);
|
||
}
|
||
if ((Mot_pos_ist < Mot_lo_lim) || (Mot_hi_lim < Mot_pos_ist)) {
|
||
if (do_warn_pos_real) {
|
||
printf ("\007Warning -- actual position is outside low/high limits\n");
|
||
printf (" Low/actual/high are %f, %f, %f.\n",
|
||
Mot_lo_lim, Mot_pos_ist, Mot_hi_lim);
|
||
Mot_pos_ist = (Mot_lo_lim + Mot_hi_lim)/2.0;
|
||
printf (" Actual position will be displayed as %f.\n",
|
||
Mot_pos_ist);
|
||
do_warn_pos_real = False;
|
||
}
|
||
}else {
|
||
do_warn_pos_real = True;
|
||
}
|
||
if ((Mot_pos_soll < Mot_lo_lim) || (Mot_hi_lim < Mot_pos_soll)) {
|
||
if (do_warn_pos_set) {
|
||
printf ("\007Warning -- set position is outside low/high limits\n");
|
||
printf (" Low/set/high are %f, %f, %f.\n",
|
||
Mot_lo_lim, Mot_pos_soll, Mot_hi_lim);
|
||
Mot_pos_soll = (Mot_lo_lim + Mot_hi_lim)/2.0;
|
||
printf (" Set position will be displayed as %f.\n",
|
||
Mot_pos_soll);
|
||
do_warn_pos_set = False;
|
||
}
|
||
}else {
|
||
do_warn_pos_set = True;
|
||
}
|
||
if ((Mot_state.dec_pt < 0) || (6 < Mot_state.dec_pt)) {
|
||
if (do_warn_dec_pt) {
|
||
printf ("\007Warning -- number of decimal digits is invalid.\n");
|
||
printf (" Low/value/high are %d, %d, %d.\n",
|
||
0, Mot_state.dec_pt, 6);
|
||
Mot_state.dec_pt = 2;
|
||
printf (" A value of %d will be assumed.\n", Mot_state.dec_pt);
|
||
do_warn_dec_pt = False;
|
||
}
|
||
}else {
|
||
do_warn_dec_pt = True;
|
||
}
|
||
Mot_factor = 1;
|
||
for (i = 0; i < Mot_state.dec_pt; i++) Mot_factor = Mot_factor * 10;
|
||
|
||
return status;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EncodeSS - encode the SS flags into text.
|
||
*/
|
||
void EncodeSS (char *text, int ss) {
|
||
/* ========
|
||
*/
|
||
int len;
|
||
|
||
if (ss == 0) {
|
||
sprintf (text, "Flags, SS = 0");
|
||
}else if ((ss & ~(0x3f)) != 0) {
|
||
sprintf (text, "Flags, SS = ??");
|
||
}else {
|
||
sprintf (text, "Flags, SS = %#x ", ss);
|
||
if ((ss & 0x20) != 0) strcat (text, "LSX/");
|
||
if ((ss & 0x10) != 0) strcat (text, "LS2/");
|
||
if ((ss & 0x08) != 0) strcat (text, "LS1/");
|
||
if ((ss & 0x04) != 0) strcat (text, "STP/");
|
||
if ((ss & 0x02) != 0) strcat (text, "CCW/");
|
||
if ((ss & 0x01) != 0) strcat (text, "HLT/");
|
||
len = strlen (text);
|
||
text[len-1] = '\0';
|
||
}
|
||
return;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** EncodeMSR - encode the MSR flags into text.
|
||
*/
|
||
void EncodeMSR (char *text, int text_len,
|
||
/* =========
|
||
*/ int msr,
|
||
int ored_msr,
|
||
int fp_cntr,
|
||
int fr_cntr) {
|
||
int len;
|
||
char my_text[132];
|
||
char my_text_0[32];
|
||
|
||
if (msr == 0) {
|
||
ored_msr = ored_msr & ~(MSR__BUSY); /* Zero "Busy" bit */
|
||
if (ored_msr == MSR__OK) {
|
||
StrJoin (text, text_len, "Status, MSR = Idle. Positioned OK.", "");
|
||
}else {
|
||
if ((ored_msr & MSR__OK) != 0) {
|
||
StrJoin (text, text_len, "Status, MSR = Idle. Positioned OK. ", "");
|
||
}else {
|
||
StrJoin (text, text_len, "Status, MSR = Idle. ", "");
|
||
}
|
||
if ((ored_msr & MSR__REF_OK) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Ref. Pos'n OK. ");
|
||
}
|
||
if ((ored_msr & MSR__LIM_ERR) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Limit Switch Problem. ");
|
||
}
|
||
if ((ored_msr & MSR__AC_FAIL) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Air-Cushion Error. ");
|
||
}
|
||
if ((ored_msr & MSR__REF_FAIL) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Ref. Pos'n Fail. ");
|
||
}
|
||
if ((ored_msr & MSR__POS_FAIL) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Pos'n Fail. ");
|
||
}
|
||
if ((ored_msr & MSR__POS_FAULT) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
if (fp_cntr == 1) {
|
||
StrJoin (text, text_len, my_text, "1 Pos'n Fault. ");
|
||
}else {
|
||
sprintf (my_text_0, "%d Pos'n Faults. ", fp_cntr);
|
||
StrJoin (text, text_len, my_text, my_text_0);
|
||
}
|
||
}
|
||
if ((ored_msr & MSR__RUN_FAIL) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Run Fail. ");
|
||
}
|
||
if ((ored_msr & MSR__RUN_FAULT) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
if (fr_cntr == 1) {
|
||
StrJoin (text, text_len, my_text, "1 Run Fault. ");
|
||
}else {
|
||
sprintf (my_text_0, "%d Run Faults. ", fr_cntr);
|
||
StrJoin (text, text_len, my_text, my_text_0);
|
||
}
|
||
}
|
||
if ((ored_msr & MSR__HALT) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Halt. ");
|
||
}
|
||
if ((ored_msr & MSR__HI_LIM) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Hit HiLim. ");
|
||
}
|
||
if ((ored_msr & MSR__LO_LIM) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Hit LoLim. ");
|
||
}
|
||
if ((ored_msr & MSR__STOPPED) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Stopped. ");
|
||
}
|
||
}
|
||
}else if ((msr & ~(0x2fff)) != 0) {
|
||
StrJoin (text, text_len, "Status, MSR = ??", "");
|
||
}else {
|
||
sprintf (my_text, "%#x ", msr);
|
||
StrJoin (text, text_len, "Status, MSR = ", my_text);
|
||
if ((msr & MSR__LIM_ERR) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Limit Switch Problem/");
|
||
}
|
||
if ((msr & MSR__AC_FAIL) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Air-Cushion Error/");
|
||
}
|
||
if ((msr & MSR__REF_FAIL) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Ref. Pos'n Fail/");
|
||
}
|
||
if ((msr & MSR__POS_FAIL) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Pos'n Fail/");
|
||
}
|
||
if ((msr & MSR__POS_FAULT) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Pos'n Fault/");
|
||
}
|
||
if ((msr & MSR__RUN_FAIL) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Run Fail/");
|
||
}
|
||
if ((msr & MSR__RUN_FAULT) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Run Fault/");
|
||
}
|
||
if ((msr & MSR__HALT) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Halt/");
|
||
}
|
||
if ((msr & MSR__HI_LIM) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Hit HiLim/");
|
||
}
|
||
if ((msr & MSR__LO_LIM) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Hit LoLim/");
|
||
}
|
||
if ((msr & MSR__STOPPED) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Stopped/");
|
||
}
|
||
if ((msr & MSR__REF_OK) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Ref. Pos'n OK/");
|
||
}
|
||
if ((msr & MSR__OK) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "OK/");
|
||
}
|
||
if ((msr & MSR__BUSY) != 0) {
|
||
StrJoin (my_text, sizeof (my_text), text, "");
|
||
StrJoin (text, text_len, my_text, "Busy/");
|
||
}
|
||
len = strlen (text);
|
||
text[len-1] = '\0';
|
||
}
|
||
return;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** ConnectToSrvr - make connection to Motor Server
|
||
*/
|
||
int ConnectToSrvr (char *host, int port) {
|
||
/* =============
|
||
*/
|
||
int status;
|
||
int my_cnct_skt; /* Socket for connecting to Motor Srv */
|
||
struct sockaddr_in lcl_sockname;
|
||
struct sockaddr_in rmt_sockname;
|
||
int rmt_inet_addr;
|
||
struct in_addr *rmt_inet_addr_pntr;
|
||
int rmt_port;
|
||
int rmt_sockname_len;
|
||
int i;
|
||
struct hostent *rmt_hostent;
|
||
|
||
#if Active_Server
|
||
rmt_hostent = gethostbyname (host);
|
||
if (rmt_hostent == NULL) FailInet ("Gethostbyname error.\n");
|
||
rmt_inet_addr_pntr = (struct in_addr *) rmt_hostent->h_addr_list[0];
|
||
|
||
rmt_port = port;
|
||
/*
|
||
** Create a TCP/IP socket for connecting to root and bind it.
|
||
*/
|
||
my_cnct_skt = socket (AF_INET, SOCK_STREAM, 0);
|
||
if (my_cnct_skt == -1) FailInet ("Socket error.\n");
|
||
|
||
lcl_sockname.sin_family = AF_INET;
|
||
lcl_sockname.sin_port = htons (0);
|
||
lcl_sockname.sin_addr.s_addr = 0;
|
||
status = bind (my_cnct_skt, (struct sockaddr *) &lcl_sockname,
|
||
sizeof (lcl_sockname));
|
||
if (status == -1) FailInet ("Bind error.\n");
|
||
/*
|
||
** Connect to Motor Server.
|
||
*/
|
||
rmt_sockname_len = sizeof (rmt_sockname);
|
||
rmt_sockname.sin_family = AF_INET;
|
||
rmt_sockname.sin_port = htons (rmt_port);
|
||
rmt_sockname.sin_addr.s_addr = rmt_inet_addr_pntr->s_addr;
|
||
status = connect (my_cnct_skt, (struct sockaddr *) &rmt_sockname,
|
||
sizeof (rmt_sockname));
|
||
if (status == -1) {
|
||
FailInet ("Connect error.\n");
|
||
}
|
||
return my_cnct_skt;
|
||
#else /* Active_Server */
|
||
return 0; /* "No server" mode - don't connect to server */
|
||
#endif /* Active_Server */
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** ModifyLabel - modify text of a simple label
|
||
*/
|
||
void ModifyLabel (
|
||
/* ===========
|
||
*/ Widget labl, /* widget id of label */
|
||
char *text) { /* The text for the label */
|
||
|
||
XmString my_compString;
|
||
|
||
my_compString = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
|
||
XtVaSetValues (labl,
|
||
XmNlabelString, my_compString,
|
||
NULL);
|
||
XmStringFree (my_compString);
|
||
|
||
return;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** SetStateInWindows - update State fields in Windows to
|
||
** match state_ptr->msr, etc.
|
||
*/
|
||
void SetStateInWindows (
|
||
/* =================
|
||
*/ struct Motor_State *old_state_ptr, /* Motor status of display */
|
||
struct Motor_State *state_ptr) { /* current motor status */
|
||
|
||
XmString tmp_cmpStr;
|
||
int i_left, i_right, i_ist, i_soll;
|
||
float flt;
|
||
char text[80];
|
||
static int state_len;
|
||
/*
|
||
** First time in, ensure that state_len is set to the length of
|
||
** the Motor_State structure which must be checked for changes.
|
||
*/
|
||
if (state_len == 0) state_len = sizeof (struct Motor_State);
|
||
if (memcmp (old_state_ptr, state_ptr, state_len) == 0) return;
|
||
|
||
if (strcmp (state_ptr->pos_real, old_state_ptr->pos_real) != 0) {
|
||
sscanf (state_ptr->pos_real, "%f", &flt);
|
||
i_left = (int) (Mot_lo_lim * Mot_factor);
|
||
i_right = (int) (Mot_hi_lim * Mot_factor);
|
||
i_ist = (int) (flt * Mot_factor);
|
||
/*
|
||
** Update "Ist" scale slider
|
||
*/
|
||
if (i_ist < i_left) i_ist = i_left;
|
||
if (i_ist > i_right) i_ist = i_right;
|
||
XmScaleSetValue (Scale_ist, i_ist);
|
||
/*
|
||
** Update "Ist" label
|
||
*/
|
||
sprintf (text, "%.*f", state_ptr->dec_pt, Mot_pos_ist);
|
||
ModifyLabel (Label_ist, text);
|
||
if (Mot_is_on_left) {
|
||
XtVaSetValues (Label_ist,
|
||
XmNleftPosition, (i_ist - i_left), NULL);
|
||
}else {
|
||
XtVaSetValues (Label_ist,
|
||
XmNrightPosition, (i_ist - i_left), NULL);
|
||
}
|
||
}
|
||
|
||
if (strcmp (state_ptr->set_real, old_state_ptr->set_real) != 0) {
|
||
sscanf (state_ptr->set_real, "%f", &flt);
|
||
i_left = (int) (Mot_lo_lim * Mot_factor);
|
||
i_right = (int) (Mot_hi_lim * Mot_factor);
|
||
i_soll = (int) (flt * Mot_factor);
|
||
/*
|
||
** Update "Soll" scale slider
|
||
*/
|
||
if (i_soll < i_left) i_soll = i_left;
|
||
if (i_soll > i_right) i_soll = i_right;
|
||
XmScaleSetValue (Scale_soll, i_soll);
|
||
/*
|
||
** Update "Soll" label
|
||
*/
|
||
sprintf (text, "%.*f", state_ptr->dec_pt, Mot_pos_soll);
|
||
ModifyLabel (Label_soll, text);
|
||
if (Mot_is_on_left) {
|
||
XtVaSetValues (Label_soll,
|
||
XmNleftPosition, (i_soll - i_left), NULL);
|
||
}else {
|
||
XtVaSetValues (Label_soll,
|
||
XmNrightPosition, (i_soll - i_left), NULL);
|
||
}
|
||
}
|
||
/*
|
||
** Update MSR label if necessary
|
||
*/
|
||
if (state_ptr->msr != old_state_ptr->msr) {
|
||
EncodeMSR (text, sizeof (text), state_ptr->msr,
|
||
state_ptr->ored_msr,
|
||
state_ptr->fp_cntr,
|
||
state_ptr->fr_cntr);
|
||
ModifyLabel (Label_msr, text);
|
||
}
|
||
/*
|
||
** Update SS label if necessary
|
||
*/
|
||
if (state_ptr->ss != old_state_ptr->ss) {
|
||
EncodeSS (text, state_ptr->ss);
|
||
ModifyLabel (Label_ss, text);
|
||
}
|
||
/*
|
||
** Update Statistics label if necessary
|
||
*/
|
||
if ((state_ptr->stat_pos != old_state_ptr->stat_pos) ||
|
||
(state_ptr->stat_pos_flt != old_state_ptr->stat_pos_flt) ||
|
||
(state_ptr->stat_pos_fail != old_state_ptr->stat_pos_fail) ||
|
||
(state_ptr->stat_cush_fail != old_state_ptr->stat_cush_fail)) {
|
||
sprintf (text, "Statistics: Total/Faults/Fails/Cush-fails = %d/%d/%d/%d",
|
||
state_ptr->stat_pos, state_ptr->stat_pos_flt,
|
||
state_ptr->stat_pos_fail, state_ptr->stat_cush_fail);
|
||
ModifyLabel (Label_stats, text);
|
||
}
|
||
/*
|
||
** Update FD label if necessary
|
||
*/
|
||
if ((state_ptr->enc_factor[0] != old_state_ptr->enc_factor[0]) ||
|
||
(state_ptr->enc_factor[1] != old_state_ptr->enc_factor[1])) {
|
||
sprintf (text, "Encoder Ratio, FD = %d:%d", state_ptr->enc_factor[0],
|
||
state_ptr->enc_factor[1]);
|
||
ModifyLabel (Label_fd, text);
|
||
}
|
||
/*
|
||
** Update FM label if necessary
|
||
*/
|
||
if ((state_ptr->mot_factor[0] != old_state_ptr->mot_factor[0]) ||
|
||
(state_ptr->mot_factor[1] != old_state_ptr->mot_factor[1])) {
|
||
sprintf (text, "Motor Ratio, FM = %d:%d", state_ptr->mot_factor[0],
|
||
state_ptr->mot_factor[1]);
|
||
ModifyLabel (Label_fm, text);
|
||
}
|
||
/*
|
||
** Update D label if necessary
|
||
*/
|
||
if (strcmp (state_ptr->inertia_tol, old_state_ptr->inertia_tol) != 0) {
|
||
sprintf (text, "Inertia tol'nce, D = %s", state_ptr->inertia_tol);
|
||
ModifyLabel (Label_d, text);
|
||
}
|
||
/*
|
||
** Update E label if necessary
|
||
*/
|
||
if (state_ptr->ramp != old_state_ptr->ramp) {
|
||
sprintf (text, "Start/stop ramp, E = %d", state_ptr->ramp);
|
||
ModifyLabel (Label_e, text);
|
||
}
|
||
/*
|
||
** Update F label if necessary
|
||
*/
|
||
if (state_ptr->loop_mode != old_state_ptr->loop_mode) {
|
||
switch (state_ptr->loop_mode) {
|
||
case 0: sprintf (text, "Open loop mode, F = 0"); break;
|
||
case 1: sprintf (text, "Closed loop mode, F = 1"); break;
|
||
default: sprintf (text, "Bad loop mode, F = %d", state_ptr->loop_mode);
|
||
}
|
||
ModifyLabel (Label_f, text);
|
||
}
|
||
/*
|
||
** Update G label if necessary
|
||
*/
|
||
if (state_ptr->slow_hz != old_state_ptr->slow_hz) {
|
||
sprintf (text, "Start/stop Hz, G = %d", state_ptr->slow_hz);
|
||
ModifyLabel (Label_g, text);
|
||
}
|
||
/*
|
||
** Update J label if necessary
|
||
*/
|
||
if (state_ptr->fast_hz != old_state_ptr->fast_hz) {
|
||
sprintf (text, "Positioning Hz, J = %d", state_ptr->fast_hz);
|
||
ModifyLabel (Label_j, text);
|
||
}
|
||
/*
|
||
** Update K label if necessary
|
||
*/
|
||
if (state_ptr->ref_mode != old_state_ptr->ref_mode) {
|
||
switch (state_ptr->ref_mode) {
|
||
case 0: sprintf (text, "Absolute encoder, K = 0"); break;
|
||
case 1: sprintf (text, "HiLimit is RefPt, K = 1"); break;
|
||
case -1: sprintf (text, "LoLimit is RefPt, K = -1"); break;
|
||
case 2: sprintf (text, "Sep RefPt, K = 2"); break;
|
||
case 11: sprintf (text, "HiLimit is RefPt + Indx, K = 11"); break;
|
||
case -11: sprintf (text, "LoLimit is RefPt + Indx, K = -11"); break;
|
||
case 12: sprintf (text, "Sep RefPt + Indx, K = 12"); break;
|
||
default: sprintf (text, "RefMode unknown, K = %d", state_ptr->ref_mode);
|
||
}
|
||
ModifyLabel (Label_k, text);
|
||
}
|
||
/*
|
||
** Update L label if necessary
|
||
*/
|
||
if (state_ptr->backlash != old_state_ptr->backlash) {
|
||
sprintf (text, "Backlash, L = %d", state_ptr->backlash);
|
||
ModifyLabel (Label_l, text);
|
||
}
|
||
/*
|
||
** Update M label if necessary
|
||
*/
|
||
if (state_ptr->pos_tol != old_state_ptr->pos_tol) {
|
||
sprintf (text, "Position Tol'nce, M = %d", state_ptr->pos_tol);
|
||
ModifyLabel (Label_m, text);
|
||
}
|
||
/*
|
||
** Update Q label if necessary
|
||
*/
|
||
if (strcmp (state_ptr->ref_param, old_state_ptr->ref_param) != 0) {
|
||
sprintf (text, "RefPt Width, Q = %s", state_ptr->ref_param);
|
||
ModifyLabel (Label_q, text);
|
||
}
|
||
/*
|
||
** Update T label if necessary
|
||
*/
|
||
if (state_ptr->is_sided != old_state_ptr->is_sided) {
|
||
if (state_ptr->is_sided == 0) {
|
||
sprintf (text, "No dir'n dependency, T = 0");
|
||
}else if (state_ptr->is_sided > 0) {
|
||
sprintf (text, "Position from above, T = %d", state_ptr->is_sided);
|
||
}else {
|
||
sprintf (text, "Position from below, T = %d", state_ptr->is_sided);
|
||
}
|
||
ModifyLabel (Label_t, text);
|
||
}
|
||
/*
|
||
** Update V label if necessary
|
||
*/
|
||
if (strcmp (state_ptr->null_pt, old_state_ptr->null_pt) != 0) {
|
||
sprintf (text, "NullPt, V = %s", state_ptr->null_pt);
|
||
ModifyLabel (Label_v, text);
|
||
}
|
||
/*
|
||
** Update W label if necessary
|
||
*/
|
||
if ((state_ptr->ac_par != old_state_ptr->ac_par) ||
|
||
(state_ptr->ac_state != old_state_ptr->ac_state)) {
|
||
if (state_ptr->ac_par == 0) {
|
||
sprintf (text, "No air-cushion present, W = 0");
|
||
}else if (state_ptr->ac_par == Motor) {
|
||
if (state_ptr->ac_state == 0) {
|
||
sprintf (text, "Air-cushion down");
|
||
}else {
|
||
sprintf (text, "Air-cushion up");
|
||
}
|
||
}else {
|
||
if (state_ptr->ac_state == 0) {
|
||
sprintf (text, "Air-cushion up (chained to %d)", state_ptr->ac_par);
|
||
}else {
|
||
sprintf (text, "Air-cushion down (chained to %d)", state_ptr->ac_par);
|
||
}
|
||
}
|
||
ModifyLabel (Label_w, text);
|
||
}
|
||
/*
|
||
** Update Output label if necessary
|
||
*/
|
||
if (state_ptr->out != old_state_ptr->out) {
|
||
if (state_ptr->out == 0) {
|
||
sprintf (text, "Output signal not active", state_ptr->null_pt);
|
||
}else {
|
||
sprintf (text, "Output signal active", state_ptr->null_pt);
|
||
}
|
||
ModifyLabel (Label_out, text);
|
||
}
|
||
/*
|
||
** Update Input label if necessary
|
||
*/
|
||
if (state_ptr->in != old_state_ptr->in) {
|
||
if (state_ptr->in == 0) {
|
||
sprintf (text, "Input signal not present");
|
||
}else {
|
||
sprintf (text, "Input signal present");
|
||
}
|
||
ModifyLabel (Label_in, text);
|
||
}
|
||
/*
|
||
** Update Z label if necessary
|
||
*/
|
||
if (state_ptr->enc_circ != old_state_ptr->enc_circ) {
|
||
sprintf (text, "Enc Circum, Z = %d", state_ptr->enc_circ);
|
||
ModifyLabel (Label_z, text);
|
||
}
|
||
/*
|
||
*/
|
||
memcpy (old_state_ptr, state_ptr, state_len);
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** SendCmndToServer - send command to RS232C server
|
||
*/
|
||
int SendCmndToServer (
|
||
/* =================
|
||
*/ int v24_chan, /* RS232C port number */
|
||
int tmo, /* Time-out (0.1 secs) */
|
||
struct RS__RespStruct *respon_ptr, /* Buffer for response */
|
||
int respon_size, /* Size of resp'se buff */
|
||
...) { /* Now we have parameter pairs -
|
||
** char *fmt = pntr to format strng
|
||
** char *param = pntr to param
|
||
** Terminate list with *fmt = NULL.
|
||
*/
|
||
struct RS__MsgStruct msg_buff;
|
||
int status, c_len, size, max_size, ncmnds;
|
||
char text[20];
|
||
va_list ap; /* Pointer to variable args */
|
||
char *fmt_ptr;
|
||
char *param_ptr;
|
||
char *cmnd_lst_ptr;
|
||
|
||
if (Cnct_skt == 0) return True; /* Do nothing if no connection - this
|
||
** allows testing in "client-only" mode.
|
||
*/
|
||
|
||
Msg_seq++; /* Set up an incrementing message id */
|
||
if (Msg_seq > 9999) Msg_seq = 1;
|
||
sprintf (msg_buff.msg_id, "%04.4d", Msg_seq);
|
||
|
||
memcpy (msg_buff.c_pcol_lvl, RS__PROTOCOL_ID,
|
||
sizeof (msg_buff.c_pcol_lvl));
|
||
sprintf (msg_buff.serial_port, "%04.4d", v24_chan);
|
||
sprintf (msg_buff.tmo, "%04.4d", tmo);
|
||
|
||
memcpy (msg_buff.terms, "1\r\0\0", sizeof (msg_buff.terms));
|
||
|
||
memcpy (msg_buff.n_cmnds, "0000", sizeof (msg_buff.n_cmnds));
|
||
|
||
va_start (ap, respon_size); /* Set up var arg machinery */
|
||
|
||
fmt_ptr = va_arg (ap, char *); /* Get pntr to next format string */
|
||
ncmnds = 0;
|
||
cmnd_lst_ptr = &msg_buff.cmnds[0];
|
||
|
||
while (fmt_ptr != NULL) {
|
||
param_ptr = va_arg (ap, char *); /* Get pntr to next param */
|
||
c_len = sprintf (cmnd_lst_ptr+2, fmt_ptr, param_ptr);
|
||
sprintf (text, "%02.2d", c_len);
|
||
memcpy (cmnd_lst_ptr, text, 2);
|
||
cmnd_lst_ptr = cmnd_lst_ptr + c_len + 2;
|
||
ncmnds++;
|
||
fmt_ptr = va_arg (ap, char *);
|
||
}
|
||
sprintf (text, "%04.4d", ncmnds);
|
||
memcpy (msg_buff.n_cmnds, text, sizeof (msg_buff.n_cmnds));
|
||
|
||
size = cmnd_lst_ptr - msg_buff.msg_id;
|
||
size = (size + 3) & (~3); /* Round up to multiple of 4 */
|
||
sprintf (text, "%04.4d", size);
|
||
memcpy (msg_buff.msg_size, text, 4);
|
||
|
||
status = send (Cnct_skt, (char *) &msg_buff, size+4, 0);
|
||
if (status != (size+4)) {
|
||
sprintf (Err_text, "send: did not send all of buffer: %d %d.\n",
|
||
size+4, status);
|
||
FailInet (Err_text);
|
||
}
|
||
|
||
size = sizeof (respon_ptr->msg_size);
|
||
status = recv (Cnct_skt, respon_ptr->msg_size, size, 0);
|
||
if (status != size) {
|
||
sprintf (Err_text, "recv: did not get full byte count: %d %d.\n",
|
||
size, status);
|
||
FailInet (Err_text);
|
||
}
|
||
if (sscanf (respon_ptr->msg_size, "%4d", &size) != 1) {
|
||
sprintf (Err_text, "recv: byte count is not ASCII decimal: %4s\n",
|
||
respon_ptr->msg_size);
|
||
FailInet (Err_text);
|
||
}
|
||
max_size = respon_size - sizeof (respon_ptr->msg_size);
|
||
if (size > max_size) {
|
||
sprintf (Err_text, "recv: message length is too big: %d, %d.\n",
|
||
max_size, size);
|
||
FailInet (Err_text);
|
||
}
|
||
status = recv (Cnct_skt, (char *) respon_ptr->msg_id, size, 0);
|
||
if (status != size) {
|
||
sprintf (Err_text, "recv: did not get all of expected data: %d %d.\n",
|
||
size, status);
|
||
FailInet (Err_text);
|
||
}
|
||
return status;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** GetReply - get next reply from a reply buffer
|
||
*/
|
||
struct RS__RplyStruct *GetReply (
|
||
/* ========
|
||
*/ struct RS__RespStruct *respon_ptr, /* Structure to pull apart */
|
||
struct RS__RplyStruct *last_rply) { /* Starting point */
|
||
|
||
int rply_len;
|
||
struct RS__RplyStruct *ptr;
|
||
|
||
static int n_replies, max_replies;
|
||
|
||
ptr = NULL;
|
||
if (last_rply == NULL) { /* Start with first reply? */
|
||
if (sscanf (respon_ptr->n_rply, "%4d", &max_replies) != 1)
|
||
max_replies = 0;
|
||
if (max_replies > 0) ptr = (struct RS__RplyStruct *) respon_ptr->u.rplys;
|
||
n_replies = 1;
|
||
}else {
|
||
n_replies++;
|
||
if (n_replies <= max_replies) {
|
||
if (sscanf (last_rply->rply_len, "%2d", &rply_len) == 1) {
|
||
ptr = (struct RS__RplyStruct *) ((char *) last_rply + rply_len + 2);
|
||
}
|
||
}
|
||
}
|
||
return ptr;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** GetMotorStatus - get Motor status from srvr
|
||
*/
|
||
int GetMotorStatus (
|
||
/* ================
|
||
*/ int type, /* FULL__STATUS or SHORT__STATUS */
|
||
struct Motor_State *state) { /* Structure to hold status */
|
||
|
||
struct RS__MsgStruct msg_buff;
|
||
int status, size, max_size;
|
||
int i, indx;
|
||
int j0, j1;
|
||
char txt0[16], txt1[16], mot_txt[10];
|
||
struct RS__RplyStruct *rply_ptr;
|
||
/*
|
||
** Start by getting "short" status of motor.
|
||
*/
|
||
#if Active_Server
|
||
sprintf (mot_txt, "%d", state->motor);
|
||
status = SendCmndToServer (AppData.v24_chan, TMO,
|
||
&Respon_buff, sizeof (Respon_buff),
|
||
"msr %s\r", mot_txt,
|
||
"ss %s\r", mot_txt,
|
||
"u %s\r", mot_txt,
|
||
"p %s\r", mot_txt,
|
||
"sp %s\r", mot_txt,
|
||
"st %s\r", mot_txt,
|
||
"sr %s\r", mot_txt,
|
||
"sa %s\r", mot_txt,
|
||
NULL);
|
||
rply_ptr = GetReply (&Respon_buff, NULL);
|
||
if (rply_ptr != NULL) {
|
||
if (sscanf (rply_ptr->rply, "%x", &state->msr) == 1) {
|
||
state->exists = True;
|
||
state->ored_msr = state->ored_msr | state->msr;
|
||
if ((state->msr & MSR__POS_FAULT) != 0) state->fp_cntr++;
|
||
if ((state->msr & MSR__RUN_FAULT) != 0) state->fr_cntr++;
|
||
rply_ptr = GetReply (&Respon_buff, rply_ptr);
|
||
if (rply_ptr != NULL) {
|
||
if (sscanf (rply_ptr->rply, "%x", &state->ss) != 1) state->ss = -1;
|
||
rply_ptr = GetReply (&Respon_buff, rply_ptr);
|
||
if (rply_ptr != NULL) {
|
||
strncpy (state->pos_real, rply_ptr->rply,
|
||
sizeof (state->pos_real) - 1);
|
||
sscanf (state->pos_real, "%f", &Mot_pos_ist);
|
||
rply_ptr = GetReply (&Respon_buff, rply_ptr);
|
||
if (rply_ptr != NULL) {
|
||
strncpy (state->set_real, rply_ptr->rply,
|
||
sizeof (state->set_real) - 1);
|
||
sscanf (state->set_real, "%f", &Mot_pos_soll);
|
||
rply_ptr = GetReply (&Respon_buff, rply_ptr);
|
||
if (rply_ptr != NULL) {
|
||
sscanf (rply_ptr->rply, "%d", &state->stat_pos);
|
||
rply_ptr = GetReply (&Respon_buff, rply_ptr);
|
||
if (rply_ptr != NULL) {
|
||
sscanf (rply_ptr->rply, "%d", &state->stat_pos_flt);
|
||
rply_ptr = GetReply (&Respon_buff, rply_ptr);
|
||
if (rply_ptr != NULL) {
|
||
sscanf (rply_ptr->rply, "%d", &state->stat_pos_fail);
|
||
rply_ptr = GetReply (&Respon_buff, rply_ptr);
|
||
if (rply_ptr != NULL) {
|
||
sscanf (rply_ptr->rply, "%d", &state->stat_cush_fail);
|
||
rply_ptr = GetReply (&Respon_buff, rply_ptr);
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}
|
||
}else {
|
||
state->exists = False;
|
||
}
|
||
}
|
||
if ((type == FULL__STATUS) && state->exists) {
|
||
status = SendCmndToServer (AppData.v24_chan, TMO,
|
||
&Respon_buff, sizeof (Respon_buff),
|
||
"mn %s\r", mot_txt,
|
||
"a %s\r", mot_txt,
|
||
"fd %s\r", mot_txt,
|
||
"fm %s\r", mot_txt,
|
||
"d %s\r", mot_txt,
|
||
"e %s\r", mot_txt,
|
||
"f %s\r", mot_txt,
|
||
"g %s\r", mot_txt,
|
||
"h %s\r", mot_txt,
|
||
"j %s\r", mot_txt,
|
||
"k %s\r", mot_txt,
|
||
"l %s\r", mot_txt,
|
||
"m %s\r", mot_txt,
|
||
"q %s\r", mot_txt,
|
||
"t %s\r", mot_txt,
|
||
"v %s\r", mot_txt,
|
||
"w %s\r", mot_txt,
|
||
"z %s\r", mot_txt,
|
||
"p %s\r", mot_txt,
|
||
"ac %s\r", mot_txt,
|
||
"so %s\r", mot_txt,
|
||
"ri %s\r", mot_txt,
|
||
NULL);
|
||
|
||
rply_ptr = GetReply (&Respon_buff, NULL);
|
||
indx = 0;
|
||
for (i = 0; Cmnd_fmt[i] != NO_MORE; i++) {
|
||
if (rply_ptr != NULL) {
|
||
switch (Cmnd_fmt[i]) {
|
||
case ONE_INT:
|
||
sscanf (rply_ptr->rply, "%d",
|
||
(int *)(((char *) state) + Offsets[indx]));
|
||
indx++;
|
||
break;
|
||
case TWO_INT:
|
||
sscanf (rply_ptr->rply, "%d %d",
|
||
(int *)(((char *) state) + Offsets[indx]),
|
||
(int *)(((char *) state) + Offsets[indx+1]));
|
||
indx++; indx++;
|
||
break;
|
||
case ONE_STRING:
|
||
sscanf (rply_ptr->rply, "%15s",
|
||
((char *) state) + Offsets[indx]);
|
||
indx++;
|
||
break;
|
||
case TWO_STRING:
|
||
sscanf (rply_ptr->rply, "%15s %15s",
|
||
((char *) state) + Offsets[indx],
|
||
((char *) state) + Offsets[indx+1]);
|
||
indx++; indx++;
|
||
break;
|
||
}
|
||
rply_ptr = GetReply (&Respon_buff, rply_ptr);
|
||
}
|
||
}
|
||
DecodeFloats (); /* Convert all strings in state to binary */
|
||
}
|
||
#else
|
||
state->exists = True;
|
||
state->msr = 1;
|
||
state->ss = 2;
|
||
strcpy (state->pos_real, "12.2");
|
||
state->pos_hex = 0x1234;
|
||
strcpy (state->name, "DELTA");
|
||
state->dec_pt = 3;
|
||
state->enc_factor[0] = 400;
|
||
state->enc_factor[1] = 2;
|
||
state->mot_factor[0] = -300;
|
||
state->mot_factor[1] = 3;
|
||
strcpy (state->inertia_tol, "0.1");
|
||
state->ramp = 20;
|
||
state->loop_mode = 1;
|
||
state->slow_hz = 300;
|
||
strcpy (&state->lims[0][0], "-50.0");
|
||
strcpy (&state->lims[1][0], "200.0");
|
||
state->fast_hz = 1000;
|
||
state->ref_mode = 2;
|
||
state->backlash = 0;
|
||
state->pos_tol = 1;
|
||
strcpy (state->ref_param, "10.0");
|
||
state->is_sided = 0;
|
||
strcpy (state->null_pt, "-15.0");
|
||
state->ac_par = state->motor;
|
||
state->enc_circ = 0;
|
||
state->stat_pos = 1234;
|
||
state->stat_pos_flt = 2345;
|
||
state->stat_pos_fail = 3456;
|
||
state->stat_cush_fail = 4567;
|
||
strcpy (state->set_real, "70.5");
|
||
state->set_hex = 0x4321;
|
||
state->ac_state = 0;
|
||
state->out = 0;
|
||
state->in = 0;
|
||
#endif /* Active_Server */
|
||
return True;
|
||
}
|
||
/*
|
||
|
||
**---------------------------------------------------------------------------
|
||
** ActivateCB - callback for button
|
||
*/
|
||
void ActivateCB (
|
||
/* ==========
|
||
*/ Widget w, /* widget id */
|
||
XtPointer client_data, /* data from application */
|
||
XtPointer call_data) { /* data from widget class */
|
||
|
||
Widget w_tmp;
|
||
char *button_name, *parent_name;
|
||
/*
|
||
** print message to prove we got activated
|
||
*/
|
||
w_tmp = XtParent (w);
|
||
button_name = XtName (w);
|
||
parent_name = XtName (w_tmp);
|
||
|
||
printf ("Push button \"%s\" of Parent \"%s\" selected.\n",
|
||
button_name, parent_name);
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** MotorSelectCB - callback for Select .../Motor .../Number
|
||
*/
|
||
void MotorSelectCB (
|
||
/* =============
|
||
*/ Widget w, /* widget id */
|
||
XtPointer client_data, /* data from application */
|
||
XtPointer call_data) { /* data from widget class */
|
||
|
||
int motor = 0, i_left, i_right, i_soll, i_ist;
|
||
char *button_name, text[80];
|
||
XmString tmp_cmpStr;
|
||
/*
|
||
** print message to prove we got activated
|
||
*/
|
||
button_name = XtName (w);
|
||
printf ("Push button \"%s\" selected.\n", button_name);
|
||
if ((sscanf (button_name, "%i", &motor) != 1) ||
|
||
(motor <= 0) ||
|
||
(motor > 12)) {
|
||
printf ("Invalid push button label or motor number!\n");
|
||
return;
|
||
}
|
||
if (motor != Motor) {
|
||
Motor = motor;
|
||
Mot_state.motor = Motor;
|
||
printf ("Getting full status of Motor %d ...\n", Motor);
|
||
GetMotorStatus (FULL__STATUS, &Mot_state);
|
||
|
||
sprintf (text, "%.*f", Mot_state.dec_pt, Mot_lo_lim);
|
||
tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
|
||
XtVaSetValues (Label_lo_lim,
|
||
XmNlabelString, tmp_cmpStr,
|
||
NULL);
|
||
XmStringFree (tmp_cmpStr);
|
||
|
||
sprintf (text, "Motor %d \"%s\"", Motor, Mot_state.name);
|
||
tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
|
||
XtVaSetValues (Label_name,
|
||
XmNlabelString, tmp_cmpStr,
|
||
NULL);
|
||
XmStringFree (tmp_cmpStr);
|
||
|
||
sprintf (text, "%.*f", Mot_state.dec_pt, Mot_hi_lim);
|
||
tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
|
||
XtVaSetValues (Label_hi_lim,
|
||
XmNlabelString, tmp_cmpStr,
|
||
NULL);
|
||
XmStringFree (tmp_cmpStr);
|
||
|
||
i_left = (int) (Mot_lo_lim * Mot_factor);
|
||
i_right = (int) (Mot_hi_lim * Mot_factor);
|
||
i_soll = (int) (Mot_pos_soll * Mot_factor);
|
||
i_ist = (int) (Mot_pos_ist * Mot_factor);
|
||
if (i_ist < i_left) i_ist = i_left;
|
||
if (i_ist > i_right) i_ist = i_right;
|
||
if (i_soll < i_left) i_soll = i_left;
|
||
if (i_soll > i_right) i_soll = i_right;
|
||
XtVaSetValues (Scale_ist,
|
||
XmNminimum, i_left,
|
||
XmNmaximum, i_right,
|
||
XmNvalue, i_ist,
|
||
NULL);
|
||
XtVaSetValues (Scale_soll,
|
||
XmNminimum, i_left,
|
||
XmNmaximum, i_right,
|
||
XmNvalue, i_soll,
|
||
NULL);
|
||
|
||
SetStateInWindows (&Old_Mot_state, &Mot_state); /* Update window display. */
|
||
}
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** AddMenuItem - add item into menu
|
||
*/
|
||
Widget AddMenuItem (
|
||
/* ===========
|
||
*/ Widget parent, /* The parent menu */
|
||
char *name, /* Name of menu item */
|
||
char accelerator, /* Accelerator character */
|
||
int menu_type, /* Menu type */
|
||
Widget casc_pane, /* Pane to link to button ..
|
||
** .. (menu_type = CASCADE only */
|
||
XtCallbackProc callback) { /* Callback procedure */
|
||
|
||
Widget my_menu_item;
|
||
|
||
Nargs = 0;
|
||
if (accelerator != 0)
|
||
XtSetArg (Args[Nargs], XmNmnemonic, accelerator); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNnavigationType, XmTAB_GROUP); Nargs++;
|
||
|
||
switch (menu_type) {
|
||
case CASCADE:
|
||
XtSetArg (Args[Nargs], XmNsubMenuId, casc_pane); Nargs++;
|
||
my_menu_item = XmCreateCascadeButton (parent, name, Args, Nargs);
|
||
break;
|
||
case PULL_DOWN:
|
||
my_menu_item = XmCreatePushButton (parent, name, Args, Nargs);
|
||
break;
|
||
case SEPARATOR:
|
||
my_menu_item = XmCreateSeparator (parent, NULL, Args, Nargs);
|
||
break;
|
||
default:
|
||
printf ("\007Illegal menu_type in call to AddMenuItem\n");
|
||
}
|
||
XtManageChild (my_menu_item);
|
||
|
||
if (callback != NULL)
|
||
XtAddCallback (my_menu_item, XmNactivateCallback, callback, NULL);
|
||
|
||
return my_menu_item;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** MakeLabel - make a simple label
|
||
*/
|
||
Widget MakeLabel (
|
||
/* =========
|
||
*/ Widget w, /* widget id of parent of label */
|
||
char *text, /* The text for the label */
|
||
unsigned char align) { /* The alignment for the label */
|
||
|
||
Widget my_label;
|
||
XmString my_compString;
|
||
|
||
my_compString = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
|
||
Nargs = 0;
|
||
XtSetArg (Args[Nargs], XmNlabelString, my_compString); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNentryAlignment, align); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNrecomputeSize, False); Nargs++;
|
||
my_label = XmCreateLabel (w, NULL, Args, Nargs);
|
||
XtManageChild (my_label);
|
||
XmStringFree (my_compString);
|
||
|
||
return my_label;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** QuitCB - callback for quit button
|
||
*/
|
||
void QuitCB (
|
||
/* ======
|
||
*/ Widget w, /* widget id */
|
||
XtPointer client_data, /* data from application */
|
||
XtPointer call_data) { /* data from widget class */
|
||
|
||
char buff[4];
|
||
|
||
if (Cnct_skt != 0) {
|
||
send (Cnct_skt, "-001", 4, 0); /* Tell our TCP/IP server that ..
|
||
** .. we are about to quit.
|
||
*/
|
||
recv (Cnct_skt, buff, sizeof (buff), 0); /* And wait for his ack */
|
||
close (Cnct_skt);
|
||
}
|
||
exit (True); /* Terminate the application. */
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** SollCB - callback for Soll-position Scale
|
||
*/
|
||
void SollCB (
|
||
/* ======
|
||
*/ Widget w, /* widget id */
|
||
XtPointer client_data, /* data from application */
|
||
XmScaleCallbackStruct *call_data) { /* data from widget class */
|
||
|
||
int status;
|
||
int i_tmp;
|
||
float f_tmp;
|
||
char fmt[80];
|
||
char text[80];
|
||
XmString tmp_cmpStr;
|
||
|
||
f_tmp = ((float) call_data->value)/((float) Mot_factor);
|
||
sprintf (text, "%.*f", Mot_state.dec_pt, f_tmp);
|
||
tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
|
||
XtVaSetValues (Label_soll,
|
||
XmNlabelString, tmp_cmpStr,
|
||
NULL);
|
||
XmStringFree (tmp_cmpStr);
|
||
|
||
if (call_data->reason != XmCR_VALUE_CHANGED) {
|
||
XmUpdateDisplay (Wtop_level);
|
||
return;
|
||
}
|
||
/*
|
||
** Adjust position of label to be near pointer. There is a
|
||
** complication if the position goes over the mid-point.
|
||
*/
|
||
i_tmp = call_data->value - (int) (Mot_lo_lim * Mot_factor);
|
||
if (((f_tmp < Mot_scale_middle) && Mot_is_on_left) ||
|
||
((f_tmp > Mot_scale_middle) && !Mot_is_on_left)) {
|
||
/*
|
||
** Get here if side has not changed.
|
||
*/
|
||
if (Mot_is_on_left) {
|
||
XtVaSetValues (Label_soll,
|
||
XmNleftPosition, i_tmp,
|
||
NULL);
|
||
XtVaSetValues (Label_ist,
|
||
XmNleftPosition, i_tmp,
|
||
NULL);
|
||
}else {
|
||
XtVaSetValues (Label_soll,
|
||
XmNrightPosition, i_tmp,
|
||
NULL);
|
||
XtVaSetValues (Label_ist,
|
||
XmNrightPosition, i_tmp,
|
||
NULL);
|
||
}
|
||
}else if (Mot_is_on_left) {
|
||
/*
|
||
** Get here if side has changed from left to right.
|
||
*/
|
||
Mot_is_on_left = False;
|
||
XtVaSetValues (Label_soll,
|
||
XmNleftAttachment, XmATTACH_NONE,
|
||
XmNleftPosition, 0,
|
||
XmNrightAttachment, XmATTACH_POSITION,
|
||
XmNrightPosition, i_tmp,
|
||
NULL);
|
||
XtVaSetValues (Label_ist,
|
||
XmNleftAttachment, XmATTACH_NONE,
|
||
XmNleftPosition, 0,
|
||
XmNrightAttachment, XmATTACH_POSITION,
|
||
XmNrightPosition, i_tmp,
|
||
NULL);
|
||
}else {
|
||
/*
|
||
** Get here if side has changed from right to left.
|
||
*/
|
||
Mot_is_on_left = True;
|
||
XtVaSetValues (Label_soll,
|
||
XmNleftAttachment, XmATTACH_POSITION,
|
||
XmNleftPosition, i_tmp,
|
||
XmNrightAttachment, XmATTACH_NONE,
|
||
XmNrightPosition, 0,
|
||
NULL);
|
||
XtVaSetValues (Label_ist,
|
||
XmNleftAttachment, XmATTACH_POSITION,
|
||
XmNleftPosition, i_tmp,
|
||
XmNrightAttachment, XmATTACH_NONE,
|
||
XmNrightPosition, 0,
|
||
NULL);
|
||
}
|
||
XmUpdateDisplay (Wtop_level);
|
||
|
||
Mot_state.ored_msr = 0;
|
||
Mot_state.fp_cntr = 0;
|
||
Mot_state.fr_cntr = 0;
|
||
sprintf (fmt, "p %d %%s\r", Motor);
|
||
status = SendCmndToServer (AppData.v24_chan, TMO,
|
||
&Respon_buff, sizeof (Respon_buff),
|
||
fmt, text,
|
||
NULL);
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** TimerCB - callback for timer
|
||
*/
|
||
void TimerCB (
|
||
/* =======
|
||
*/ XtPointer client_data, /* data from application */
|
||
XtIntervalId *id) { /* data from widget class */
|
||
|
||
static int first = True;
|
||
static int blink = True;
|
||
static Display *disp;
|
||
static Window wind;
|
||
static GC gc;
|
||
|
||
GetMotorStatus (SHORT__STATUS, &Mot_state);
|
||
SetStateInWindows (&Old_Mot_state, &Mot_state); /* Update window display. */
|
||
|
||
if (AppData.msec_timer > 0) {
|
||
XtAppAddTimeOut (App_context, AppData.msec_timer, TimerCB, NULL);
|
||
}else {
|
||
printf ("\007EL734 -- status polling disabled.\n");
|
||
}
|
||
#if Blink_On /* This is just an exercise to do a bit of graphics!! */
|
||
if (first) {
|
||
first = False;
|
||
disp = XtDisplay (DrawnBut);
|
||
wind = XtWindow (DrawnBut);
|
||
gc = DefaultGCOfScreen (XtScreen (DrawnBut));
|
||
}
|
||
if (blink) {
|
||
XFillArc (disp, wind, gc,
|
||
10, 10, 50, 50, 0, 360*64);
|
||
}else {
|
||
XClearArea (disp, wind, 10, 10, 50, 50, False);
|
||
}
|
||
blink = !blink;
|
||
#endif /* Blink_On */
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** CreateMenuBar - Create menu bar for main window.
|
||
*/
|
||
Widget CreateMenuBar (Widget window) {
|
||
/* =============
|
||
*/
|
||
Widget my_menu_bar; /* MenuBar */
|
||
|
||
Widget quit_menu_pane; /* Quit MenuPane */
|
||
Widget slct_menu_pane; /* Select MenuPane */
|
||
Widget help_menu_pane; /* Help MenuPane */
|
||
|
||
Widget mot_menu_pane; /* Motor MenuPane */
|
||
|
||
Widget my_button;
|
||
/*-------------------------------------------------------------
|
||
** Create MenuBar in MainWindow.
|
||
*/
|
||
Nargs = 0;
|
||
XtSetArg (Args[Nargs], XmNadjustLast, True); Nargs++;
|
||
my_menu_bar = XmCreateMenuBar (window, "menu_bar", Args, Nargs);
|
||
XtManageChild (my_menu_bar);
|
||
/*---------------------------------------------------------
|
||
** Create panes for the Menu Bar Pulldown Menus.
|
||
*/
|
||
Nargs = 0;
|
||
quit_menu_pane = XmCreatePulldownMenu (my_menu_bar, "Quit_Menu",
|
||
Args, Nargs);
|
||
slct_menu_pane = XmCreatePulldownMenu (my_menu_bar, "Select_Menu",
|
||
Args, Nargs);
|
||
help_menu_pane = XmCreatePulldownMenu (my_menu_bar, "Help_Menu",
|
||
Args, Nargs);
|
||
|
||
mot_menu_pane = XmCreatePulldownMenu (slct_menu_pane, "Motor_Menu",
|
||
Args, Nargs);
|
||
/*-------------------------------------------------------------
|
||
** Create buttons on menu bar and specify afterwards
|
||
** which one is the Help item.
|
||
*/
|
||
Wquit_cascade = AddMenuItem (my_menu_bar, "File", 'F',
|
||
CASCADE, quit_menu_pane, NULL);
|
||
Wslct_cascade = AddMenuItem (my_menu_bar, "Select", 'S',
|
||
CASCADE, slct_menu_pane, NULL);
|
||
Whelp_cascade = AddMenuItem (my_menu_bar, "Help", 'H',
|
||
CASCADE, help_menu_pane, NULL);
|
||
|
||
XtSetArg (Args[0], XmNmenuHelpWidget, Whelp_cascade);
|
||
XtSetValues (my_menu_bar, Args, 1);
|
||
/*---------------------------------------------------------
|
||
** Put items into the menu bar menu panes. Start with Exit.
|
||
*/
|
||
AddMenuItem (quit_menu_pane, "Quit/Finish", 'F', PULL_DOWN, NULL, QuitCB);
|
||
/*---------------------------------------------------------
|
||
** Now do Select.
|
||
*/
|
||
Wmot_cascade = AddMenuItem (slct_menu_pane,
|
||
"Motor", 'M', CASCADE, mot_menu_pane, NULL);
|
||
/*---------------------------------------------------------
|
||
** Now do Help.
|
||
*/
|
||
AddMenuItem (help_menu_pane, "Context-sensitive Help", 'C',
|
||
PULL_DOWN, NULL, ActivateCB);
|
||
AddMenuItem (help_menu_pane, NULL, '\0', SEPARATOR, NULL, NULL);
|
||
AddMenuItem (help_menu_pane, "Overview", 'O',
|
||
PULL_DOWN, NULL, ActivateCB);
|
||
/*---------------------------------------------------------
|
||
** Now do Motor.
|
||
*/
|
||
AddMenuItem (mot_menu_pane, "1", '1', PULL_DOWN, NULL, MotorSelectCB);
|
||
AddMenuItem (mot_menu_pane, "2", '2', PULL_DOWN, NULL, MotorSelectCB);
|
||
AddMenuItem (mot_menu_pane, "3", '3', PULL_DOWN, NULL, MotorSelectCB);
|
||
AddMenuItem (mot_menu_pane, "4", '4', PULL_DOWN, NULL, MotorSelectCB);
|
||
AddMenuItem (mot_menu_pane, "5", '5', PULL_DOWN, NULL, MotorSelectCB);
|
||
AddMenuItem (mot_menu_pane, "6", '6', PULL_DOWN, NULL, MotorSelectCB);
|
||
AddMenuItem (mot_menu_pane, "7", '7', PULL_DOWN, NULL, MotorSelectCB);
|
||
AddMenuItem (mot_menu_pane, "8", '8', PULL_DOWN, NULL, MotorSelectCB);
|
||
AddMenuItem (mot_menu_pane, "9", '9', PULL_DOWN, NULL, MotorSelectCB);
|
||
AddMenuItem (mot_menu_pane, "10 (0x0a)", 'a', PULL_DOWN, NULL, MotorSelectCB);
|
||
AddMenuItem (mot_menu_pane, "11 (0x0b)", 'b', PULL_DOWN, NULL, MotorSelectCB);
|
||
AddMenuItem (mot_menu_pane, "12 (0x0c)", 'c', PULL_DOWN, NULL, MotorSelectCB);
|
||
|
||
return my_menu_bar;
|
||
}
|
||
/*
|
||
**---------------------------------------------------------------------------
|
||
** CreateApplication - set up main window. Return value
|
||
** is main window widget.
|
||
*/
|
||
Widget CreateApplication (Widget parent) {
|
||
/* =================
|
||
*/
|
||
Widget main_window; /* MainWindow */
|
||
Widget form_0; /* Form Widget */
|
||
Widget rc_00; /* RowColumn Widget */
|
||
Widget rc_01; /* RowColumn Widget */
|
||
|
||
XmString tmp_cmpStr;
|
||
char text[80];
|
||
int i_left, i_right, i_soll, i_ist;
|
||
/*-------------------------------------------------------------*/
|
||
i_left = (int) (Mot_lo_lim * Mot_factor);
|
||
i_right = (int) (Mot_hi_lim * Mot_factor);
|
||
i_soll = (int) (Mot_pos_soll * Mot_factor);
|
||
i_ist = (int) (Mot_pos_ist * Mot_factor);
|
||
Mot_scale_middle = (Mot_lo_lim + Mot_hi_lim)/2.0;
|
||
if (Mot_pos_soll < Mot_scale_middle) {
|
||
Mot_is_on_left = True;
|
||
}else {
|
||
Mot_is_on_left = False;
|
||
}
|
||
/*-------------------------------------------------------------
|
||
** Create MainWindow.
|
||
*/
|
||
Nargs = 0;
|
||
main_window = XmCreateMainWindow (parent, "main_window", Args, Nargs);
|
||
XtManageChild (main_window);
|
||
|
||
CreateMenuBar (main_window);
|
||
/*
|
||
** Create Form Widget to hold the various items
|
||
** in the Main Window
|
||
*/
|
||
Nargs = 0;
|
||
form_0 = XmCreateForm (main_window, "form_0", Args, Nargs);
|
||
XtVaSetValues (form_0,
|
||
XmNfractionBase, (i_right - i_left),
|
||
NULL);
|
||
XtManageChild (form_0);
|
||
/*
|
||
** Create label to show lower limit
|
||
*/
|
||
sprintf (text, "%.*f", Mot_state.dec_pt, Mot_lo_lim);
|
||
tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
|
||
Nargs = 0;
|
||
XtSetArg (Args[Nargs], XmNentryAlignment, XmALIGNMENT_BEGINNING); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNrecomputeSize, True); Nargs++;
|
||
Label_lo_lim = XmCreateLabel (form_0, "Lo_Lim_Label", Args, Nargs);
|
||
XtManageChild (Label_lo_lim);
|
||
XmStringFree (tmp_cmpStr);
|
||
/*
|
||
** Create label to show motor number and name
|
||
*/
|
||
sprintf (text, "Motor %d \"%s\"", Motor, Mot_state.name);
|
||
tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
|
||
Nargs = 0;
|
||
XtSetArg (Args[Nargs], XmNentryAlignment, XmALIGNMENT_CENTER); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNrecomputeSize, True); Nargs++;
|
||
Label_name = XmCreateLabel (form_0, "Name_Label", Args, Nargs);
|
||
XtManageChild (Label_name);
|
||
XmStringFree (tmp_cmpStr);
|
||
/*
|
||
** Create label to show upper limit
|
||
*/
|
||
sprintf (text, "%.*f", Mot_state.dec_pt, Mot_hi_lim);
|
||
tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
|
||
Nargs = 0;
|
||
XtSetArg (Args[Nargs], XmNentryAlignment, XmALIGNMENT_END); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNrecomputeSize, True); Nargs++;
|
||
Label_hi_lim = XmCreateLabel (form_0, "Hi_Lim_Label", Args, Nargs);
|
||
XtManageChild (Label_hi_lim);
|
||
XmStringFree (tmp_cmpStr);
|
||
/*
|
||
** Create scales -- use resource value as dimension.
|
||
*/
|
||
/*
|
||
** Create label to show "Soll" position
|
||
*/
|
||
sprintf (text, "%.*f", Mot_state.dec_pt, Mot_pos_soll);
|
||
tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
|
||
Nargs = 0;
|
||
XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++;
|
||
Label_soll = XmCreateLabel (form_0, "Soll_Label", Args, Nargs);
|
||
XtManageChild (Label_soll);
|
||
XmStringFree (tmp_cmpStr);
|
||
/*
|
||
** Create scales to show "Soll" and "Ist" positions
|
||
*/
|
||
Nargs = 0;
|
||
XtSetArg (Args[Nargs], XmNdecimalPoints, Mot_state.dec_pt); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNminimum, i_left); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNmaximum, i_right); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNorientation, XmHORIZONTAL); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNscaleWidth, Scale_width); Nargs++;
|
||
|
||
Scale_soll = XmCreateScale (form_0, "Soll_Scale", Args, Nargs);
|
||
XtManageChild (Scale_soll);
|
||
|
||
Scale_ist = XmCreateScale (form_0, "Ist_Scale", Args, Nargs);
|
||
XtManageChild (Scale_ist);
|
||
|
||
XtVaSetValues (Scale_soll,
|
||
XmNvalue, i_soll,
|
||
XmNsensitive, True,
|
||
NULL);
|
||
|
||
XtVaSetValues (Scale_ist,
|
||
XmNvalue, i_ist,
|
||
XmNsensitive, False,
|
||
NULL);
|
||
|
||
XtAddCallback (Scale_soll, XmNdragCallback,
|
||
(XtCallbackProc) SollCB, NULL);
|
||
XtAddCallback (Scale_soll, XmNvalueChangedCallback,
|
||
(XtCallbackProc) SollCB, NULL);
|
||
/*
|
||
** Create label to show "Ist" position
|
||
*/
|
||
sprintf (text, "%.*f", Mot_state.dec_pt, Mot_pos_ist);
|
||
tmp_cmpStr = XmStringCreateLtoR (text, XmSTRING_DEFAULT_CHARSET);
|
||
Nargs = 0;
|
||
XtSetArg (Args[Nargs], XmNlabelString, tmp_cmpStr); Nargs++;
|
||
Label_ist = XmCreateLabel (form_0, "Ist_Label", Args, Nargs);
|
||
XtManageChild (Label_ist);
|
||
XmStringFree (tmp_cmpStr);
|
||
/*
|
||
** Create RowColumn widgets for status displays
|
||
*/
|
||
Nargs = 0;
|
||
XtSetArg (Args[Nargs], XmNnumColumns, 1); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNpacking, XmPACK_COLUMN); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNorientation, XmVERTICAL); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNentryAlignment, XmALIGNMENT_BEGINNING); Nargs++;
|
||
rc_00 = XmCreateRowColumn (form_0, "RowCol_00", Args, Nargs);
|
||
XtManageChild (rc_00);
|
||
|
||
Nargs = 0;
|
||
XtSetArg (Args[Nargs], XmNnumColumns, 3); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNpacking, XmPACK_COLUMN); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNorientation, XmVERTICAL); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNentryAlignment, XmALIGNMENT_BEGINNING); Nargs++;
|
||
rc_01 = XmCreateRowColumn (form_0, "RowCol_01", Args, Nargs);
|
||
XtManageChild (rc_01);
|
||
/*
|
||
** create labels for RowColumn widgets
|
||
*/
|
||
EncodeMSR (text, sizeof (text), Mot_state.msr,
|
||
Mot_state.ored_msr,
|
||
Mot_state.fp_cntr,
|
||
Mot_state.fr_cntr);
|
||
Label_msr = MakeLabel (rc_00, text, XmALIGNMENT_BEGINNING);
|
||
|
||
EncodeSS (text, Mot_state.ss);
|
||
Label_ss = MakeLabel (rc_00, text, XmALIGNMENT_BEGINNING);
|
||
|
||
sprintf (text, "Statistics: Total/Faults/Fails/Cush-fails = %d/%d/%d/%d",
|
||
Mot_state.stat_pos, Mot_state.stat_pos_flt,
|
||
Mot_state.stat_pos_fail, Mot_state.stat_cush_fail);
|
||
Label_stats = MakeLabel (rc_00, text, XmALIGNMENT_BEGINNING);
|
||
|
||
sprintf (text, "Encoder Ratio, FD = %d:%d", Mot_state.enc_factor[0],
|
||
Mot_state.enc_factor[1]);
|
||
Label_fd = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
sprintf (text, "Motor Ratio, FM = %d:%d", Mot_state.mot_factor[0],
|
||
Mot_state.mot_factor[1]);
|
||
Label_fm = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
sprintf (text, "Inertia tol'nce, D = %s", Mot_state.inertia_tol);
|
||
Label_d = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
sprintf (text, "Start/stop ramp, E = %d", Mot_state.ramp);
|
||
Label_e = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
switch (Mot_state.loop_mode) {
|
||
case 0: sprintf (text, "Open loop mode, F = 0"); break;
|
||
case 1: sprintf (text, "Closed loop mode, F = 1"); break;
|
||
default: sprintf (text, "Bad loop mode, F = %d", Mot_state.loop_mode);
|
||
}
|
||
Label_f = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
sprintf (text, "Start/stop Hz, G = %d", Mot_state.slow_hz);
|
||
Label_g = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
sprintf (text, "Positioning Hz, J = %d", Mot_state.fast_hz);
|
||
Label_j = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
switch (Mot_state.ref_mode) {
|
||
case 0: sprintf (text, "Absolute encoder, K = 0"); break;
|
||
case 1: sprintf (text, "HiLimit is RefPt, K = 1"); break;
|
||
case -1: sprintf (text, "LoLimit is RefPt, K = -1"); break;
|
||
case 2: sprintf (text, "Sep RefPt, K = 2"); break;
|
||
case 11: sprintf (text, "HiLimit is RefPt + Indx, K = 11"); break;
|
||
case -11: sprintf (text, "LoLimit is RefPt + Indx, K = -11"); break;
|
||
case 12: sprintf (text, "Sep RefPt + Indx, K = 12"); break;
|
||
default: sprintf (text, "RefMode unknown, K = %d", Mot_state.ref_mode);
|
||
}
|
||
Label_k = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
sprintf (text, "Backlash, L = %d", Mot_state.backlash);
|
||
Label_l = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
sprintf (text, "Position Tol'nce, M = %d", Mot_state.pos_tol);
|
||
Label_m = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
sprintf (text, "RefPt Width, Q = %s", Mot_state.ref_param);
|
||
Label_q = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
if (Mot_state.is_sided == 0) {
|
||
sprintf (text, "No dir'n dependency, T = 0");
|
||
}else if (Mot_state.is_sided > 0) {
|
||
sprintf (text, "Position from above, T = %d", Mot_state.is_sided);
|
||
}else {
|
||
sprintf (text, "Position from below, T = %d", Mot_state.is_sided);
|
||
}
|
||
Label_t = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
sprintf (text, "NullPt, V = %s", Mot_state.null_pt);
|
||
Label_v = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
if (Mot_state.ac_par == 0) {
|
||
sprintf (text, "No air-cushion present, W = 0");
|
||
}else if (Mot_state.ac_par == Motor) {
|
||
if (Mot_state.ac_state == 0) {
|
||
sprintf (text, "Air-cushion down");
|
||
}else {
|
||
sprintf (text, "Air-cushion up");
|
||
}
|
||
}else {
|
||
if (Mot_state.ac_state == 0) {
|
||
sprintf (text, "Air-cushion up (chained to %d)", Mot_state.ac_par);
|
||
}else {
|
||
sprintf (text, "Air-cushion down (chained to %d)", Mot_state.ac_par);
|
||
}
|
||
}
|
||
Label_w = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
if (Mot_state.out == 0) {
|
||
sprintf (text, "Output signal not active", Mot_state.null_pt);
|
||
}else {
|
||
sprintf (text, "Output signal active", Mot_state.null_pt);
|
||
}
|
||
Label_out = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
if (Mot_state.in == 0) {
|
||
sprintf (text, "Input signal not present");
|
||
}else {
|
||
sprintf (text, "Input signal present");
|
||
}
|
||
Label_in = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
sprintf (text, "Enc Circum, Z = %d", Mot_state.enc_circ);
|
||
Label_z = MakeLabel (rc_01, text, XmALIGNMENT_BEGINNING);
|
||
/*
|
||
** Create DrawnButton in Frame for a bit of research
|
||
*/
|
||
#if Blink_On
|
||
Nargs = 0;
|
||
DrawnButFrame = XmCreateFrame (form_0, "Button_Frame", Args, Nargs);
|
||
XtManageChild (DrawnButFrame);
|
||
|
||
Nargs = 0;
|
||
XtSetArg (Args[Nargs], XmNminimum, i_left); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNmaximum, i_right); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNwidth, Scale_width/2); Nargs++;
|
||
XtSetArg (Args[Nargs], XmNheight, 100); Nargs++;
|
||
DrawnBut = XmCreateDrawnButton (DrawnButFrame, "Drawn_Button", Args, Nargs);
|
||
XtManageChild (DrawnBut);
|
||
#endif /* Blink_On */
|
||
/*-------------------------------------------------------------
|
||
** Organise the components of the Main Form
|
||
*/
|
||
XtVaSetValues (Label_lo_lim,
|
||
XmNtopAttachment, XmATTACH_FORM,
|
||
XmNleftAttachment, XmATTACH_FORM,
|
||
NULL);
|
||
|
||
XtVaSetValues (Label_name,
|
||
XmNtopAttachment, XmATTACH_FORM,
|
||
XmNleftAttachment, XmATTACH_WIDGET,
|
||
XmNleftWidget, Label_lo_lim,
|
||
XmNrightAttachment, XmATTACH_WIDGET,
|
||
XmNrightWidget, Label_hi_lim,
|
||
NULL);
|
||
|
||
XtVaSetValues (Label_hi_lim,
|
||
XmNtopAttachment, XmATTACH_FORM,
|
||
XmNrightAttachment, XmATTACH_FORM,
|
||
NULL);
|
||
|
||
XtVaSetValues (Label_soll,
|
||
XmNtopAttachment, XmATTACH_WIDGET,
|
||
XmNtopWidget, Label_name,
|
||
NULL);
|
||
if (Mot_is_on_left) {
|
||
XtVaSetValues (Label_soll,
|
||
XmNleftAttachment, XmATTACH_POSITION,
|
||
XmNleftPosition, (i_soll - i_left),
|
||
NULL);
|
||
}else {
|
||
XtVaSetValues (Label_soll,
|
||
XmNrightAttachment, XmATTACH_POSITION,
|
||
XmNrightPosition, (i_soll - i_left),
|
||
NULL);
|
||
}
|
||
|
||
XtVaSetValues (Scale_soll,
|
||
XmNleftAttachment, XmATTACH_FORM,
|
||
XmNtopAttachment, XmATTACH_WIDGET,
|
||
XmNtopWidget, Label_soll,
|
||
NULL);
|
||
|
||
XtVaSetValues (Scale_ist,
|
||
XmNleftAttachment, XmATTACH_FORM,
|
||
XmNtopAttachment, XmATTACH_WIDGET,
|
||
XmNtopWidget, Scale_soll,
|
||
NULL);
|
||
|
||
XtVaSetValues (Label_ist,
|
||
XmNtopAttachment, XmATTACH_WIDGET,
|
||
XmNtopWidget, Scale_ist,
|
||
NULL);
|
||
if (Mot_is_on_left) {
|
||
XtVaSetValues (Label_ist,
|
||
XmNleftAttachment, XmATTACH_POSITION,
|
||
XmNleftPosition, (i_ist - i_left),
|
||
NULL);
|
||
}else {
|
||
XtVaSetValues (Label_ist,
|
||
XmNrightAttachment, XmATTACH_POSITION,
|
||
XmNrightPosition, (i_ist - i_left),
|
||
NULL);
|
||
}
|
||
XtVaSetValues (rc_00,
|
||
XmNleftAttachment, XmATTACH_FORM,
|
||
XmNtopAttachment, XmATTACH_WIDGET,
|
||
XmNtopWidget, Label_ist,
|
||
NULL);
|
||
XtVaSetValues (rc_01,
|
||
XmNleftAttachment, XmATTACH_FORM,
|
||
XmNtopAttachment, XmATTACH_WIDGET,
|
||
XmNtopWidget, rc_00,
|
||
NULL);
|
||
#if Blink_On
|
||
XtVaSetValues (DrawnButFrame,
|
||
XmNleftAttachment, XmATTACH_FORM,
|
||
XmNtopAttachment, XmATTACH_WIDGET,
|
||
XmNtopWidget, Label_stats,
|
||
NULL);
|
||
#endif /* Blink_On */
|
||
return main_window;
|
||
}
|
||
/*
|
||
**==========================================================================
|
||
** Main line program
|
||
** ------------------
|
||
*/
|
||
int main (int argc, char **argv) {
|
||
/* ============================
|
||
*/
|
||
Widget main_window; /* MainWindow */
|
||
int status, i;
|
||
/*-------------------------------------------------
|
||
** Initialize Mot_state to rubbish.
|
||
*/
|
||
memset (&Mot_state, '%', sizeof (Mot_state));
|
||
Mot_state.motor = Motor;
|
||
Mot_state.exists = False;
|
||
Mot_state.ored_msr = 0;
|
||
Mot_state.fp_cntr = 0;
|
||
Mot_state.fr_cntr = 0;
|
||
Mot_state.pos_real[15] = '\0';
|
||
Mot_state.name[15] = '\0';
|
||
Mot_state.inertia_tol[15] = '\0';
|
||
Mot_state.lims[0][15] = '\0';
|
||
Mot_state.lims[1][15] = '\0';
|
||
Mot_state.ref_param[15] = '\0';
|
||
Mot_state.null_pt[15] = '\0';
|
||
Mot_state.set_real[15] = '\0';
|
||
memcpy (&Old_Mot_state, &Mot_state, sizeof (Mot_state));
|
||
/*
|
||
** Initialize toolkit and open the display.
|
||
*/
|
||
Wtop_level = XtAppInitialize (&App_context, "SinQ_rc",
|
||
OpTable, XtNumber(OpTable),
|
||
&argc, argv, NULL, NULL, 0);
|
||
|
||
XtGetApplicationResources (Wtop_level, (XtPointer) &AppData,
|
||
Resources, XtNumber(Resources), NULL, 0);
|
||
|
||
printf ("Motor Client, Version %s\n\n", ident);
|
||
|
||
if (strcmp (AppData.vme_motor_host, "Undefined") == 0) {
|
||
printf (" \"-host\" not specified!\n\n");
|
||
return EXIT_FAILURE;
|
||
}
|
||
|
||
if (AppData.v24_chan == 0xffff) {
|
||
printf (" \"-chan\" not specified!\n\n");
|
||
return EXIT_FAILURE;
|
||
}else if ((AppData.v24_chan < 0) || (AppData.v24_chan > 15)) {
|
||
printf (" \"-chan\" is illegal!\n\n");
|
||
return EXIT_FAILURE;
|
||
}
|
||
|
||
if ((AppData.vme_motor_number <= 0) || (AppData.vme_motor_number > 12)) {
|
||
printf (" \"-motor\" not specified or illegal!\n\n");
|
||
return EXIT_FAILURE;
|
||
}
|
||
|
||
printf ("Motor Server = \"%s\"\n",
|
||
AppData.vme_motor_host);
|
||
|
||
if (AppData.vme_motor_port == 0) {
|
||
AppData.vme_motor_port = 4000;
|
||
printf ("Default TCP/IP Port = %d\n", AppData.vme_motor_port);
|
||
}else {
|
||
printf ("TCP/IP Port = %d\n", AppData.vme_motor_port);
|
||
}
|
||
|
||
printf ("RS-232-C channel = %d\n", AppData.v24_chan);
|
||
printf ("Polling delay = %d msec.\n", AppData.msec_timer);
|
||
Scale_width = AppData.scale_width;
|
||
printf ("Scale width = %d pixels.\n\n", Scale_width);
|
||
|
||
Motor = AppData.vme_motor_number;
|
||
printf ("Motor number = %d.\n\n", Motor);
|
||
|
||
printf ("Opening connection to Motor Server ...\n");
|
||
Cnct_skt = ConnectToSrvr (AppData.vme_motor_host,
|
||
AppData.vme_motor_port);
|
||
|
||
Mot_state.motor = Motor;
|
||
|
||
printf ("Ensuring EL734 is in \"rmt 1\" mode ...\n");
|
||
status = SendCmndToServer (AppData.v24_chan, TMO,
|
||
&Respon_buff, sizeof (Respon_buff),
|
||
"rmt 1\r", NULL,
|
||
"rmt 1\r", NULL,
|
||
NULL);
|
||
|
||
printf ("Ensuring EL734 is in \"echo 0\" mode ...\n");
|
||
status = SendCmndToServer (AppData.v24_chan, TMO,
|
||
&Respon_buff, sizeof (Respon_buff),
|
||
"echo 0\r", NULL,
|
||
NULL);
|
||
|
||
printf ("Getting full status of Motor ...\n");
|
||
GetMotorStatus (FULL__STATUS, &Mot_state);
|
||
if (!Mot_state.exists) {
|
||
printf ("\007Selected motor is off-line.\n");
|
||
exit (False);
|
||
}
|
||
memcpy (&Old_Mot_state, &Mot_state, sizeof (Mot_state));
|
||
|
||
main_window = CreateApplication (Wtop_level);
|
||
/*
|
||
** Realize Widgets
|
||
*/
|
||
XtRealizeWidget (Wtop_level);
|
||
/*
|
||
** Make a timer so that the display gets updated regularly.
|
||
*/
|
||
if (AppData.msec_timer > 0) {
|
||
XtAppAddTimeOut (App_context, AppData.msec_timer, TimerCB, NULL);
|
||
} else {
|
||
printf ("msecTimer = 0. Continuous status update disabled.\n");
|
||
}
|
||
/*
|
||
** process events
|
||
*/
|
||
XtAppMainLoop (App_context);
|
||
}
|
||
/*------------------------------------------------------ End of EL734.C */
|