From 7f80f5fd873b0f2b06f6d544db1c3fac6c876cbb Mon Sep 17 00:00:00 2001 From: cvs Date: Wed, 13 Sep 2000 14:28:36 +0000 Subject: [PATCH] Some utilities which might be useful. --- utils/el734.c | 2087 ++++++++++++++++++++++ utils/el734_test.c | 4133 ++++++++++++++++++++++++++++++++++++++++++++ utils/el737.c | 2848 ++++++++++++++++++++++++++++++ 3 files changed, 9068 insertions(+) create mode 100755 utils/el734.c create mode 100755 utils/el734_test.c create mode 100755 utils/el737.c diff --git a/utils/el734.c b/utils/el734.c new file mode 100755 index 00000000..3f6e32bd --- /dev/null +++ b/utils/el734.c @@ -0,0 +1,2087 @@ +#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 *el734Host None +** -port *el734Port 4000 +** -chan *el734Chan None +** -poll EL734.msecPoll 1000 +** -m EL734.el734Motor None +** -scale EL734.scaleWidth: 800 +** where +** must be in the range 1 to 12. It is the motor which +** will be controlled. +** 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 +#include +#include +#include +#include + +#ifdef __VMS +#include +#include +#else +#include +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +/* +**-------------------------------------------------------------------------- +** Define global structures and constants. +*/ +#include +#include +#include + +#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", + ((char *) state) + Offsets[indx]); + indx++; + break; + case TWO_INT: + sscanf (rply_ptr->rply, "%d %d", + ((char *) state) + Offsets[indx], + ((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 */ diff --git a/utils/el734_test.c b/utils/el734_test.c new file mode 100755 index 00000000..52876100 --- /dev/null +++ b/utils/el734_test.c @@ -0,0 +1,4133 @@ +#define ident "1F01" +#define Active_Motor 1 + +#ifdef __DECC +#pragma module EL734_TEST 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 tas_src:[utils]el734_test debug +**!$! +**!$! To build on PSICL0 ... +**!$! $ build_cc_select :== decc +**!$! $ set default usr_scroot:[maden] +**!$! $ copy lnsa09::ud0:[maden.motor]el734_test.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_test debug +**!$! +**!$ if p1 .eqs. "DEBUG" then dbg1 := /debug +**!$ if p1 .eqs. "DEBUG" then dbg2 := _dbg +**!$ link 'dbg1'/exe=el734_test'dbg2'.exe sys$input/options +**! el734_test +**! mad_lib:sinq_dbg.olb/lib/include=(el734_errcodes,asynsrv_errcodes) +**! sys$share:decw$xmlibshr12/share +**! sys$share:decw$xtlibshrr5/share +**! sys$share:decw$xlibshr/share +**!$ purge/nolog el734_test'dbg2'.exe +**!$ set prot=w:re el734_test'dbg2'.exe +**!$ my_dir = f$element (0, "]", f$environment ("procedure")) + "]" +**!$ write sys$output "Exec file is ''my_dir'EL734_TEST''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_test.c" \ +** $TAS_SRC/utils/el734_test.c +** cc -std -g -o $TAS_BIN/el734_test \ +** -I$TAS_INC \ +** $TAS_SRC/utils/el734_test.c \ +** -L$TAS_LIB -lsinq -lrt -lXm -lXt -lX11 +** +** Resources and Flags File: decw$user_defaults:SinQ_rc.dat +** ------------------- or $HOME/SinQ_rc +** +** Resource Flag Default Description +** -------- ---- ------- ----------- +** - -name el734_test Name to use when looking up the +** resources. The default is the +** image file name. +** ... +** A value given via -name will be converted to lowercase before being used. +**+ +**--------------------------------------------------------------------------- +** Module Name . . . . . . . . : [...MOTOR]EL734_TEST.C +** +** Author . . . . . . . . . . : D. Maden +** Date of creation . . . . . . : Nov 1995 +** +** Purpose +** ======= +** EL734_TEST is a test program for the EL734 Motor Controller. +** Use: +** === +** 1) On VMS, define a foreign command, e.g. +** +** $ el734_test :== $psi_public:[exe_axp]el734_test.exe +** +** On Unix systems, ensure el734_test is in a suitable PATH directory. +** +** 2) Issue commands of the form: +** +** el734_test -host lnsp22 -chan 5 -m 6 -p 25.0 +** +** where +** -host specifies the name of the computer to which the EL734 is +** attached. This computer must be running the +** RS232C_SRV program or equivalent. +** -chan specifies the serial channel number to which the EL734 is +** attached. +** -m specifies the motor number to be driven and +** -p specifies that a positioning command is to be executed. +** +** For a full list of options, issue the command: +** +** el734_test -help +** +** Updates: +** 1A01 25-Nov-1994 DM. Initial version. +** 1C01 12-Sep-1996 DM. Use SINQ.OLB and SINQ_C.TLB on VMS. +** 1D01 6-Nov-1996 DM. Add EC command to SAVE command list. +** 1E01 8-May-1997 DM. Add RESTORE and NO_RESTORE to LOAD command list. +** 1F01 30-May-2000 DM. Add DIFF command list. +**- +**==================================================================== +*/ +#include +#include +#include +#include + +#include + +#ifdef __VMS +#include +#else +#include +#endif + +#include +/* +**==================================================================== +*/ + +#include +#include +/* + +**-------------------------------------------------------------------------- +** Define global structures and constants. +*/ +#define NIL '\0' +#ifndef True +#define True 1 +#define False 0 +#endif +/* +** Define the file idents for stdin, stdout and stderr +*/ +#define STDIN 0 +#define STDOUT 1 +#define STDERR 2 + +#define N_ELEMENTS(arg) (sizeof (arg)/sizeof (arg[0])) +/*------------------------------------------------------------- +** Global Variables +*/ + static int C_gbl_status; /* Return status from C_... routines */ + static int Ctrl_C_has_happened; + void *Hndl = NULL; + + static XrmOptionDescRec OpTable_0[] = { + {"-name", ".name", XrmoptionSepArg, (XPointer) NULL}, + {"-?", ".el734HelpItem", XrmoptionSepArg, (XPointer) NULL}, + {"-?cmd", ".el734HelpCmd", XrmoptionNoArg, (XPointer) "1"}, + {"-?msg", ".el734HelpMsg", XrmoptionNoArg, (XPointer) "1"}, + {"-?par", ".el734HelpPar", XrmoptionNoArg, (XPointer) "1"}, + {"-?res", ".el734HelpRes", XrmoptionNoArg, (XPointer) "1"}, + {"-chan", ".el734Chan", XrmoptionSepArg, (XPointer) NULL}, + {"-diff", ".el734Diff", XrmoptionSepArg, (XPointer) NULL}, + {"-f", ".el734Frequency", XrmoptionSepArg, (XPointer) NULL}, + {"-fb", ".el734Fb", XrmoptionNoArg, (XPointer) "-1"}, + {"-ff", ".el734Ff", XrmoptionNoArg, (XPointer) "-1"}, + {"-frequency",".el734Frequency", XrmoptionSepArg, (XPointer) NULL}, + {"-help", ".el734Help", XrmoptionNoArg, (XPointer) "1"}, + {"-hi", ".el734High", XrmoptionSepArg, (XPointer) NULL}, + {"-high", ".el734High", XrmoptionSepArg, (XPointer) NULL}, + {"-host", ".el734Host", XrmoptionSepArg, (XPointer) NULL}, + {"-hunt", ".el734Hunt", XrmoptionNoArg, (XPointer) "1"}, + {"-id", ".el734Id", XrmoptionSepArg, (XPointer) NULL}, + {"-limits", ".el734Limits", XrmoptionSepArg, (XPointer) NULL}, + {"-lo", ".el734Low", XrmoptionSepArg, (XPointer) NULL}, + {"-load", ".el734Load", XrmoptionSepArg, (XPointer) NULL}, + {"-low", ".el734Low", XrmoptionSepArg, (XPointer) NULL}, + {"-m", ".el734Motor", XrmoptionSepArg, (XPointer) NULL}, + {"-motor", ".el734Motor", XrmoptionSepArg, (XPointer) NULL}, + {"-n", ".el734N", XrmoptionSepArg, (XPointer) NULL}, + {"-p", ".el734Position", XrmoptionSepArg, (XPointer) NULL}, + {"-port", ".el734Port", XrmoptionSepArg, (XPointer) NULL}, + {"-position", ".el734Position", XrmoptionSepArg, (XPointer) NULL}, + {"-random", ".el734Random", XrmoptionNoArg, (XPointer) "1"}, + {"-ref", ".el734Ref", XrmoptionNoArg, (XPointer) "1"}, + {"-rndm", ".el734Random", XrmoptionNoArg, (XPointer) "1"}, + {"-s", ".el734Stop", XrmoptionNoArg, (XPointer) "1"}, + {"-save", ".el734Save", XrmoptionSepArg, (XPointer) NULL}, + {"-saw", ".el734Saw", XrmoptionNoArg, (XPointer) "1"}, + {"-sb", ".el734Sb", XrmoptionNoArg, (XPointer) "-1"}, + {"-scan", ".el734Scan", XrmoptionNoArg, (XPointer) "-1"}, + {"-seed", ".el734Seed", XrmoptionSepArg, (XPointer) NULL}, + {"-sf", ".el734Sf", XrmoptionNoArg, (XPointer) "-1"}, + {"-step", ".el734Step", XrmoptionSepArg, (XPointer) NULL}, + {"-stop", ".el734Stop", XrmoptionNoArg, (XPointer) "1"}, + {"-tmo", ".el734Tmo", XrmoptionSepArg, (XPointer) NULL}, + {"-ur@", ".el734SetPos", XrmoptionSepArg, (XPointer) NULL}, + {"-v", ".el734Verbose", XrmoptionSepArg, (XPointer) NULL}, + {"-V", ".el734VeryVerbose",XrmoptionNoArg, (XPointer) "1"}, + {"-wait", ".el734Wait", XrmoptionSepArg, (XPointer) NULL}, + }; + char El734_host[20]; + int El734_port; /* TCP/IP Port number for socket */ + int El734_chan; /* Asynch channel number */ + char El734_id0[20]; /* The 1st EL734 identifier string */ + char El734_id1[20]; /* The 2nd EL734 identifier string */ + int Check_EL734_id; + int Motor; /* Motor number */ + int Enc_typ; + int Enc_num; + int Enc_par; + int N_moves; + float Lo_arg, Hi_arg; + int Lo_arg_present, Hi_arg_present; + int Do_help, Do_posit, Do_rndm, Do_saw, Do_scan, Do_step; + int Do_ref, Do_hunt, Do_ff, Do_fb, Do_sf, Do_sb, Do_stop; + int Do_save, Do_load, Do_diff; + int Do_limits, Do_setpos; + float Lim_arg_lo, Lim_arg_hi, Ist_arg; + float Tmo, Tmo_ref; + unsigned int Seed; + int Seed_present; + int Verbose; + int Very_verbose; + int Wait_time, Frequency; + float Soll_posit; + float Step; + char Save_file[80]; + char Load_file[80]; + char Diff_file[80]; + + int Dec_pt = 3; + int Enc_fact_0, Enc_fact_1; + int Mot_fact_0, Mot_fact_1; + float Inertia_tol; + int Ramp; + int Loop_mode; + int Slow_hz; + float Lo, Hi; + char Ctrl_id[32]; + int Fast_hz; + int Ref_mode; + int Backlash; + int Pos_tol; + char Mot_mem[16]; + char Mot_name[16]; + float Ref_param; + int Is_sided; + int Null_pt; + int Ac_par; + int Enc_circ; + int Stat_pos; + int Stat_pos_flt; + int Stat_pos_fail; + int Stat_cush_fail; + float Ist_pos; + int Prop; + int Integ; + int Deriv; + + char *Errstack; + int Errcode, Errno, Vaxc_errno; +/* +**-------------------------------------------------------------------------- +** PrintErrInfo: print out error information. +*/ + int PrintErrInfo (char *text) { +/* ============ +*/ + + EL734_ErrInfo (&Errstack, &Errcode, &Errno, &Vaxc_errno); + fprintf (stderr, "\n\007" + " Error return from %s\n" + " Errstack = \"%s\"\n" + " Errcode = %d Errno = %d Vaxc$errno = %d\n", + text, Errstack, Errcode, Errno, Vaxc_errno); + switch (Errcode) { + case EL734__BAD_ADR: + fprintf (stderr, " Address error\n"); break; + case EL734__BAD_CMD: + fprintf (stderr, " Command error\n"); break; + case EL734__BAD_ILLG: + fprintf (stderr, " Illegal response\n"); break; + case EL734__BAD_LOC: + fprintf (stderr, " EL734 is in manual mode.\n"); break; + case EL734__BAD_MALLOC: + fprintf (stderr, " Call to \"malloc\" failed\n"); perror (text); break; + case EL734__BAD_OFL: + fprintf (stderr, " Connection to asynch port lost\n"); break; + case EL734__BAD_OVFL: + fprintf (stderr, " Overflow: may be due to bad encoder gearing factor\n"); break; + case EL734__BAD_PAR: + fprintf (stderr, " Illegal parameter specified\n"); break; + case EL734__BAD_RNG: + fprintf (stderr, " Attempted to exceed lower or upper limit\n"); break; + case EL734__BAD_SOCKET: + fprintf (stderr, " Call to \"AsynSrv_Open\" failed\n"); perror (text); break; + case EL734__BAD_STP: + fprintf (stderr, " Motor is disabled: \"Stop\" signal is active!"); + break; + case EL734__BAD_TMO: + fprintf (stderr, " Time-out of EL734 response.\n"); + break; + default: if ((Errno != 0) || (Vaxc_errno != 0)) perror (text); + } + return Errcode; + } +/* +**-------------------------------------------------------------------------- +** GetKHVQZ: read the K, H, V, Q and Zero-point parameters +*/ + int GetKHVQZ ( +/* ======== +*/ int *k, + float *lo, + float *hi, + int *v, + float *q, + float *z) { + + int status; + + status = EL734_GetRefMode (&Hndl, k); + if (!status) { + printf ("\n\007"); + printf ("Bad status from EL734_GetRefMode.\n"); + return False; + } + + status = EL734_GetLimits (&Hndl, lo, hi); + if (!status) { + printf ("\n\007"); + printf ("Bad status from EL734_GetLimits.\n"); + return False; + } + + status = EL734_GetNullPoint (&Hndl, v); + if (!status) { + printf ("\n\007"); + printf ("Bad status from EL734_GetZeroPoint.\n"); + return False; + } + + status = EL734_GetRefParam (&Hndl, q); + if (!status) { + printf ("\n\007"); + printf ("Bad status from EL734_GetRefParam.\n"); + return False; + } + + status = EL734_GetZeroPoint (&Hndl, z); + if (!status) { + printf ("\n\007"); + printf ("Bad status from EL734_GetZeroPoint.\n"); + return False; + } + + return True; + } +/* +**--------------------------------------------------------------------------- +** My_WaitIdle: Wait till MSR goes to zero or +** This routine is similar to EL734_WaitIdle +** with the extra verbose argument and a test +** for . +*/ + int My_WaitIdle ( +/* =========== +*/ void **handle, + int verbose, /* Width of display field */ + int *ored_msr, + int *fp_cntr, + int *fr_cntr, + float *ist_posit) { +#ifdef __VMS +#include +#define hibernate lib$wait (0.25) +#else +#include +#include + struct timespec delay = {0, 250000000}; + struct timespec delay_left; +#define hibernate nanosleep (&delay, &delay_left) +#endif + int i, msr, ss, s_stat; + int my_verbose; + float last_posit; + char buff[64]; + + my_verbose = verbose; + if (my_verbose*2 > sizeof (buff)) my_verbose = sizeof (buff)/2; + if (my_verbose > 0) { + s_stat = EL734_GetStatus (handle, + &msr, ored_msr, fp_cntr, fr_cntr, &ss, ist_posit); + if (!s_stat) { + PrintErrInfo ("My_WaitIdle/EL734_GetStatus"); + return False; + } + last_posit = *ist_posit; + sprintf (buff, "%*.*f", my_verbose, Dec_pt, last_posit); + printf (buff); fflush (NULL); + for (i=0; i 0) && (*ist_posit != last_posit)) { + last_posit = *ist_posit; + sprintf (&buff[my_verbose], "%*.*f", my_verbose, Dec_pt, last_posit); + printf (buff); fflush (NULL); + } + if ((msr & MSR__BUSY) == 0) return True; + hibernate; + if (Ctrl_C_has_happened) return False; + } + PrintErrInfo ("My_WaitIdle/EL734_GetStatus"); /* Error detected in + ** EL734_GetStatus */ + return False; + } +/* +**-------------------------------------------------------------------------- +** LoadCheckTwoInteger: routine to check that a command specifying +** two integers set correctly. +*/ + int LoadCheckTwoInteger (char *cmnd) { +/* =================== +*/ + int status, len; + char my_cmnd[80], rd_cmnd[40], buff[40]; + char *cmnd_tok, *motor_tok, *par0_tok, *par1_tok, *rd0_tok, *rd1_tok; + + StrJoin (my_cmnd, sizeof (my_cmnd), cmnd, ""); /* Make a copy of cmnd */ + len = strlen (my_cmnd); + if (my_cmnd[len-1] == '\r') my_cmnd[len-1] = NIL; + + cmnd_tok = strtok (my_cmnd, " "); + motor_tok = strtok (NULL, " "); + par0_tok = strtok (NULL, " "); + par1_tok = strtok (NULL, " "); + if ((cmnd_tok == NULL) || (motor_tok == NULL) || + (par0_tok == NULL) || (par1_tok == NULL)) { + printf ("\007Software problem in LoadCheckTwoInteger\n"); + return False; + } + StrJoin (buff, sizeof (buff), cmnd_tok, " "); + StrJoin (rd_cmnd, sizeof (rd_cmnd), buff, motor_tok); + len = strlen (rd_cmnd); + rd_cmnd[len] = '\r'; + rd_cmnd[len+1] = NIL; + status = EL734_SendCmnd (&Hndl, rd_cmnd, buff, sizeof (buff)); + if (status) { + rd0_tok = strtok (buff, " "); + rd1_tok = strtok (NULL, " "); + if ((rd0_tok == NULL) || + (rd1_tok == NULL) || + (strcmp (par0_tok, rd0_tok) != 0) || + (strcmp (par1_tok, rd1_tok) != 0)) { + if (rd0_tok == NULL) rd0_tok = ""; + if (rd1_tok == NULL) rd1_tok = ""; + printf ("\007Verify error for command \"%s %s %s %s\"\n", + cmnd_tok, motor_tok, par0_tok, par1_tok); + printf ("Values set in EL734 controller are \"%s %s\"\n" + " They should be \"%s %s\"\n", + rd0_tok, rd1_tok, par0_tok, par1_tok); + return False; + }else { + return True; /* The parameter has been set correctly! */ + } + }else { + printf ("\007LoadCheckTwoInteger -- error from EL734_SendCmnd\n"); + printf ("Command being checked was \"%s %s %s %s\"\n", + cmnd_tok, motor_tok, par0_tok, par1_tok); + return False; + } + } +/* +**-------------------------------------------------------------------------- +** LoadCheckTwoFloat: routine to check that a command specifying +** two real values set correctly. +*/ + int LoadCheckTwoFloat (char *cmnd, int n_dec) { +/* ================= +*/ + int status, len; + char my_cmnd[80], rd_cmnd[40], buff[40], par0[40], par1[40]; + char *cmnd_tok, *motor_tok, *par0_tok, *par1_tok, *rd0_tok, *rd1_tok; + char *whole_tok, *frac_tok; + + StrJoin (my_cmnd, sizeof (my_cmnd), cmnd, ""); /* Make a copy of cmnd */ + len = strlen (my_cmnd); + if (my_cmnd[len-1] == '\r') my_cmnd[len-1] = NIL; + + cmnd_tok = strtok (my_cmnd, " "); + motor_tok = strtok (NULL, " "); + par0_tok = strtok (NULL, " "); + par1_tok = strtok (NULL, " "); + if ((cmnd_tok == NULL) || (motor_tok == NULL) || + (par0_tok == NULL) || (par1_tok == NULL)) { + printf ("\007Software problem in LoadCheckTwoFloat\n"); + return False; + } + /*--------------------------------------------------- + ** Check that the number of decimal places in the first set + ** parameter agrees with the setting of the EL734. + */ + StrJoin (par0, sizeof (par0), par0_tok, ""); + whole_tok = strtok (par0, "."); + frac_tok = strtok (NULL, "."); + if (frac_tok == NULL) { /* Check for a decimal point */ + len = strlen (whole_tok); /* None there, so put in a ".0" */ + frac_tok = whole_tok + len + 1; + frac_tok[0] = '0'; + frac_tok[1] = NIL; + } + len = strlen (frac_tok); + if (len > n_dec) { /* Param has too many decimal places */ + /* Try to remove trailing zeros */ + while ((len >= 0) && (frac_tok[len-1] == '0')) { + len = len - 1; + frac_tok[len] = NIL; + if (len == n_dec) break; + } + if (len != n_dec) { + printf ("Don't expect the parameter to verify correctly.\n" + "You have specified too many decimal places!\n"); + } + }else if (len < n_dec) { /* Param has too few decimal places */ + while (len < n_dec) { /* Pad with zeros */ + frac_tok[len] = '0'; + len = len + 1; + frac_tok[len] = NIL; + } + } + len = strlen (whole_tok); /* Re-join the parts of param again */ + whole_tok[len] = '.'; + /*--------------------------------------------------- + ** Check that the number of decimal places in the second set + ** parameter agrees with the setting of the EL734. + */ + StrJoin (par1, sizeof (par1), par1_tok, ""); + whole_tok = strtok (par1, "."); + frac_tok = strtok (NULL, "."); + if (frac_tok == NULL) { /* Check for a decimal point */ + len = strlen (whole_tok); /* None there, so put in a ".0" */ + frac_tok = whole_tok + len + 1; + frac_tok[0] = '0'; + frac_tok[1] = NIL; + } + len = strlen (frac_tok); + if (len > n_dec) { /* Param has too many decimal places */ + /* Try to remove trailing zeros */ + while ((len >= 0) && (frac_tok[len-1] == '0')) { + len = len - 1; + frac_tok[len] = NIL; + if (len == n_dec) break; + } + if (len != n_dec) { + printf ("Don't expect the parameter to verify correctly.\n" + "You have specified too many decimal places!\n"); + } + }else if (len < n_dec) { /* Param has too few decimal places */ + while (len < n_dec) { /* Pad with zeros */ + frac_tok[len] = '0'; + len = len + 1; + frac_tok[len] = NIL; + } + } + len = strlen (whole_tok); /* Re-join the parts of param again */ + whole_tok[len] = '.'; + /* End of checking number of decimal places + **--------------------------------------------------- + */ + StrJoin (buff, sizeof (buff), cmnd_tok, " "); + StrJoin (rd_cmnd, sizeof (rd_cmnd), buff, motor_tok); + len = strlen (rd_cmnd); + rd_cmnd[len] = '\r'; + rd_cmnd[len+1] = NIL; + status = EL734_SendCmnd (&Hndl, rd_cmnd, buff, sizeof (buff)); + if (status) { + rd0_tok = strtok (buff, " "); + rd1_tok = strtok (NULL, " "); + if ((rd0_tok == NULL) || + (rd1_tok == NULL) || + (strcmp (par0, rd0_tok) != 0) || + (strcmp (par1, rd1_tok) != 0)) { + if (rd0_tok == NULL) rd0_tok = ""; + if (rd1_tok == NULL) rd1_tok = ""; + printf ("\007Verify error for command \"%s %s %s %s\"\n", + cmnd_tok, motor_tok, par0, par1); + printf ("Value set in EL734 controller is \"%s %s\"\n" + " It should be \"%s %s\"\n", + rd0_tok, rd1_tok, par0, par1); + return False; + }else { + return True; /* The parameter has been set correctly! */ + } + }else { + printf ("\007LoadCheckTwoFloat -- error from EL734_SendCmnd\n"); + printf ("Command being checked was \"%s %s %s %s\"\n", + cmnd_tok, motor_tok, par0, par1); + return False; + } + } +/* +**-------------------------------------------------------------------------- +** LoadFloatJuggle: routine to try to get around an EL734 problem. +** +** The problem is that the EL734 does not at the moment +** handle binary <--> float conversion correctly. +*/ + int LoadFloatJuggle ( +/* =============== +*/ char *cmnd, /* The command to be issued */ + char *motor, /* The motor index being loaded */ + char *param, /* The desired parameter */ + int n_dec) { /* The number of decimal places */ +/* +** It is assumed that all parameters are consistent (especially +** param and n_dec) since this is an internal routine and that +** they are not terminated with . +*/ + int status, i, incr0, incr1, incr2; + char set_cmnd[80], read_cmnd[40], my_par[40], buff[40]; + char *rd_tok; + + printf ("Trying to juggle the \"%s\" parameter of Motor %s" + " to be %s ..\n .. ", cmnd, motor, param); + + sprintf (read_cmnd, "%s %s\r", cmnd, motor); /* Prepare the param rd cmnd */ + /* + ** Find indices of last 3 chars to be incremented + */ + incr0 = strlen (param); + incr0--; /* incr0 now indexes the last digit of param */ + + if (!isdigit (param[incr0])) incr0--; /* Be careful not to increment .. */ + /* .. a decimal point! */ + incr1 = incr0 - 1; + if (!isdigit (param[incr1])) incr1--; /* Be careful not to increment .. */ + /* .. a decimal point! */ + incr2 = incr1 - 1; + if (!isdigit (param[incr2])) incr2--; /* Be careful not to increment .. */ + /* .. a decimal point! */ + if ((!isdigit (param[incr0])) || + (!isdigit (param[incr1])) || + (!isdigit (param[incr2]))) { + printf ("LoadFloatJuggle: software problem with decimal point\n" + " The routine probably needs to be enhanced!\n"); + return False; + } + /*---------------------------------------------------------------- + ** First try incrementing the last digit of the set value of the + ** parameter 5 times. + */ + StrJoin (my_par, sizeof (my_par), param, ""); /* Make a copy of param */ + + for (i = 0; i < 5; i++) { + if (my_par[incr0] != '9') { /* Check for carry to next digit */ + my_par[incr0]++; + }else { + my_par[incr0] = '0'; + if (my_par[incr1] != '9') { + my_par[incr1]++; + }else { + my_par[incr1] = '0'; + if (my_par[incr2] != '9') { + my_par[incr2]++; + }else { + my_par[incr2] = '0'; + } + } + } + + printf ("%s .. ", my_par); + sprintf (set_cmnd, "%s %s %s\r", cmnd, motor, my_par); + + status = EL734_SendCmnd (&Hndl, set_cmnd, buff, sizeof (buff)); + if (status) status = EL734_SendCmnd (&Hndl, read_cmnd, buff, sizeof (buff)); + if (!status) { + printf ("\nError with \"%s %s %s\"\n" + "Abandoning parameter juggle!\n", cmnd, motor, my_par); + return False; + } + rd_tok = strtok (buff, " "); /* Skip leading spaces */ + if (strcmp (param, rd_tok) == 0) { + printf ("\n Success. Parameter as sent was %s\n" + " Parameter as read is %s\n", my_par, param); + return True; + } + } + /*---------------------------------------------------------------- + ** Now try decrementing the last digit of the set value of the + ** parameter 5 times. + */ + StrJoin (my_par, sizeof (my_par), param, ""); /* Make a copy of param */ + + for (i = 0; i < 5; i++) { + if (my_par[incr0] != '0') { /* Check for carry to next digit */ + my_par[incr0]--; + }else { + my_par[incr0] = '9'; + if (my_par[incr1] != '0') { + my_par[incr1]--; + }else { + my_par[incr1] = '9'; + if (my_par[incr2] != '0') { + my_par[incr2]--; + }else { + my_par[incr2] = '9'; + } + } + } + + printf ("%s .. ", my_par); + sprintf (set_cmnd, "%s %s %s\r", cmnd, motor, my_par); + + status = EL734_SendCmnd (&Hndl, set_cmnd, buff, sizeof (buff)); + if (status) status = EL734_SendCmnd (&Hndl, read_cmnd, buff, sizeof (buff)); + if (!status) { + printf ("\nError with \"%s %s %s\"\n" + "Abandoning parameter juggle!\n", cmnd, motor, my_par); + return False; + } + rd_tok = strtok (buff, " "); /* Skip leading spaces */ + if (strcmp (param, rd_tok) == 0) { + printf ("\n Success. Parameter as sent was %s\n" + " Parameter as read is %s\n", my_par, param); + return True; + } + } + /* + ** Failed - go back to original setting + */ + sprintf (set_cmnd, "%s %s %s\r", cmnd, motor, param); + status = EL734_SendCmnd (&Hndl, set_cmnd, buff, sizeof (buff)); + if (status) status = EL734_SendCmnd (&Hndl, read_cmnd, buff, sizeof (buff)); + if (status) { + rd_tok = strtok (buff, " "); + printf ("\n Failed. Parameter value is set to %s\n", rd_tok); + }else { + printf ("\n Failed. Parameter value is unknown due to error\n"); + } + return False; + } +/* +**-------------------------------------------------------------------------- +** LoadIntJuggle: routine to try to get around an EL734 problem. +** +** The problem is that some integer parameters (e.g. E) +** do not set correctly. +*/ + int LoadIntJuggle ( +/* ============= +*/ char *cmnd, /* The command to be issued */ + char *motor, /* The motor index being loaded */ + char *param) { /* The desired parameter */ +/* +** It is assumed that the parameters are trimmed (especially +** param) and are not terminated with . +*/ + int status, i, my_par; + char set_cmnd[80], read_cmnd[40], buff[40]; + char *rd_tok; + + printf ("Trying to juggle the \"%s\" parameter of Motor %s" + " to be %s ..\n .. ", cmnd, motor, param); + + sprintf (read_cmnd, "%s %s\r", cmnd, motor); /* Prepare the param rd cmnd */ + + /*---------------------------------------------------------------- + ** First try incrementing the parameter 5 times. + */ + sscanf (param, "%d", &my_par); /* Gen binary value of param */ + + for (i = 0; i < 5; i++) { + my_par++; + + printf ("%d .. ", my_par); + sprintf (set_cmnd, "%s %s %d\r", cmnd, motor, my_par); + + status = EL734_SendCmnd (&Hndl, set_cmnd, buff, sizeof (buff)); + if (status) status = EL734_SendCmnd (&Hndl, read_cmnd, buff, sizeof (buff)); + if (!status) { + printf ("\nError with \"%s %s %d\"\n" + "Abandoning parameter juggle!\n", cmnd, motor, my_par); + return False; + } + rd_tok = strtok (buff, " "); /* Skip leading spaces */ + if (strcmp (param, rd_tok) == 0) { + printf ("\n Success. Parameter as sent was %d\n" + " Parameter as read is %s\n", my_par, param); + return True; + } + } + /*---------------------------------------------------------------- + ** Now try decrementing the last digit of the set value of the + ** parameter 5 times. + */ + sscanf (param, "%d", &my_par); /* Gen binary value of param */ + + for (i = 0; i < 5; i++) { + my_par--; + + printf ("%d .. ", my_par); + sprintf (set_cmnd, "%s %s %d\r", cmnd, motor, my_par); + + status = EL734_SendCmnd (&Hndl, set_cmnd, buff, sizeof (buff)); + if (status) status = EL734_SendCmnd (&Hndl, read_cmnd, buff, sizeof (buff)); + if (!status) { + printf ("\nError with \"%s %s %d\"\n" + "Abandoning parameter juggle!\n", cmnd, motor, my_par); + return False; + } + rd_tok = strtok (buff, " "); /* Skip leading spaces */ + if (strcmp (param, rd_tok) == 0) { + printf ("\n Success. Parameter as sent was %d\n" + " Parameter as read is %s\n", my_par, param); + return True; + } + } + /* + ** Failed - go back to original setting + */ + sprintf (set_cmnd, "%s %s %s\r", cmnd, motor, param); + status = EL734_SendCmnd (&Hndl, set_cmnd, buff, sizeof (buff)); + if (status) status = EL734_SendCmnd (&Hndl, read_cmnd, buff, sizeof (buff)); + if (status) { + rd_tok = strtok (buff, " "); + printf ("\n Failed. Parameter value is set to %s\n", rd_tok); + }else { + printf ("\n Failed. Parameter value is unknown due to error\n"); + } + return False; + } +/* +**-------------------------------------------------------------------------- +** LoadCheckOneInteger: routine to check that a command specifying +** a single integer set correctly. +*/ + int LoadCheckOneInteger (char *cmnd) { +/* =================== +*/ + int status, len; + char my_cmnd[80], rd_cmnd[40], buff[40]; + char *cmnd_tok, *motor_tok, *param_tok, *rd_tok; + + StrJoin (my_cmnd, sizeof (my_cmnd), cmnd, ""); /* Make a copy of cmnd */ + len = strlen (my_cmnd); + if (my_cmnd[len-1] == '\r') my_cmnd[len-1] = NIL; + + cmnd_tok = strtok (my_cmnd, " "); + motor_tok = strtok (NULL, " "); + param_tok = strtok (NULL, " "); + if ((cmnd_tok == NULL) || (motor_tok == NULL) || (param_tok == NULL)) { + printf ("\007Software problem in LoadCheckOneInteger\n"); + return False; + } + StrJoin (buff, sizeof (buff), cmnd_tok, " "); + StrJoin (rd_cmnd, sizeof (rd_cmnd), buff, motor_tok); + len = strlen (rd_cmnd); + rd_cmnd[len] = '\r'; + rd_cmnd[len+1] = NIL; + status = EL734_SendCmnd (&Hndl, rd_cmnd, buff, sizeof (buff)); + if (status) { + rd_tok = strtok (buff, " "); + if ((rd_tok == NULL) || + (strcmp (param_tok, rd_tok) != 0)) { + if (rd_tok == NULL) rd_tok = ""; + printf ("\007Verify error for command \"%s %s %s\"\n", + cmnd_tok, motor_tok, param_tok); + printf ("Value set in EL734 controller is \"%s\"\n" + " It should be \"%s\"\n", + rd_tok, param_tok); + status = LoadIntJuggle (cmnd_tok, motor_tok, param_tok); + return status; + }else { + return True; /* The parameter has been set correctly! */ + } + }else { + printf ("\007LoadCheckOneInteger -- error from EL734_SendCmnd\n"); + printf ("Command being checked was \"%s %s %s\"\n", + cmnd_tok, motor_tok, param_tok); + return False; + } + } +/* +**-------------------------------------------------------------------------- +** LoadCheckOneFloat: routine to check that a command specifying +** a single real value set correctly. +*/ + int LoadCheckOneFloat (char *cmnd, int n_dec) { +/* ================= +*/ + int status, len, n_dec_ok; + char my_cmnd[80], rd_cmnd[40], buff[40], param[40]; + char *cmnd_tok, *motor_tok, *param_tok, *rd_tok; + char *whole_tok, *frac_tok; + + StrJoin (my_cmnd, sizeof (my_cmnd), cmnd, ""); /* Make a copy of cmnd */ + len = strlen (my_cmnd); + if (my_cmnd[len-1] == '\r') my_cmnd[len-1] = NIL; + + cmnd_tok = strtok (my_cmnd, " "); + motor_tok = strtok (NULL, " "); + param_tok = strtok (NULL, " "); + if ((cmnd_tok == NULL) || (motor_tok == NULL) || (param_tok == NULL)) { + printf ("\007Software problem in LoadCheckOneFloat\n"); + return False; + } + /* + ** Check that the number of decimal places in the set parameter + ** agrees with the setting of the EL734. + */ + n_dec_ok = True; /* Assume it will be OK */ + StrJoin (param, sizeof (param), param_tok, ""); + whole_tok = strtok (param, "."); + frac_tok = strtok (NULL, "."); + if (frac_tok == NULL) { /* Check for a decimal point */ + len = strlen (whole_tok); /* None there, so put in a ".0" */ + frac_tok = whole_tok + len + 1; + frac_tok[0] = '0'; + frac_tok[1] = NIL; + } + len = strlen (frac_tok); + if (len > n_dec) { /* Param has too many decimal places */ + /* Try to remove trailing zeros */ + while ((len >= 0) && (frac_tok[len-1] == '0')) { + len = len - 1; + frac_tok[len] = NIL; + if (len == n_dec) break; + } + if (len != n_dec) { + printf ("Don't expect the parameter to verify correctly.\n" + "You have specified too many decimal places!\n"); + n_dec_ok = False; /* Remember it (to suppress retries) */ + } + }else if (len < n_dec) { /* Param has too few decimal places */ + while (len < n_dec) { /* Pad with zeros */ + frac_tok[len] = '0'; + len = len + 1; + frac_tok[len] = NIL; + } + } + len = strlen (whole_tok); /* Re-join the parts of param again */ + whole_tok[len] = '.'; + + StrJoin (buff, sizeof (buff), cmnd_tok, " "); + StrJoin (rd_cmnd, sizeof (rd_cmnd), buff, motor_tok); + len = strlen (rd_cmnd); + rd_cmnd[len] = '\r'; + rd_cmnd[len+1] = NIL; + status = EL734_SendCmnd (&Hndl, rd_cmnd, buff, sizeof (buff)); + if (status) { + rd_tok = strtok (buff, " "); + if ((rd_tok == NULL) || + (strcmp (param, rd_tok) != 0)) { + if (rd_tok == NULL) rd_tok = ""; + printf ("\007Verify error for command \"%s %s %s\"\n", + cmnd_tok, motor_tok, param); + printf ("Value set in EL734 controller is \"%s\"\n" + " It should be \"%s\"\n", + rd_tok, param); + if (n_dec_ok) { + status = LoadFloatJuggle (cmnd_tok, motor_tok, param, n_dec); + } + return status; + }else { + return True; /* The parameter has been set correctly! */ + } + }else { + printf ("\007LoadCheckOneFloat -- error from EL734_SendCmnd\n"); + printf ("Command being checked was \"%s %s %s\"\n", + cmnd_tok, motor_tok, param); + return False; + } + } +/* +**-------------------------------------------------------------------------- +** DoStop: Send a STOP command to the motor. If has +** been detected, assume that this is an emergency +** stop and do fewer tests. +*/ + int DoStop () { +/* ====== +*/ + int status, no_errors, i, len, act_len; + int msr, ored_msr, fp_cntr, fr_cntr, ss; + char recd[132], buff[132], cmnd[80]; + float f_tmp; + + no_errors = True; + + if (!Ctrl_C_has_happened) { + EL734_ZeroStatus (&Hndl); + printf ("Sending STOP command to motor %d ...", Motor); + }else { + printf ("\n\007 detected: Sending STOP command to motor %d ...", + Motor); + } + + status = EL734_Stop (&Hndl); + if (!status) no_errors = False; + + if (no_errors) { + if (Ctrl_C_has_happened) { + printf (" OK.\n"); + return True; + }else { + printf ("\nWaiting for motor to become idle ... "); + status = My_WaitIdle (&Hndl, Verbose, + &ored_msr, &fp_cntr, &fr_cntr, &Ist_pos); + if (!status) { + if (Ctrl_C_has_happened) { + printf ("\n\007 detected: Wait-for-idle abandoned!\n"); + }else { + printf ("\n\007 Error return status from My_WaitIdle!\n"); + } + return False; + } + if ((ored_msr & MSR__STOPPED) == 0) { + printf ("\n\007 Warning -- MSR STOP bit is not set!\n"); + return False; + } + if ((ored_msr & (~MSR__STOPPED)) != 0) { + printf ("\n\007 ... unexpected MSR obtained!\n"); + printf (" %s\n", EL734_EncodeMSR (buff, sizeof (buff), + 0, ored_msr, fp_cntr, fr_cntr)); + return False; + } + printf (" OK.\n"); + } + return True; + }else { + printf ("\n\007 STOP command not accepted!\n"); + return False; + } + } +/* +**-------------------------------------------------------------------------- +** DoLimits: Set the lower and upper software limits +*/ + int DoLimits ( +/* ======== +*/ float lo, + float hi) { + + int status, no_errors, i, len, act_len; + int msr, ored_msr, fp_cntr, fr_cntr, ss; + char recd[132], buff[132], cmnd[80]; + float f_tmp; + + no_errors = False; + + printf ("Sending command \"h %d %.*f %.*f\" ...", + Motor, Dec_pt, lo, Dec_pt, hi); + + sprintf (cmnd, "h %d %.*f %.*f\r", Motor, Dec_pt, lo, Dec_pt, hi); + status = EL734_SendCmnd (&Hndl, cmnd, buff, sizeof (buff)); + if (status && (buff[0] == NIL)) no_errors = True; + + if (no_errors) { + printf (" OK.\n"); + return True; + }else { + printf ("\n\007 Command not accepted!\n"); + return False; + } + } +/* +**-------------------------------------------------------------------------- +** DoSimpleMove: Send a simple move command to the motor and wait for idle +*/ + int DoSimpleMove ( +/* ============ +*/ char *a_cmnd, + int test_status) { + + int status, i, len, act_len; + int msr, ored_msr, fp_cntr, fr_cntr, ss; + char recd[132], buff[132], cmnd[80]; + float f_tmp; + char *etxt; + + EL734_ZeroStatus (&Hndl); + + sprintf (cmnd, a_cmnd, Motor); + printf ("Sending \"%s\" command ...", cmnd); + + i = strlen (cmnd); + cmnd[i] = '\r'; + cmnd[i+1] = NIL; + status = EL734_SendCmnd (&Hndl, cmnd, buff, sizeof (buff)); + if (!status) { + PrintErrInfo ("EL734_SendCmnd"); + return False; + } + + if (buff[0] != NIL) { + printf ("\007 response was \"%s\".\n", buff); + etxt = "Unrecognised response!"; + if (strcmp (buff, "?BSY") == 0) etxt = "Motor busy!"; + if (strcmp (buff, "?CMD") == 0) etxt = "Bad command!"; + if (strcmp (buff, "?LOC") == 0) etxt = "Controller is in manual mode!"; + if (strcmp (buff, "?ADR") == 0) etxt = "Bad motor number!"; + if (strcmp (buff, "?RNG") == 0) etxt = "Range error! Check low/high limits."; + if (strcmp (buff, "*MS") == 0) + etxt = "Motor is disabled: \"Stop\" signal is active!"; + if (strcmp (buff, "*ES") == 0) + etxt = "Motor is disabled: \"Emergency Stop\" signal is active!"; + if (strncmp (buff, "?TMO", 4) == 0) + etxt = "Time-out! You should check the cables, perhaps."; + printf ("%s\n", etxt); + return False; + } + + printf ("\nWaiting for motor to become idle ..."); fflush (NULL); + status = My_WaitIdle (&Hndl, Verbose, + &ored_msr, &fp_cntr, &fr_cntr, &Ist_pos); + if (!status) { + if (Ctrl_C_has_happened) DoStop (); + return False; + } + if (test_status && ((ored_msr & (~MSR__BUSY)) != MSR__OK)) { + printf ("\n\007 ... unexpected MSR obtained!\n"); + printf (" %s\n", EL734_EncodeMSR (buff, sizeof (buff), + 0, ored_msr, fp_cntr, fr_cntr)); + return False; + } + printf (" OK.\nPosition = %.*f\n", Dec_pt, Ist_pos); + return True; + } +/* +**-------------------------------------------------------------------------- +** DoSimpleSet: Send a parameter set command to the motor and +** check for null response. +*/ + int DoSimpleSet ( +/* =========== +*/ char *a_cmnd) { + + int status, i; + char cmnd[80], buff[40]; + + sprintf (cmnd, a_cmnd, Motor); + printf ("Sending \"%s\" command ...", cmnd); + i = strlen (cmnd); + cmnd[i] = '\r'; + cmnd[i+1] = NIL; + + status = EL734_SendCmnd (&Hndl, cmnd, buff, sizeof (buff)); + if (status && (buff[0] == NIL)) { + printf (" OK.\n"); + return True; + }else if (!status) { + printf ("\n\007"); + PrintErrInfo ("EL734_SendCmnd"); + return False; + }else { + printf ("\n\007Error response from the motor: \"%s\"!\n", buff); + return False; + } + } +/* +**-------------------------------------------------------------------------- +** DoSetPos: Set the current position +*/ + int DoSetPos (float ist) { +/* ======== +*/ + + int status; + char cmnd[80]; + + sprintf (cmnd, "UU %%d %.*f", Dec_pt, ist); + status = DoSimpleSet (cmnd); + if (status) printf ("Position set to %.*f\n", Dec_pt, ist); + return status; + } +/* +**-------------------------------------------------------------------------- +** DoRef: Perform a Reference Seek +*/ + int DoRef ( +/* ===== +*/ float *shift) { + + int status, no_restore, i, len, act_len; + int msr, ored_msr, fp_cntr, fr_cntr, ss; + char recd[132], buff[132], cmnd[80]; + int k, v; + float lo, hi, q, zero_pt, targ; + float f_tmp; +/*----------------------------------------------------------------- +** Absolute encoder? +*/ + status = GetKHVQZ (&k, &lo, &hi, &v, &q, &zero_pt); + if (!status) return status; + + if (k == 0) { + printf ("\n\007Absolute encoder, K = 0, " + "\"-ref\" option is not meaningful!\n"); + return False; + }else { + printf ("Performing reference point seek.\n"); + sprintf (recd, "%.*f", Dec_pt, zero_pt); + if (k == -1 || k == -11) { + printf ("Reference point = %s (lower limit switch) ...", recd); + }else if (k == 1 || k == 11) { + printf ("Reference point = %s (upper limit switch) ...", recd); + }else if (k == 2 || k == 12) { + printf ("Reference point = %s (separate switch) ...", recd); + }else { + printf ("Reference point = %s (reference mode = %d (unrecognised)) ...", + recd, k); + } + } +/*---------------------------------------------------------------*/ + *shift = 0.0; + + status = EL734_GetStatus (&Hndl, + &msr, &ored_msr, &fp_cntr, &fr_cntr, &ss, &Ist_pos); + if ((!status) || (msr == -1)) { + printf ("\n\007"); + printf ("Bad status from EL734_GetStatus.\n" + " ... failed to do reference seek.\n"); + return False; + } + EL734_ZeroStatus (&Hndl); + + sprintf (cmnd, "rf %d\r", Motor); /* Start reference seek */ + status = EL734_SendCmnd (&Hndl, cmnd, buff, sizeof (buff)); + if (!status) { + printf ("\n\007" + " ... failed to initiate reference seek.\n"); + PrintErrInfo ("EL734_SendCmnd"); + return False; + }else { + if (buff[0] != NIL) { + printf ("\n\007" + " ... error response when initiating reference seek:" + " \"%s\".\n" + " Operation abandoned.\n", buff); + return False; + } + } + status = My_WaitIdle (&Hndl, Verbose, + &ored_msr, &fp_cntr, &fr_cntr, &Ist_pos); + if (!status) { + if (Ctrl_C_has_happened) { + DoStop (); + }else { + PrintErrInfo ("My_WaitIdle"); + } + return False; + } + if ((ored_msr & MSR__REF_OK) != 0) { + printf (" OK.\n"); + }else { + if ((ored_msr & MSR__REF_FAIL) != 0) { + printf ("\007 failed!\n"); + }else { + printf ("\007 unexpected MSR obtained!\n"); + } + printf (" %s\n", EL734_EncodeMSR (recd, sizeof (recd), + 0, ored_msr, fp_cntr, fr_cntr)); + return False; + } + + *shift = Ist_pos - zero_pt; + sprintf (recd, "%.*f", Dec_pt, *shift); + printf ("Position = %.*f, Zero-point error = %s\n", Dec_pt, Ist_pos, recd); + sscanf (recd, "%f", &f_tmp); + if (f_tmp != 0.0) { + sprintf (recd, "%.*f", Dec_pt, zero_pt); + printf ("\007Setting current position to be %s\n", recd); + status = DoSetPos (zero_pt); + if (!status) return False; + } + if ((zero_pt < lo) || (zero_pt > hi)) { /* Move into range? */ + if (zero_pt < lo) targ = lo; /* Yes */ + if (zero_pt > lo) targ = hi; + printf ("Moving into low-high range ...\n"); + sprintf (cmnd, "P %%d %.*f", Dec_pt, targ); + status = DoSimpleMove (cmnd, True); + } + return True; + } +/* +**-------------------------------------------------------------------------- +** DoFF: Send a FF command to the motor +*/ + int DoFF () { +/* ==== +*/ + int status; + char cmnd[32]; + + if (Frequency > 0) { + sprintf (cmnd, "FF %%d %d", Frequency); + }else { + strcpy (cmnd, "FF %d"); + } + status = DoSimpleMove (cmnd, True); + return status; + } +/* +**-------------------------------------------------------------------------- +** DoFB: Send a FB command to the motor +*/ + int DoFB () { +/* ==== +*/ + int status; + char cmnd[32]; + + if (Frequency > 0) { + sprintf (cmnd, "FB %%d %d", Frequency); + }else { + strcpy (cmnd, "FB %d"); + } + status = DoSimpleMove (cmnd, True); + return status; + } +/* +**-------------------------------------------------------------------------- +** DoSF: Send a SF command to the motor +*/ + int DoSF () { +/* ==== +*/ + int status; + char cmnd[32]; + + if (Frequency > 0) { + sprintf (cmnd, "SF %%d %d", Frequency); + }else { + strcpy (cmnd, "SF %d"); + } + status = DoSimpleMove (cmnd, True); + return status; + } +/* +**-------------------------------------------------------------------------- +** DoSB: Send a SB command to the motor +*/ + int DoSB () { +/* ==== +*/ + int status; + char cmnd[32]; + + if (Frequency > 0) { + sprintf (cmnd, "SB %%d %d", Frequency); + }else { + strcpy (cmnd, "SB %d"); + } + status = DoSimpleMove (cmnd, True); + return status; + } +/* +**-------------------------------------------------------------------------- +** DoHunt: hunt for the motor's reference point. +*/ + int DoHunt (int ist_posit) { +/* ====== +*/ + int status; + int k; + float lo, hi, q, shift, zero; + int v; + int msr, ored_msr, fp_cntr, fr_cntr, ss; + float step, targ, start_posit, f_tmp; + char cmnd[20]; + + status = GetKHVQZ (&k, &lo, &hi, &v, &q, &zero); + if (!status) return status; +/*----------------------------------------------------------------- +** Absolute encoder */ + if (k == 0) { + printf ("\n\007Absolute encoder, K = 0, " + "-hunt option is not meaningful!\n"); + return False; +/*----------------------------------------------------------------- +** Lo-Lim is Ref Pt */ + }else if ((k == -1) || (k == -11)) { + printf ("Reference point = %.*f (low limit switch)\n", Dec_pt, zero); + if (q <= 0) { + printf ("\n\007Q = %.*f. This is inconsistent with K = %d!\n", + Dec_pt, q, k); + return False; + } + printf ("Setting wide soft limits so that we can hit the " + "low-limit switch ...\n"); + status = DoSimpleSet ("H %d -8000 8000"); + if (!status) return status; + + if ((ist_posit < -2000.0) || (ist_posit > 2000.0)) { + printf ("Forcing the current position to zero ...\n"); + status = DoSetPos (0.0); + if (!status) { + DoLimits (lo, hi); /* On error, reset the limits */ + return status; + } + } + + status = DoSimpleMove ("FB %d", False); /* Do FB but don't test MSR at end */ + if (!status) return status; + + DoLimits (lo, hi); /* Reset lo/hi limits */ + + status = EL734_GetStatus (&Hndl, + &msr, &ored_msr, &fp_cntr, &fr_cntr, &ss, &Ist_pos); + if (msr == -1) { + printf ("\n\007Bad status from EL734_GetStatus!"); + return False; + } + + if ((ored_msr & MSR__LO_LIM) == 0) { + printf ("\n\007Low-limit switch was not reached!"); + return False; + } + + status = DoSetPos (zero); + if (!status) return status; + + if ((ss & SS__LSX) != 0) { + printf ("\n\007Reference-point is still active!"); + return False; + } + + status = DoRef (&shift); + return status; +/*----------------------------------------------------------------- +** Hi-Lim is Ref Pt */ + }else if ((k == 1) || (k == 11)) { + printf ("Reference point = %.*f (high limit switch)\n", Dec_pt, zero); + if (q <= 0) { + printf ("\n\007Q = %.*f. This is inconsistent with K = %d!\n", + Dec_pt, q, k); + return False; + } + status = DoSimpleSet ("H %d -8000 8000"); + if (!status) return status; + + status = DoSetPos (0.0); + if (!status) return status; + + status = DoSimpleMove ("FF %d", False); /* Do FF but don't test MSR at end */ + if (!status) return status; + + DoLimits (lo, hi); /* Reset lo/hi limits */ + + status = EL734_GetStatus (&Hndl, + &msr, &ored_msr, &fp_cntr, &fr_cntr, &ss, &Ist_pos); + if (msr == -1) { + printf ("\n\007Bad status from EL734_GetStatus!"); + return False; + } + + if ((ored_msr & MSR__HI_LIM) == 0) { + printf ("\n\007High-limit switch was not reached!"); + return False; + } + + status = DoSetPos (zero); + if (!status) return status; + + if ((ss & SS__LSX) != 0) { + printf ("\n\007Reference-point is still active!"); + return False; + } + + status = DoRef (&shift); + return status; +/*----------------------------------------------------------------- +** Separate Ref Pt */ + }else if ((k == 2) || (k == 12)) { + printf ("Reference point = %.*f (separate switch)\n", Dec_pt, zero); + printf ("Ref-point width (Q parameter) = %.*f\n", Dec_pt, q); + if (q == 0.0) { + printf ("\n\007Q = %.*f. This is inconsistent with K = %d!\n", + Dec_pt, q, k); + return False; + }else { + sprintf (cmnd, "%.*f", Dec_pt, q); /* Check Q param is not too small */ + sscanf (cmnd, "%f", &f_tmp); + if (f_tmp == 0.0) { + printf ("\n\007Q = %f. This is too small!\n", q); + return False; + } + } + printf ("Setting wide soft limits so that they do not interfere ...\n"); + status = DoSimpleSet ("H %d -8000 8000"); + if (!status) return status; + /* + ** If the current position is more or less a reasonable + ** work without forcing the position to zero. Otherwise, + ** force the position to zero to ensure the algorithms + ** have a good chance of working. + */ + if ((ist_posit < -2000.0) || (ist_posit > 2000.0)) { + printf ("Forcing the current position to zero ...\n"); + status = DoSetPos (0.0); + if (!status) {DoLimits (lo, hi); return status;} + targ = 0.0; + }else { + targ = zero - (q/2.0); + sprintf (cmnd, "P %%d %.*f", Dec_pt, targ); + printf ("Moving to start position = Ref-pt - (q/2.0) = %.*f ...\n", + Dec_pt, targ); + status = DoSimpleMove (cmnd, False); + if (!status) {DoLimits (lo, hi); return status;} + status = EL734_GetStatus (&Hndl, + &msr, &ored_msr, &fp_cntr, &fr_cntr, &ss, &Ist_pos); + if (status && + (((ored_msr & MSR__LO_LIM) != 0) || + ((ored_msr & MSR__HI_LIM) != 0))) { + if ((ored_msr & MSR__LO_LIM) != 0) { + printf ("Hit lo-limit switch!\n"); + }else { + printf ("Hit hi-limit switch!\n"); + } + targ = Ist_pos; + } + EL734_ZeroStatus (&Hndl); + } + + start_posit = targ; + step = 0.95 * q; + printf ("Low-to-High distance = %.*f\n", Dec_pt, (hi - lo)); + printf ("Approximate number of steps = %d\n", (int) ((hi - lo)/step)); + printf ("Step size = %.*f\n", Dec_pt, step); + if (step > 0) { + printf ("Stepping to low-limit switch looking for ref-point ...\n"); + }else { + printf ("Stepping to high-limit switch looking for ref-point ...\n"); + } + fflush (NULL); + status = EL734_GetStatus (&Hndl, + &msr, &ored_msr, &fp_cntr, &fr_cntr, &ss, &Ist_pos); + while (status && + ((ored_msr & MSR__LO_LIM) == 0) && + ((ored_msr & MSR__HI_LIM) == 0) && + ((ss & SS__LSX) == 0)) { + targ = targ - step; + sprintf (cmnd, "P %%d %.*f", Dec_pt, targ); + status = DoSimpleMove (cmnd, False); + if (!status) { + if (Ctrl_C_has_happened) { + DoStop (); + }else { + PrintErrInfo ("DoSimpleMove"); + } + DoLimits (lo, hi); + return False; + } + status = EL734_GetStatus (&Hndl, + &msr, &ored_msr, &fp_cntr, &fr_cntr, &ss, &Ist_pos); + } + if (!status) { + DoLimits (lo, hi); + return False; + } + if ((ored_msr & (MSR__LO_LIM | MSR__HI_LIM)) != 0) { + printf ("Got to limit switch. Ref-point not found. " + "Returning to Start.\n"); fflush (NULL); + sprintf (cmnd, "P %%d %.*f", Dec_pt, start_posit); + status = DoSimpleMove (cmnd, False); + if (!status) { + if (Ctrl_C_has_happened) { + DoStop (); + }else { + PrintErrInfo ("DoSimpleMove"); + } + DoLimits (lo, hi); + return False; + } + targ = start_posit; + if (step > 0) { + printf ("Stepping to high-limit switch looking for ref-point ...\n"); + }else { + printf ("Stepping to low-limit switch looking for ref-point ...\n"); + } + status = EL734_GetStatus (&Hndl, + &msr, &ored_msr, &fp_cntr, &fr_cntr, &ss, &Ist_pos); + while (status && + ((ored_msr & MSR__LO_LIM) == 0) && + ((ored_msr & MSR__HI_LIM) == 0) && + ((ss & SS__LSX) == 0)) { + targ = targ + step; + sprintf (cmnd, "P %%d %.*f", Dec_pt, targ); + status = DoSimpleMove (cmnd, False); + if (!status) { + if (Ctrl_C_has_happened) { + DoStop (); + }else { + PrintErrInfo ("DoSimpleMove"); + } + DoLimits (lo, hi); + return False; + } + status = EL734_GetStatus (&Hndl, + &msr, &ored_msr, &fp_cntr, &fr_cntr, &ss, &Ist_pos); + } + if (!status) return False; + if ((ored_msr & (MSR__LO_LIM | MSR__HI_LIM)) != 0) { + printf ("\n\007Got to limit switch. Ref-point not found!\n"); + printf ("Hunt operation abandoned.\n"); + DoLimits (lo, hi); + if (step > 0) DoSetPos (hi); else DoSetPos (lo); + return False; + } + } + DoLimits (lo, hi); /* Reset lo/hi limits */ + if ((ss & SS__LSX) == 0) { + printf ("\n\007Ref-point not found!\n"); + DoLimits (lo, hi); + return False; + }else { + printf ("\n" + " +-------------------------------+\n" + " | Ref-point found at %10.3f |\n" + " +-------------------------------+\n\n", targ); + } + status = DoRef (&shift); + return status; + }else { + printf ("\n\007Reference Mode, K = %d. Unrecognised value!\n", k); + return False; + } + } +/* +**-------------------------------------------------------------------------- +** DoSave: Get all parameter settings of motor. +*/ + int DoSave () { +/* ====== +*/ + int status, no_errors; + char buff[80]; + int msr, ored_msr, fp_cntr, fr_cntr, ss; + int air_cush, inp_state, act_mot; + FILE *lun; + time_t time_now; + struct EL734info *info_ptr; + + char cmnd00[10], cmnd01[10], cmnd02[10], cmnd03[10], cmnd04[10]; + char cmnd05[10], cmnd06[10], cmnd07[10], cmnd08[10], cmnd09[10]; + char cmnd10[10], cmnd11[10], cmnd12[10], cmnd13[10], cmnd14[10]; + char cmnd15[10], cmnd16[10], cmnd17[10], cmnd18[10], cmnd19[10]; + char cmnd20[10], cmnd21[10], cmnd22[10], cmnd23[10], cmnd24[10]; + char cmnd25[10], cmnd26[10], cmnd27[10], cmnd28[10], cmnd29[10]; + char cmnd30[10], cmnd31[10]; + + char *rptr00, *rptr01, *rptr02, *rptr03, *rptr04; + char *rptr05, *rptr06, *rptr07, *rptr08, *rptr09; + char *rptr10, *rptr11, *rptr12, *rptr13, *rptr14; + char *rptr15, *rptr16, *rptr17, *rptr18, *rptr19; + char *rptr20, *rptr21, *rptr22, *rptr23, *rptr24; + char *rptr25, *rptr26, *rptr27, *rptr28, *rptr29; + char *rptr30, *rptr31; + + int no_EC_cmnd = True; + int no_A_cmnd = True; + int no_FD_cmnd = True; + int no_FM_cmnd = True; + int no_D_cmnd = True; + int no_E_cmnd = True; + int no_F_cmnd = True; + int no_G_cmnd = True; + int no_H_cmnd = True; + int no_J_cmnd = True; + int no_K_cmnd = True; + int no_L_cmnd = True; + int no_M_cmnd = True; + int no_Q_cmnd = True; + int no_T_cmnd = True; + int no_V_cmnd = True; + int no_W_cmnd = True; + int no_Z_cmnd = True; + int no_SP_cmnd = True; + int no_ST_cmnd = True; + int no_SR_cmnd = True; + int no_SA_cmnd = True; + int no_AC_cmnd = True; + int no_RI_cmnd = True; + int no_AM_cmnd = True; + int no_EP_cmnd = True; + int no_KP_cmnd = True; + int no_KI_cmnd = True; + int no_KD_cmnd = True; + + if ((strcmp (Save_file, "-") == 0) || + (strcmp (Save_file, "=") == 0)) { /* Use standard output? */ + lun = stdout; /* Yes */ + }else { + lun = fopen (Save_file, "w"); + if (lun == NULL) return False; + printf ("Writing motor parameters to file %s ...", Save_file); + fflush (NULL); + } + time_now = time (NULL); + fprintf (lun, "! EL734 Status at %s", asctime (localtime (&time_now))); + fprintf (lun, "! ============\n"); + + sprintf (cmnd00, "id\r"); + sprintf (cmnd01, "mn %d\r", Motor); + sprintf (cmnd02, "mem %d\r", Motor); + sprintf (cmnd03, "ec %d\r", Motor); + sprintf (cmnd04, "a %d\r", Motor); + sprintf (cmnd05, "fd %d\r", Motor); + sprintf (cmnd06, "fm %d\r", Motor); + sprintf (cmnd07, "d %d\r", Motor); + sprintf (cmnd08, "e %d\r", Motor); + sprintf (cmnd09, "f %d\r", Motor); + sprintf (cmnd10, "g %d\r", Motor); + sprintf (cmnd11, "h %d\r", Motor); + sprintf (cmnd12, "j %d\r", Motor); + sprintf (cmnd13, "k %d\r", Motor); + sprintf (cmnd14, "l %d\r", Motor); + sprintf (cmnd15, "m %d\r", Motor); + sprintf (cmnd16, "q %d\r", Motor); + sprintf (cmnd17, "t %d\r", Motor); + sprintf (cmnd18, "v %d\r", Motor); + sprintf (cmnd19, "w %d\r", Motor); + sprintf (cmnd20, "z %d\r", Motor); + sprintf (cmnd21, "sp %d\r", Motor); + sprintf (cmnd22, "st %d\r", Motor); + sprintf (cmnd23, "sr %d\r", Motor); + sprintf (cmnd24, "sa %d\r", Motor); + sprintf (cmnd25, "ac %d\r", Motor); + sprintf (cmnd26, "ri %d\r", Motor); + sprintf (cmnd27, "am\r"); + sprintf (cmnd28, "ep %d\r", Motor); + sprintf (cmnd29, "kp %d\r", Motor); + sprintf (cmnd30, "ki %d\r", Motor); + sprintf (cmnd31, "kd %d\r", Motor); + + no_errors = True; + + info_ptr = (struct EL734info *) Hndl; + status = AsynSrv_SendCmnds (&info_ptr->asyn_info, + &info_ptr->to_host, &info_ptr->from_host, + cmnd00, cmnd01, cmnd02, cmnd03, cmnd04, cmnd05, cmnd06, + cmnd07, cmnd08, cmnd09, cmnd10, cmnd11, cmnd12, cmnd13, + cmnd14, cmnd15, cmnd16, cmnd17, cmnd18, cmnd19, cmnd20, + cmnd21, cmnd22, cmnd23, cmnd24, cmnd25, cmnd26, cmnd27, + cmnd28, cmnd29, cmnd30, cmnd31, NULL); + if (status) { + rptr00 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, NULL); + rptr01 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr00); + rptr02 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr01); + rptr03 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr02); + rptr04 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr03); + rptr05 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr04); + rptr06 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr05); + rptr07 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr06); + rptr08 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr07); + rptr09 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr08); + rptr10 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr09); + rptr11 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr10); + rptr12 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr11); + rptr13 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr12); + rptr14 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr13); + rptr15 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr14); + rptr16 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr15); + rptr17 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr16); + rptr18 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr17); + rptr19 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr18); + rptr20 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr19); + rptr21 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr20); + rptr22 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr21); + rptr23 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr22); + rptr24 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr23); + rptr25 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr24); + rptr26 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr25); + rptr27 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr26); + rptr28 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr27); + rptr29 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr28); + rptr30 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr29); + rptr31 = AsynSrv_GetReply (&info_ptr->asyn_info, + &info_ptr->from_host, rptr30); + if ((rptr00 == NULL) || (rptr01 == NULL) || (rptr02 == NULL) || + (rptr03 == NULL) || (rptr04 == NULL) || (rptr05 == NULL) || + (rptr06 == NULL) || (rptr07 == NULL) || (rptr08 == NULL) || + (rptr09 == NULL) || (rptr10 == NULL) || (rptr11 == NULL) || + (rptr12 == NULL) || (rptr13 == NULL) || (rptr14 == NULL) || + (rptr15 == NULL) || (rptr16 == NULL) || (rptr17 == NULL) || + (rptr18 == NULL) || (rptr19 == NULL) || (rptr20 == NULL) || + (rptr21 == NULL) || (rptr22 == NULL) || (rptr23 == NULL) || + (rptr24 == NULL) || (rptr25 == NULL) || (rptr26 == NULL) || + (rptr27 == NULL) || (rptr28 == NULL) || (rptr29 == NULL) || + (rptr30 == NULL) || (rptr31 == NULL)) { + no_errors = False; + }else { + StrJoin (Ctrl_id, sizeof (Ctrl_id), rptr00, ""); + StrJoin (Mot_name, sizeof (Mot_name), rptr01, ""); + StrJoin (Mot_mem, sizeof (Mot_mem), rptr02, ""); + if (sscanf (rptr03, "%d %d", &Enc_typ, &Enc_num) == 2) + no_EC_cmnd = False; + if (sscanf (rptr04, "%d", &Dec_pt) == 1) no_A_cmnd = False; + if (sscanf (rptr05, "%d %d", &Enc_fact_0, &Enc_fact_1) == 2) + no_FD_cmnd = False; + if (sscanf (rptr06, "%d %d", &Mot_fact_0, &Mot_fact_1) == 2) + no_FM_cmnd = False; + if (sscanf (rptr07, "%f", &Inertia_tol) == 1) no_D_cmnd = False; + if (sscanf (rptr08, "%d", &Ramp) == 1) no_E_cmnd = False; + if (sscanf (rptr09, "%d", &Loop_mode) == 1) no_F_cmnd = False; + if (sscanf (rptr10, "%d", &Slow_hz) == 1) no_G_cmnd = False; + if (sscanf (rptr11, "%f %f", &Lo, &Hi) == 2) no_H_cmnd = False; + if (sscanf (rptr12, "%d", &Fast_hz) == 1) no_J_cmnd = False; + if (sscanf (rptr13, "%d", &Ref_mode) == 1) no_K_cmnd = False; + if (sscanf (rptr14, "%d", &Backlash) == 1) no_L_cmnd = False; + if (sscanf (rptr15, "%d", &Pos_tol) == 1) no_M_cmnd = False; + if (sscanf (rptr16, "%f", &Ref_param) == 1) no_Q_cmnd = False; + if (sscanf (rptr17, "%d", &Is_sided) == 1) no_T_cmnd = False; + if (sscanf (rptr18, "%d", &Null_pt) == 1) no_V_cmnd = False; + if (sscanf (rptr19, "%d", &Ac_par) == 1) no_W_cmnd = False; + if (sscanf (rptr20, "%d", &Enc_circ) == 1) no_Z_cmnd = False; + if (sscanf (rptr21, "%d", &Stat_pos) == 1) no_SP_cmnd = False; + if (sscanf (rptr22, "%d", &Stat_pos_flt) == 1) no_ST_cmnd = False; + if (sscanf (rptr23, "%d", &Stat_pos_fail) == 1) + no_SR_cmnd = False; + if (sscanf (rptr24, "%d", &Stat_cush_fail) == 1) + no_SA_cmnd = False; + if (sscanf (rptr25, "%d", &air_cush) == 1) no_AC_cmnd = False; + if (sscanf (rptr26, "%d", &inp_state) == 1) no_RI_cmnd = False; + if (sscanf (rptr27, "%x", &act_mot) == 1) no_AM_cmnd = False; + if (sscanf (rptr28, "%d", &Enc_par) == 1) no_EP_cmnd = False; + if (sscanf (rptr29, "%d", &Prop) == 1) no_KP_cmnd = False; + if (sscanf (rptr30, "%d", &Integ) == 1) no_KI_cmnd = False; + if (sscanf (rptr31, "%d", &Deriv) == 1) no_KD_cmnd = False; + } + }else { + no_errors = False; + } + if (no_errors) { + EL734_GetStatus (&Hndl, + &msr, &ored_msr, &fp_cntr, &fr_cntr, &ss, &Ist_pos); + if (msr == -1) no_errors = False; + } + if (no_errors) goto ds_do; + printf ("\007"); + fprintf (lun, "!\n"); + fprintf (lun, "! Failed to get status of motor\n"); + if (lun != stdout) { + fclose (lun); + printf ("\007error detected.\n"); + } + return False; +ds_do: + if (no_K_cmnd) { + fprintf (lun, "!\n" + "! EL734 ID = \"%s\"\n" + "! Server \"%s\"\n" + "! Port %5d\n" + "! Channel %5d\n" + "! Motor %5d\n", + Ctrl_id, El734_host, El734_port, El734_chan, Motor); + }else { + fprintf (lun, "!\n" + "! Reference mode information: EL734 ID = \"%s\"\n" + "! K = -11 = LoLim + Index is ref. pt. Server \"%s\"\n" + "! -1 = LoLim is ref. pt. Port %5d\n" + "! 0 = Abs encoder Channel %5d\n" + "! 1 = HiLim is ref. pt. Motor %5d\n" + "! 2 = Separate ref. pt.\n" + "! 11 = HiLim + Index is ref. pt.\n" + "! 12 = Separate + Index ref. pt.\n", + Ctrl_id, El734_host, El734_port, El734_chan, Motor); + } + fprintf (lun, "!\n"); + if (!no_SP_cmnd) fprintf (lun, "! # of positionings, SP = %d\n", + Stat_pos); + if (!no_ST_cmnd) fprintf (lun, "! # of positioning faults, ST = %d\n", + Stat_pos_flt); + if (!no_SR_cmnd) fprintf (lun, "! # of positioning failures, SR = %d\n", + Stat_pos_fail); + if (!no_SA_cmnd) fprintf (lun, "! # of air-cushion failures, SA = %d\n", + Stat_cush_fail); + fprintf (lun, "! %s", EL734_EncodeMSR (buff, sizeof (buff), + msr, ored_msr, fp_cntr, fr_cntr)); + fprintf (lun, " %s\n", EL734_EncodeSS (buff, sizeof (buff), ss)); + if (!no_W_cmnd) { + if (Ac_par == 0) { + switch (air_cush) { + case 0: break; /* Don't mention air cushions in this case! */ + case 1: fprintf (lun, "! Air-cushion status is \"on\".\n"); break; + default: fprintf (lun, "! Air-cushion status = %d.\n", air_cush); + } + }else { + switch (air_cush) { + case 0: fprintf (lun, "! Air-cushion is \"down\"\n"); break; + case 1: fprintf (lun, "! Air-cushion is \"up\"\n"); break; + default: fprintf (lun, "! Air-cushion status = %d.\n", air_cush); + } + } + } + if (!no_RI_cmnd) { + switch (inp_state) { + case 0: fprintf (lun, "! Input status is \"off\".\n"); break; + case 1: fprintf (lun, "! Input status is \"on.\"\n"); break; + default: fprintf (lun, "! Input status = %d.\n", inp_state); + } + } + if (!no_AM_cmnd) { + if (act_mot != 0) { + fprintf (lun, "! Active motor status = 0x%03X\n", act_mot); + }else { + fprintf (lun, "! No motors are active.\n"); + } + } + fprintf (lun, "!\n"); + if (Mot_name[0] == NIL) { + sprintf (buff, " mn %%d ..............."); + }else { + sprintf (buff, " mn %%d %s", Mot_name); + } + fprintf (lun, "%-32s! %s\n", buff, "Motor name"); + if (!no_EC_cmnd) { + sprintf (buff, " ec %%d 0 0"); + fprintf (lun, "%-32s! %s\n", buff, "Zero the encoder mapping"); + sprintf (buff, " ec %%d %s", rptr03); + fprintf (lun, "%-32s! %s\n", buff, "Encoder mapping (type/number)"); + } + if (!no_EP_cmnd) { + sprintf (buff, " ep %%d %s", rptr28); + fprintf (lun, "%-32s! %s\n", buff, "Encoder magic parameter"); + } + if (!no_A_cmnd) { + sprintf (buff, " a %%d %s", rptr04); + fprintf (lun, "%-32s! %s\n", buff, "Precision"); + } + if (!no_FD_cmnd) { + sprintf (buff, " fd %%d %s", rptr05); + fprintf (lun, "%-32s! %s\n", buff, "Encoder gearing (numer/denom)"); + } + if (!no_FM_cmnd) { + sprintf (buff, " fm %%d %s", rptr06); + fprintf (lun, "%-32s! %s\n", buff, "Motor gearing (numer/denom)"); + } + if (!no_D_cmnd) { + sprintf (buff, " d %%d %s", rptr07); + fprintf (lun, "%-32s! %s\n", buff, "Inertia tolerance"); + } + if (!no_E_cmnd) { + sprintf (buff, " e %%d %s", rptr08); + fprintf (lun, "%-32s! %s\n", buff, "Start/stop ramp (kHz/sec)"); + } + if (!no_F_cmnd) { + sprintf (buff, " f %%d %s", rptr09); + fprintf (lun, "%-32s! %s\n", buff, "Open loop/Closed loop (0/1)"); + } + if (!no_G_cmnd) { + sprintf (buff, " g %%d %s", rptr10); + fprintf (lun, "%-32s! %s\n", buff, "Start/stop frequency (Mot-S/sec)"); + } + if (!no_H_cmnd) { + sprintf (buff, " h %%d %s", rptr11); + fprintf (lun, "%-32s! %s\n", buff, "Low/High Software Limits"); + } + if (!no_J_cmnd) { + sprintf (buff, " j %%d %s", rptr12); + fprintf (lun, "%-32s! %s\n", buff, "Top speed (Mot-S/sec)"); + } + if (!no_K_cmnd) { + sprintf (buff, " k %%d %s", rptr13); + fprintf (lun, "%-32s! %s\n", buff, "Reference mode"); + } + if (!no_L_cmnd) { + sprintf (buff, " l %%d %s", rptr14); + fprintf (lun, "%-32s! %s\n", buff, "Backlash/Spielausgleich (Mot-S)"); + } + if (!no_M_cmnd) { + sprintf (buff, " m %%d %s", rptr15); + fprintf (lun, "%-32s! %s\n", buff, "Position tolerance (Enc-Steps)"); + } + if (!no_Q_cmnd) { + sprintf (buff, " q %%d %s", rptr16); + fprintf (lun, "%-32s! %s\n", buff, "Reference switch width"); + } + if (!no_T_cmnd) { + sprintf (buff, " t %%d %s", rptr17); + fprintf (lun, "%-32s! %s\n", buff, "One-sided operation flag (0 = no)"); + } + if (!no_V_cmnd) { + sprintf (buff, " v %%d %s", rptr18); + fprintf (lun, "%-32s! %s\n", buff, "Null point"); + } + if (!no_W_cmnd) { + sprintf (buff, " w %%d %s", rptr19); + fprintf (lun, "%-32s! %s\n", buff, "Air-cushion dependency"); + } + if (!no_Z_cmnd) { + sprintf (buff, " z %%d %s", rptr20); + fprintf (lun, "%-32s! %s\n", buff, "Circumf. of encoder (Enc-Steps)"); + } + if (!no_KP_cmnd) { + sprintf (buff, " kp %%d %s", rptr29); + fprintf (lun, "%-32s! %s\n", buff, "Proportional"); + } + if (!no_KI_cmnd) { + sprintf (buff, " ki %%d %s", rptr30); + fprintf (lun, "%-32s! %s\n", buff, "Integral"); + } + if (!no_KD_cmnd) { + sprintf (buff, " kd %%d %s", rptr31); + fprintf (lun, "%-32s! %s\n", buff, "Differential"); + } + if (Mot_mem[0] == NIL) { + sprintf (buff, " mem %%d ..............."); + }else { + sprintf (buff, " mem %%d %s", Mot_mem); + } + fprintf (lun, "%-32s! %s\n", buff, "User data register"); + + if (Ref_mode != 0) { + fprintf (lun, "%-32s! %s\n", " restore", "Incr. encoder" + " - specify position restore"); + } + + fprintf (lun, "!\n"); + fprintf (lun, "! Current position is %.*f\n", Dec_pt, Ist_pos); + fprintf (lun, "!\n"); + if (lun != stdout) { + fclose (lun); + chmod (Save_file, 0644); + printf (" OK.\n"); + } + return True; + } +/* +**-------------------------------------------------------------------------- +** DoLoad: Load parameter settings from a file. +*/ + int DoLoad () { +/* ====== +*/ + int status, go_on, no_errors, no_restore, i, len, act_len; + int msr, ored_msr, fp_cntr, fr_cntr, ss; + FILE *lun; + char recd[132], buff[132], cmnd[80], cmnd_prnt[80]; + /* + ** Setting motor parameters usually causes the current + ** position to get lost. Read it now so that it can be + ** restored at the end if required. + */ + printf ("The current position, "); + status = EL734_GetPrecision (&Hndl, &Dec_pt); + if (status) { + EL734_GetStatus (&Hndl, + &msr, &ored_msr, &fp_cntr, &fr_cntr, &ss, &Ist_pos); + if (msr == -1) status = False; + } + if (!status) { + printf ("\n ... failed to get current position.\n"); + return False; + }else { + printf ("%.*f, can be restored at end of load operation if\n" + "a \"RESTORE\" command is given. Executing a \"U\" or a \"UU\"" + " or any motion command\n" + "will cancel the effect of a \"RESTORE\" command.\n", + Dec_pt, Ist_pos); + no_restore = True; + } + + if ((strcmp (Load_file, "-") == 0) || + (strcmp (Load_file, "=") == 0)) { /* Use standard input? */ + lun = stdin; /* Yes */ + printf ("Getting motor parameters from standard input ...\n> "); + }else { + lun = fopen (Load_file, "r"); + if (lun == NULL) { + printf ("\007Error opening file %s ... load failed.\n", Load_file); + return False; + } + printf ("Getting motor parameters from file %s ...\n", Load_file); + } + + go_on = True; + no_errors = True; + + while (go_on && (fgets (recd, sizeof (recd), lun) != NULL)) { + len = strlen (recd); + if (len <= 1) { + if (lun == stdin) {printf ("> "); fflush (NULL);} + continue; + } + if (recd[len-1] != '\n') { + recd[20] = NIL; + printf ("\007 Record not terminated by \"\\n\". " + "It is probably too long!\n" + " The record starts thus: %s ...\n" + " It has been skipped.\n", recd); + if (lun == stdin) {printf ("> "); fflush (NULL);} + continue; + } + recd[len-1] = NIL; /* Remove the terminating "\n" */ + /* + ** Strip off any trailing stuff (but keep it around so that we + ** can print it out). "Trailing stuff" is anything after a "!". + */ + act_len = strcspn (recd, "!"); + len = sizeof (buff); + StrEdit (buff, recd, "trim compress uncomment", &len); + /* + ** If the remainder is just white-space, do nothing. + */ + if (len <= 0) { + if (lun == stdin) {printf ("> "); fflush (NULL);} + continue; + } + if (strlen (buff) >= sizeof (cmnd)) { + recd[20] = NIL; + printf ("\007 Record has a dubious format!!\n" + " The record starts thus: %s ...\n" + " It has been skipped.\n", recd); + if (lun == stdin) {printf ("> "); fflush (NULL);} + continue; + } + if (sprintf (cmnd, buff, Motor) >= sizeof (cmnd)) { + fprintf (stderr, + "\007 Record has generated a command which is too long.\n" + " This may have corrupted the program. To be safe,\n" + " we are now going to do an emergency exit. Bye.\n"); + exit (False); + } + if ((lun != stdin) && (len > 0)) { /* Show user what's going on */ + strcpy (cmnd_prnt, cmnd); + MakePrint (cmnd_prnt); + printf ("%-32s%s\n", cmnd_prnt, &recd[act_len]); fflush (NULL); + } + len = sizeof (cmnd); + StrEdit (cmnd, cmnd, "upcase compress", &len); + if (strncmp (cmnd, "EXIT", 4) == 0) { + go_on = False; + continue; + }else if (strncmp (cmnd, "QUIT", 4) == 0) { + go_on = False; + continue; + }else if (strncmp (cmnd, "NO_RESTORE", 10) == 0) { + no_restore = True; + printf ("The restore operation has been suppressed via " + "the \"NO_RESTORE\" command.\n"); + }else if (strncmp (cmnd, "RESTORE", 7) == 0) { + no_restore = False; + printf ("The restore operation has been requested via " + "the \"RESTORE\" command.\n"); + }else if (strncmp (cmnd, "WAIT", 4) == 0) { + status = My_WaitIdle (&Hndl, Verbose, + &ored_msr, &fp_cntr, &fr_cntr, &Ist_pos); + if (!status) { + go_on = no_errors = False; + if (Ctrl_C_has_happened) DoStop (); + continue; + }else { + if ((ored_msr & ~(MSR__BUSY | MSR__OK)) != 0) { + printf ("! %s\n", EL734_EncodeMSR (buff, sizeof (buff), + 0, ored_msr, fp_cntr, fr_cntr)); + } + } + }else { + len = strlen (cmnd); + if (len == 2 && cmnd[0] == '\\' && cmnd[1] == 'R') len = 0; + if (len == 2 && cmnd[0] == '\\' && cmnd[1] == '0') { + cmnd[0] = NIL; /* Null command */ + }else { + cmnd[len] = '\r'; /* Terminate command with a */ + cmnd[len+1] = NIL; + } + status = EL734_SendCmnd (&Hndl, cmnd, buff, sizeof (buff)); + if (!status) { + go_on = no_errors = False; + continue; + }else { + if (buff[0] == NIL) { + len = sizeof (cmnd); + if ((strncmp (cmnd, "U ", 2) == 0) || + (strncmp (cmnd, "UU ", 3) == 0) || + (strncmp (cmnd, "P ", 2) == 0) || + (strncmp (cmnd, "PD ", 3) == 0) || + (strncmp (cmnd, "PR ", 3) == 0) || + (strncmp (cmnd, "R ", 2) == 0) || + (strncmp (cmnd, "FF ", 3) == 0) || + (strncmp (cmnd, "FB ", 3) == 0) || + (strncmp (cmnd, "SF ", 3) == 0) || + (strncmp (cmnd, "SB ", 3) == 0)) { + no_restore = True; + }else if ((strncmp (cmnd, "A ", 2) == 0) || + (strncmp (cmnd, "E ", 2) == 0) || + (strncmp (cmnd, "EP ", 3) == 0) || + (strncmp (cmnd, "F ", 2) == 0) || + (strncmp (cmnd, "G ", 2) == 0) || + (strncmp (cmnd, "J ", 2) == 0) || + (strncmp (cmnd, "K ", 2) == 0) || + (strncmp (cmnd, "L ", 2) == 0) || + (strncmp (cmnd, "M ", 2) == 0) || + (strncmp (cmnd, "T ", 2) == 0) || + (strncmp (cmnd, "V ", 2) == 0) || + (strncmp (cmnd, "W ", 2) == 0) || + (strncmp (cmnd, "Z ", 2) == 0)) { + LoadCheckOneInteger (cmnd); + if (strncmp (cmnd, "A ", 2) == 0) { + status = EL734_GetPrecision (&Hndl, &i); + if (status) Dec_pt = i; + } + }else if ((strncmp (cmnd, "EC ", 3) == 0) || + (strncmp (cmnd, "FD ", 3) == 0) || + (strncmp (cmnd, "FM ", 3) == 0)) { + LoadCheckTwoInteger (cmnd); + }else if ((strncmp (cmnd, "D ", 2) == 0)) { + LoadCheckOneFloat (cmnd, 1); /* D cmnd only has 1 Dec Place */ + }else if ((strncmp (cmnd, "Q ", 2) == 0)) { + LoadCheckOneFloat (cmnd, Dec_pt); + }else if ((strncmp (cmnd, "H ", 2) == 0)) { + LoadCheckTwoFloat (cmnd, Dec_pt); + } + }else { + if (buff[0] == '?') { + printf ("%s\n", buff); + if (lun != stdin) { /* If input from file .. */ + go_on = no_errors = False; /* .. quit */ + continue; + } + }else { + if (strncmp (cmnd, "MSR ", 4) == 0) { + sscanf (buff, "%x", &ored_msr); + printf ("%s ! %s\n", buff, + EL734_EncodeMSR (buff, sizeof (buff), + ored_msr, ored_msr, 0, 0)); + }else if (strncmp (cmnd, "SS ", 3) == 0) { + sscanf (buff, "%x", &ss); + printf ("%s ! %s\n", buff, + EL734_EncodeSS (buff, sizeof (buff), ss)); + }else { + printf ("%s\n", buff); + } + } + } + } + } + if (lun == stdin) {printf ("> "); fflush (NULL);} + } + /* + ** Restore the current motor position. + */ + if (no_errors && !no_restore) { + EL734_GetPrecision (&Hndl, &Dec_pt); + printf ("Restoring %.*f as current motor position ...\n", + Dec_pt, Ist_pos); + sprintf (cmnd, "uu %d %.*f\r", Motor, Dec_pt, Ist_pos); + status = EL734_SendCmnd (&Hndl, cmnd, buff, sizeof(buff)); + if (status) { + if (buff[0] != NIL) { + no_errors = False; + } + }else { + no_errors = False; + } + } + if (lun != stdin) fclose (lun); + if (no_errors) { + printf ("\"load\" completed.\n"); + EL734_GetStatus (&Hndl, + &msr, &ored_msr, &fp_cntr, &fr_cntr, &ss, &Ist_pos); + printf ("The motor position is %.*f\n", Dec_pt, Ist_pos); + }else { + printf ("\007Failed to load motor parameters.\n"); + } + return no_errors; + } +/* +**-------------------------------------------------------------------------- +** DoDiff: Compare parameter settings with those in a file. +*/ + int DoDiff () { +/* ====== +*/ + int status, go_on, no_errors, n_errs, i, len, act_len; + int msr, ored_msr, fp_cntr, fr_cntr, ss; + FILE *lun; + char recd[132], buff[132], buff0[132], cmnd[80], cmnd_prnt[80]; + char *tok0, *tok1, *tok2, *tok3, *tok2a, *tok3a; + + if ((strcmp (Diff_file, "-") == 0) || + (strcmp (Diff_file, "=") == 0)) { /* Use standard input? */ + lun = stdin; /* Yes */ + printf ("Comparing motor parameters with those from standard " + "input ...\n> "); + }else { + lun = fopen (Diff_file, "r"); + if (lun == NULL) { + printf ("\007Error opening file %s ... diff failed.\n", Diff_file); + return False; + } + printf ("Comparing motor parameters with those in %s ...\n", Diff_file); + } + + go_on = True; + no_errors = True; + n_errs = 0; + + while (go_on && (fgets (recd, sizeof (recd), lun) != NULL)) { + len = strlen (recd); + if (len <= 1) { + if (lun == stdin) {printf ("> "); fflush (NULL);} + continue; + } + if (recd[len-1] != '\n') { + recd[20] = NIL; + printf ("\007 Record not terminated by \"\\n\". " + "It is probably too long!\n" + " The record starts thus: %s ...\n" + " It has been skipped.\n", recd); + if (lun == stdin) {printf ("> "); fflush (NULL);} + continue; + } + recd[len-1] = NIL; /* Remove the terminating "\n" */ + /* + ** Strip off any trailing stuff (but keep it around so that we + ** can print it out). "Trailing stuff" is anything after a "!". + */ + act_len = strcspn (recd, "!"); + len = sizeof (buff0); + StrEdit (buff0, recd, "trim compress uncomment", &len); + /* + ** If the remainder is just white-space, do nothing. + */ + if (len <= 0) { + if (lun == stdin) {printf ("> "); fflush (NULL);} + continue; + } + if (sprintf (buff, buff0, Motor) >= sizeof (buff)) { + fprintf (stderr, + "\007 Record has generated a command which is too long.\n" + " This may have corrupted the program. To be safe,\n" + " we are now going to do an emergency exit. Bye.\n"); + exit (False); + } + if (strlen (buff) >= sizeof (cmnd)) { + recd[20] = NIL; + printf ("\007 Record has a dubious format!!\n" + " The record starts thus: %s ...\n" + " It has been skipped.\n", recd); + if (lun == stdin) {printf ("> "); fflush (NULL);} + continue; + } + tok0 = strtok (buff, " \t"); if (tok0 == NULL) tok0 = ""; + tok1 = strtok (NULL, " \t"); if (tok1 == NULL) tok1 = ""; + tok2 = strtok (NULL, " \t"); if (tok2 == NULL) tok2 = ""; + tok3 = strtok (NULL, " \t"); if (tok3 == NULL) tok3 = ""; + MakePrint (tok0); MakePrint (tok1); MakePrint (tok2); MakePrint (tok3); + sprintf (cmnd_prnt, "%-2s %s", tok0, tok1); + len = sizeof (cmnd); + StrEdit (cmnd, cmnd_prnt, "upcase compress", &len); + StrJoin (cmnd_prnt, sizeof (cmnd_prnt), cmnd_prnt, " "); + StrJoin (cmnd_prnt, sizeof (cmnd_prnt), cmnd_prnt, tok2); + StrJoin (cmnd_prnt, sizeof (cmnd_prnt), cmnd_prnt, " "); + StrJoin (cmnd_prnt, sizeof (cmnd_prnt), cmnd_prnt, tok3); + if (strncmp (cmnd, "EXIT", 4) == 0) { + go_on = False; + continue; + }else if (strncmp (cmnd, "QUIT", 4) == 0) { + go_on = False; + continue; + }else if ((strcmp (tok2, "0") == 0) && + (strcmp (tok3, "0") == 0) && + (strcmp (&recd[act_len], "! Zero the encoder mapping") == 0)) { + /* + ** This is the command "ec %d 0 0" which is used to zero + ** the encoder mapping before it is set again. Simply + ** skip this command. + */ + if (lun == stdin) {printf ("> "); fflush (NULL);} + continue; + }else { + if (lun != stdin) { /* Show user what's going on */ + printf ("%-32s%s\n", cmnd_prnt, &recd[act_len]); fflush (NULL); + } + len = strlen (cmnd); + cmnd[len] = '\r'; /* Terminate command with a */ + cmnd[len+1] = NIL; + status = EL734_SendCmnd (&Hndl, cmnd, buff0, sizeof (buff0)); + if (!status) { + go_on = no_errors = False; + n_errs++; + continue; + }else { + tok2a = strtok (buff0, " \t"); if (tok2a == NULL) tok2a = ""; + tok3a = strtok (NULL, " \t"); if (tok3a == NULL) tok3a = ""; + if ((strcmp (tok2, tok2a) != 0) && (strcmp (tok3, tok3a) != 0)) { + printf (" >>>> Parameters were %-7s and %s\n", tok2, tok3); + printf (" >>>> Now they are %-7s and %s\n", tok2a, tok3a); + no_errors = False; + n_errs++; + }else if (strcmp (tok2, tok2a) != 0) { + if ((strcmp (tok2, "") == 0) || + (strcmp (tok2a, "...............") == 0)) { + }else if ((strcmp (tok2, "...............") == 0) || + (strcmp (tok2a, "") == 0)) { + }else { + printf (" >>>> Parameter was %-7s\n", tok2); + printf (" >>>> Now it is %-7s\n", tok2a); + no_errors = False; + n_errs++; + } + }else if (strcmp (tok3, tok3a) != 0) { + printf (" >>>> Parameters were %-7s and %s\n", tok2, tok3); + printf (" >>>> Now they are %-7s and %s\n", tok2a, tok3a); + no_errors = False; + n_errs++; + } + } + } + if (lun == stdin) {printf ("> "); fflush (NULL);} + } + if (lun != stdin) fclose (lun); + if (no_errors) { + printf ("All OK.\n"); + }else if (n_errs == 1) { + printf ("\007%d motor parameter difference found.\n", n_errs); + }else { + printf ("\007%d motor parameter differences found.\n", n_errs); + } + return no_errors; + } +/* +**--------------------------------------------------------------------------- +** DoWait - wait (if necessary) +*/ + void DoWait ( +/* ====== +*/ int print_flag) { + + int my_wait, irand; + float my_rand; + + if (Wait_time == 0) return; + + if (Wait_time > 0) { + if (print_flag) printf (" waiting %d secs ...", Wait_time); + sleep (Wait_time); + if (print_flag) printf ("\n"); + return; + } + + my_wait = -Wait_time; + + irand = rand () & 0x7FFF; + my_rand = ((float) irand)/32768.0; + + my_rand = my_rand * ((float) (my_wait)); + irand = (int) (my_rand + 1); + if (print_flag) printf (" waiting %d secs ...", irand); + sleep (irand); + if (print_flag) printf ("\n"); + } +/* +**-------------------------------------------------------------------------- +** PrintUsage: Auxilliary routine for ShowUsage and ShowItemUsage +*/ + int PrintUsage (char **txt, int n_recd) { +/* ========== +*/ + int i = 0; + int ans; + + printf ("\n"); + while (i < n_recd) { + printf ("%s\n", txt[i]); + i++; + if ((i % 24 == 0) && isatty (STDOUT)) { + printf ("More? "); + ans = getchar (); + if ((ans == EOF) || (toupper (ans) == 'Q')) return False; + } + } + printf ("\n"); + } +/* +**-------------------------------------------------------------------------- +** ShowUsage: A simple help routine. +*/ + void ShowUsage (int level) { +/* ========= +*/ + char *short_help_txt[] = { +"\007To get help on running the program issue the command:", +"", +" el734_test -help"}; + + char *help_txt[] = { +" Usage: el734_test [options ...]", +"", +" Valid options are:", +" -help Generates this help text.", +" -?