26 #include "lemSCWatchdog.h"
31 #define SM_ETS_LOGOUT_SLEEP 10000
33 #define SM_TIME_OUT 2000
34 #define SM_TIME_BETWEEN_SETS 10
35 #define SM_ACCURACY 1.0
40 #define SM_RECONNECTION_TIMEOUT 5
41 #define SM_MAX_READBACK_FAILURE 5
43 #define SM_MAX_RECONNECTION_FAILURE 5
47 #define SM_MAX_ERROR 3
48 #define SM_DELTA_TIME_ERROR 3600
51 #define SM_INIT_ERROR -2
52 #define SM_READ_ERROR -1
57 #define SM_K2700_CH 20
58 #define SM_K2700_SIG_CH 4
59 #define SM_K2700_POT_CH 2
60 #define SM_SCS900_CH 32
61 #define SM_SCS900_SIG_CH 4
62 #define SM_SCS900_POT_CH 2
63 #define SM_SCS2001M_CH 44
64 #define SM_SCS2001M_SIG_CH 14
65 #define SM_SCS2001M_POT_CH 15
79 #define SM_INTERNAL_STR "\
80 ODB Offset = INT : 12\n\
81 Detailed Messages = INT : 0\n\
82 ETS_IN_USE = INT : 1\n\
83 SCW_IN_USE = INT : 0\n\
84 No Connection = INT : 1\n\
85 Reconnection Timeout = INT : 10\n\
86 Read Timeout = INT : 5\n"
105 char read_back_device[NAME_LENGTH];
123 char sm_in_name[NAME_LENGTH];
124 char sm_out_name[NAME_LENGTH];
125 char sm_modus_name[NAME_LENGTH];
126 INT (*bd)(INT cmd, ...);
177 cm_msg(MINFO,
"sm_send_rcv",
"sm_send_rcv: trial %d, cmd = %s", i, cmd);
179 status = BD_GETS(tmpstr,
sizeof(tmpstr),
"\r\n",
SM_TIME_OUT);
181 cm_msg(MINFO,
"sm_send_rcv",
"sm_send_rcv: trial %d, status = %d, str = %s", i, status, tmpstr);
191 cm_msg(MINFO,
"sm_send_rcv",
"sm_send_rcv: %d time Time_out after sending %s", i, cmd);
194 sprintf( msg,
"Steppermotor of Transferline does not respond");
195 al_trigger_alarm(
"sm_send_rcv", msg,
"Warning", msg, AT_INTERNAL);
221 cm_msg(MINFO,
"sm_send",
"sm_send: str = %s", cmd);
267 sprintf( s,
"PRINT SER\r\n");
271 cm_msg(MERROR,
"sm_check_serialnumber",
"sm_check_serialnumber: no response, stat = %d", stat);
274 cm_msg(MINFO,
"sm_check_serialnumber",
"sm_check_serialnumber: %s", res);
276 if ((stat != l_serial) || (res[14] !=
'A')) {
300 float position = 9.999e+11;
306 sprintf( s,
"PRINT POS\r\n");
309 position = atof(res);
313 cm_msg(MINFO,
"sm_read_position",
"sm_read_position: position = %e", position );
331 float velocity = 9.999e+11;
337 sprintf( s,
"PRINT VM\r\n");
340 velocity = atof(res);
344 cm_msg(MINFO,
"sm_read_velocity",
"sm_read_velocity: velocity = %e", velocity );
365 int size =
sizeof(float);
369 int isize =
sizeof(int);
371 cm_get_experiment_database(&hDB, NULL);
374 info = calloc(1,
sizeof(
SM_INFO));
379 if ((status != DB_SUCCESS) && (status != DB_OPEN_RECORD)) {
380 cm_msg(MINFO,
"sm_in_init",
"sm_in_init: start init, create internal record DD = %d", status);
387 cm_msg(MINFO,
"sm_in_init",
"sm_in_init: start init, db_find_DD = %d",
388 db_find_key(hDB, hKey,
"DD", &hkeydd));
392 if (status != DB_SUCCESS) {
393 cm_msg(MINFO,
"sm_in_init",
"sm_in_init: start init, open record DD = %d", status);
406 if (info->
data == NULL) {
407 cm_msg(MERROR,
"sm_in_init",
"sm_in_init: couldn't allocate data memory.");
414 db_find_key(hDB, 0,
"/Equipment/K2700/Variables/Input", &hkeydd);
415 db_open_record(hDB, hkeydd, (
void *)info->
data,
SM_K2700_CH*
sizeof(
float), MODE_READ, NULL, NULL);
420 for (i=0; i<5; i++) {
427 cm_msg(MINFO,
"sm_in_init" ,
"sm_in_init: You are using transferline %d ", info->
sm_in_use);
430 cm_msg(MINFO,
"sm_in_init" ,
"sm_in_init: No valid signature found" );
439 cm_msg(MINFO,
"sm_in_init" ,
"sm_in_init: initial values : %e", info->
voltage );
445 if (info->
data == NULL) {
446 cm_msg(MERROR,
"sm_in_init",
"sm_in_init: couldn't allocate data memory.");
453 db_find_key(hDB, 0,
"/Equipment/SCS900/Variables/Input", &hkeydd);
454 db_open_record(hDB, hkeydd, (
void *)info->
data,
SM_SCS900_CH*
sizeof(
float), MODE_READ, NULL, NULL);
459 for (i=0; i<5; i++) {
466 cm_msg(MINFO,
"sm_in_init" ,
"sm_in_init: You are using transferline %d ", info->
sm_in_use);
469 cm_msg(MINFO,
"sm_in_init" ,
"sm_in_init: No valid signature found" );
478 cm_msg(MINFO,
"sm_in_init" ,
"sm_in_init: initial values : %e", info->
voltage);
480 cm_msg(MINFO,
"sm_in_init",
"sm_in_int: SCS900/Variables/Input %d ? %d, %e",
487 if (info->
data == NULL) {
488 cm_msg(MERROR,
"sm_in_init",
"sm_in_init: couldn't allocate data memory.");
495 db_find_key(hDB, 0,
"/Equipment/SCS2001M/Variables/Input", &hkeydd);
496 db_open_record(hDB, hkeydd, (
void *)info->
data,
SM_SCS2001M_CH*
sizeof(
float), MODE_READ, NULL, NULL);
501 for (i=0; i<5; i++) {
508 cm_msg(MINFO,
"sm_in_init" ,
"sm_in_init: You are using transferline %d ", info->
sm_in_use);
511 cm_msg(MINFO,
"sm_in_init" ,
"sm_in_init: No valid signature found" );
520 cm_msg(MINFO,
"sm_in_init" ,
"sm_in_init: initial values : %e", info->
voltage);
522 cm_msg(MINFO,
"sm_in_init",
"sm_in_int: SCS2001M/Variables/Input %d ? %d, %e",
532 db_find_key(hDB, 0,
"/Equipment/SampleCryo/Variables/Output", &hkeydd);
535 info->
modus = (int) value;
540 cm_msg(MINFO,
"sm_in_init",
"sm_in_init: present setpoint = %e", info->
setpoint);
543 size =
sizeof(float);
546 cm_msg(MINFO,
"sm_in_init",
"sm_in_init: Demand value = %e", value);
551 cm_msg(MINFO,
"sm_in_init",
"sm_in_init: Will change demand value from %e to %e",
561 sprintf( info->
sm_in_name,
"Needle valve (read_back)");
562 sprintf( info->
sm_out_name,
"Needle valve (Set Point)");
563 sprintf( info->
sm_modus_name,
"NV: R(0), RW(1), A(2), PID(3)");
571 status = db_find_key(hDB, hKey,
"DD/Internal/No Connection", &info->
hkey_no_connection);
574 cm_msg(MERROR,
"sm_in_init" ,
"sm_in_init: couldn't establish the bus driver connection.");
580 cm_msg(MINFO,
"sm_in_init" ,
"sm_in_init: Found: DD/Internal/No Connection");
584 if (info->
modus == 0) {
588 if (info->
modus == 3) {
591 db_find_key(info->
hDB, info->
hkey,
"DD/ToAutoPress", &hkeydd);
593 db_set_data(info->
hDB, hkeydd, (
void *)&ivalue, isize, 1, TID_INT);
600 cm_msg(MINFO,
"sm_init",
"sm_init: Activated AutoPress");
603 cm_msg(MINFO,
"sm_init",
"sm_init: AutoPress could not be activated");
607 cm_msg(MINFO,
"sm_init",
"sm_init: AutoPress could not be activated, while it is not running");
614 status = info->
bd(CMD_INIT, hKey, &info->
bd_info);
615 if (status != FE_SUCCESS) {
621 cm_msg(MINFO,
"sm_in_init",
"sm_in_init: Bus driver initialized.");
632 cm_msg(MERROR,
"sm_in_init",
"sm_in_int: ERROR: check_serial_number_and_maxima = %d", status);
638 cm_msg(MINFO,
"sm_in_init",
"sm_in_int: INFO: check_serial_number_and_maxima = %d", status);
648 cm_msg(MINFO,
"sm_in_init",
"sm_in_int: Initial position = %e", info->
position);
656 cm_msg(MINFO,
"sm_in_init",
"sm_in_int: Initial velocity = %e", info->
velocity);
673 INT
sm_out_init(HNDLE hKey,
void **pinfo, INT channels, INT (*bd)(INT cmd, ...))
677 cm_get_experiment_database(&hDB, NULL);
693 char cmd[128], str[128];
694 float position, value, target;
695 int status, ii, delay;
704 cm_msg(MINFO,
"SM_set",
"SM_set entered to set %f percent", setpoint);
715 cm_msg(MERROR,
"SM_set",
"too many reconnection failures in sm_set, bailing out :-(");
723 info->
scw.last_updated = ss_time();
724 lem_scw_update(&info->
scw);
731 cm_msg(MINFO,
"SM_set",
"Steppermotor: reconnection trial ...");
734 if (status != FE_SUCCESS) {
737 cm_msg(MINFO,
"SM_set",
"Steppermotor: reconnection attempted failed");
745 cm_msg(MINFO,
"SM_get",
"Steppermotor: successfully reconnected");
757 cm_msg(MINFO,
"SM_set",
"SM_set: too less time between the set commands");
767 if ((value < -20.0) || (value > 110.0)) {
768 cm_msg(MINFO,
"sm_set",
"sm_set: potmeter reading out range: value = %e", value);
769 sprintf( str,
"Potentiometer reading out of range, value = %e", value);
770 al_trigger_alarm(
"sm_set", str,
"Warning", str, AT_INTERNAL);
775 cm_msg(MINFO,
"sm_set",
"sm_set: Changing the NeedleValve from %e to %e percent opening",
780 cm_msg(MINFO,
"sm_set",
781 "sm_set: position of the needle valve potentiometer has been changed, it was %e and is now %e !!",
783 cm_msg(MINFO,
"sm_set",
"sm_set: assuming %e to be correct !!", value );
785 sprintf( str,
"Transferline_Needle_Valve has been changed manually ?");
792 if ((fabs(position) < 0.001) && (fabs(info->
position) > 0.001)) {
793 sprintf( str,
"sm_set: Steppermotor drive has been without power !!");
794 al_trigger_alarm(
"sm_set", str,
"Warning", str, AT_INTERNAL);
795 cm_msg(MINFO,
"sm_set",
"sm_set: Steppermotor drive has been without power !!");
800 if ((fabs( position - info->
position ) > 0.1) && (fabs(position) > 0.001)) {
801 cm_msg(MINFO,
"sm_set",
802 "sm_set: position of the needle motor has been changed unexpectively, it was %e and is now %e !!",
810 if ((setpoint < -10.0) || (setpoint > 110.0)) {
811 cm_msg(MINFO,
"sm_set",
"sm_set: setpoint out range: setpoint = %e", setpoint);
812 sprintf( str,
"Transferline setpoint reading out of range, value = %e", setpoint);
813 al_trigger_alarm(
"sm_set", str,
"Warning", str, AT_INTERNAL);
832 sprintf( cmd,
"MOVR %f\r\n", value);
833 target = position + value;
836 cm_msg(MINFO,
"sm_set",
"sm_set: Sending: %s", cmd);
844 delay = 2 * (int) (fabs(value) / info->
velocity) + 20;
850 cm_msg(MINFO,
" sm_set",
"sm_set: needlvevalve moved to %.2f degrees in %.1f seconds reaching %.2f percent",
858 cm_msg(MINFO,
" sm_set",
"sm_set: needlvevalve moved by %.2f degrees in %.1f seconds to %.2f percent",
859 value, (
float) ii/2.0, setpoint);
863 cm_msg(MINFO,
" sm_set",
864 "sm_set: needlvevalve could not be moved by %.2f degrees in %.1f seconds", value, ((
float) delay/2.0) );
865 sprintf( str,
"needlvevalve could not be moved by %.2f degrees in %0.1f seconds", value, ((
float) delay/2.0) );
866 al_trigger_alarm(
"sm_set", str,
"Warning", str, AT_INTERNAL);
894 if ((*pvalue < -20.0) || (*pvalue > 120.0)) {
895 *pvalue = *pvalue - 1000.0;
902 cm_msg(MINFO,
"sm_get",
"sm_get: Getting value = %e", *pvalue);
935 cm_msg(MINFO,
"sm_read_potmeter",
"sm_read_potmeter: voltage = %e, value = %e", info->
voltage, value);
975 strncpy(name, info->
sm_in_name,
sizeof(name));
993 int size =
sizeof(float);
994 int isize =
sizeof(int);
997 modus = (int) floatmodus;
1008 db_find_key(info->
hDB, info->
hkey,
"DD/ToAutoPress", &hkeydd);
1010 db_set_data(info->
hDB, hkeydd, (
void *)&ivalue,
sizeof(ivalue), 1, TID_INT);
1014 status = status + 1;
1017 cm_msg(MINFO,
"sm_switch",
"sm_switch: Deactivated AutoPress");
1019 cm_msg(MINFO,
"sm_switch",
"sm_switch: AutoPress could not be deactivated");
1025 switch (info->
modus) {
1027 cm_msg(MINFO,
"sm_switch",
"sm_switch: Setting steppermotor from read-write to read-only");
1030 cm_msg(MINFO,
"sm_switch",
"sm_switch: Setting steppermotor from auto to read-only");
1033 cm_msg(MINFO,
"sm_switch",
"sm_switch: Setting steppermotor from PID to read-only");
1048 if ((info->
modus == 0 || info->
modus == 3) && (modus == 1 || modus == 2)) {
1049 if (info->
modus == 0 && modus == 1)
1050 cm_msg(MINFO,
"sm_switch",
"sm_switch: Setting steppermotor from read-only to read-write");
1051 if (info->
modus == 0 && modus == 2)
1052 cm_msg(MINFO,
"sm_switch",
"sm_switch: Setting steppermotor from read-only to auto");
1053 if (info->
modus == 3 && modus == 1)
1054 cm_msg(MINFO,
"sm_switch",
"sm_switch: Setting steppermotor from PID to read-write");
1055 if (info->
modus == 3 && modus == 2)
1056 cm_msg(MINFO,
"sm_switch",
"sm_switch: Setting steppermotor from PID to auto");
1059 db_find_key(info->
hDB, 0,
"/Equipment/SampleCryo/Variables/Output", &hkeydd);
1064 cm_msg(MINFO,
"sm_switch",
"sm_switch: present setpoint = %e", info->
setpoint);
1066 size =
sizeof(float);
1068 if (
SM_DEBUG) cm_msg(MINFO,
"sm_switch",
"sm_switch: Demand value = %e", value);
1071 cm_msg(MINFO,
"sm_in_switch",
"sm_switch: Will change demand value from %e to %e",
1078 if (status != FE_SUCCESS) {
1084 cm_msg(MINFO,
"sm_switch",
"sm_switch: Bus driver initialized.");
1093 if ( status != 0 ) {
1094 cm_msg(MERROR,
"sm_switch",
"sm_switch: ERROR: check_serial_number_and_maxima = %d", status);
1100 "sm_switch",
"sm_switch: INFO: check_serial_number_and_maxima = %d", status);
1108 cm_msg(MINFO,
"sm_switch",
"sm_switch: Initial position = %e", info->
position);
1115 cm_msg(MINFO,
"sm_switch",
"sm_switch: Initial velocity = %e", info->
velocity);
1121 if ((info->
modus == 2) && (modus == 1)) {
1122 cm_msg(MINFO,
"sm_switch",
"sm_switch: Setting steppermotor from auto to read-write");
1126 if ((info->
modus == 1) && (modus == 2)) {
1127 cm_msg(MINFO,
"sm_switch",
"sm_switch: Setting steppermotor from read-write to auto");
1141 db_find_key(info->
hDB, info->
hkey,
"DD/ToAutoPress", &hkeydd);
1143 db_set_data(info->
hDB, hkeydd, (
void *)&ivalue, isize, 1, TID_INT);
1147 status = status + 1;
1149 cm_msg(MINFO,
"sm_switch",
"sm_switch: Activated AutoPress");
1151 cm_msg(MINFO,
"sm_switch",
"sm_switch: AutoPress could not be activated");
1154 cm_msg(MINFO,
"sm_switch",
"sm_switch: AutoPress could not be activated, while it is not running");
1158 info->
modus = modus;
1190 INT channel, status;
1196 va_start(argptr, cmd);
1197 status = FE_SUCCESS;
1201 hKey = va_arg(argptr, HNDLE);
1202 info = va_arg(argptr,
void *);
1203 channel = va_arg(argptr, INT);
1204 flags = va_arg(argptr, DWORD);
1205 bd = va_arg(argptr,
void *);
1206 status =
sm_in_init(hKey, info, channel, bd);
1210 info = va_arg(argptr,
void *);
1215 info = va_arg(argptr,
void *);
1216 channel = va_arg(argptr, INT);
1217 pvalue = va_arg(argptr,
float*);
1218 status =
sm_get(info, pvalue);
1222 info = va_arg(argptr,
void *);
1223 channel = va_arg(argptr, INT);
1224 name = va_arg(argptr,
char *);
1240 INT channel, status;
1246 va_start(argptr, cmd);
1247 status = FE_SUCCESS;
1251 hKey = va_arg(argptr, HNDLE);
1252 info = va_arg(argptr,
void *);
1253 channel = va_arg(argptr, INT);
1254 flags = va_arg(argptr, DWORD);
1255 bd = va_arg(argptr,
void *);
1260 info = va_arg(argptr,
void *);
1261 channel = va_arg(argptr, INT);
1262 value = (float) va_arg(argptr,
double);
1263 if (channel == 0) status =
sm_set(info, value);
1264 if (channel == 1) status =
sm_switch(info, value);
1268 info = va_arg(argptr,
void *);
1269 channel = va_arg(argptr, INT);
1270 name = va_arg(argptr,
char *);
INT reconnection_failures
how many reconnection failures took place
#define SM_ACCURACY
condition for alarm on manual changes
int first_bd_error
flag showing if the bus driver error message is already given
float mrc_open
maximum steady current on opening the valve
INT sm_switch(SM_INFO *info, float floatmodus)
INT ets_in_use
flag indicating if the rs232 terminal server is in use
float sm_read_potmeter(SM_INFO *info)
INT sm_send_rcv(SM_INFO *info, char *cmd, char *str)
float sm_read_position(SM_INFO *info)
DWORD last_set_time
time at the last setting of the valve
float position
prevailing position (filled by sm_in_init
char read_back_device[NAME_LENGTH]
device used to read the potentiometer, K2700 or SCS900
INT no_connection
flag showing that there is no connection at the moment
INT sm_exit(SM_INFO *info)
INT sm_out_init(HNDLE hKey, void **pinfo, INT channels, INT(*bd)(INT cmd,...))
float mac_open
maximum accelaration current on opening the valve
#define SM_RECONNECTION_TIMEOUT
timeout in (sec) between logout terminal server an reconnection trial
#define SM_TIME_BETWEEN_SETS
minimum time between settings of steppermotor to allow odb updates
char sm_in_name[NAME_LENGTH]
float valve_range
total number of degrees that the valve cvan turn
#define SM_WAIT
time (ms) to wait between commands
#define SM_MAX_TRY
maximum number of communication attempts
INT sm_send(SM_INFO *info, char *cmd)
float voltage
voltage over the potentiometer
int check_serialnumber_and_maxima(SM_INFO *info)
INT sm_in_get_default_name(SM_INFO *info, INT channel, char *name)
char sm_out_name[NAME_LENGTH]
INT scw_in_use
flag indicating if the slowcontrol watchdog shall be used
int FromAutoPress
ODB map of NeedleValve/DD/FromAutoPress.
INT sm_get(SM_INFO *info, float *pvalue)
int sm_in_use
flag signalling 'in use' of the steppermotor
INT sm_set(SM_INFO *info, float setpoint)
void sm_no_connection(SM_INFO *info, INT value)
#define SM_DEBUG
debug tag, if set to TRUE, additional messages will be displayed at execution time ...
INT startup_error
startup error tag
#define SM_MAX_RECONNECTION_FAILURE
maximum number of reconnections before bailing off
float signature
signature of the steppermotor
INT read_timeout
get data every read_timeout (sec), if zero midas has the timing control
int modus
modus: readonly = 0, readwrite = 1, auto = 2, PID = 3
stores internal informations within the DD.
void * bd_info
private info of bus driver
float mhc
maximum holding current
INT ToAutoPress
handshake to auto pressure program
float setpoint
prevailing setpoint
float velocity
maximum velocity of the motor
SM_INDIVIDUAL individual[5]
parameters for each steppermotor
float mac_close
maximum accelaration current on closing the valve
#define SM_SCS2001M_SIG_CH
int bd_connected
flag showing if bus driver is connected
float signature
(unique) voltage read from line 3 of the transferline
char sm_modus_name[NAME_LENGTH]
INT FromAutoPress
handshake from auto pressure program
HNDLE hkey
handle to the BD key
INT odb_offset
what is the odb offset of the DD. Needed for absolut addressing of the ODB
stores internal information
float mrc_close
maximum steady current on closing the valve
HNDLE hDB
main handle to the ODB
#define SM_SCS2001M_POT_CH
INT sm_out_get_default_name(SM_INFO *info, INT channel, char *name)
structure to store information on individual steppermotor
#define SM_TIME_OUT
time out in msecs for read (rs232)
INT(* bd)(INT cmd,...)
bus driver entry function
float sm_read_velocity(SM_INFO *info)
INT sm_in_init(HNDLE hKey, void **pinfo, INT channels, INT(*bd)(INT cmd,...))
#define SM_INTERNAL_STR
initializing string for SM_INTERNAL
INT reconnect_timeout
reconnection timeout in (sec)
SM_INTERNAL intern
internal data for device driver
SM_SETTINGS sm_settings
ODB data etc.
HNDLE hkey_no_connection
handle to the no connection flag
LEM_SC_WATCHDOG scw
slowcontrol watchdog info structure
INT detailed_msg
flag indicating if detailed status/error messages are wanted
DWORD last_reconnect
timer for bus driver reconnect error
float * data
pointer to data to obtain TFL signature and pot.meter reading