Low-Energy Muon (LEM) Experiment  0.5.2
steppermotor.c
Go to the documentation of this file.
1 /********************************************************************\
2 
3  Name: steppermotor.c
4  Created by: Ge Nieuwenhuys 2006/10/12
5 
6  Contents: device driver for the steppermotor
7  defined as a multi class device.
8 
9  RS232: 9600 baud, 8 data bits, 1 stop bit, no parity bit,
10  protocol: no flow control, termination \r\n (CR\LF)
11 
12  July, 20, 2007: changed readback device for tent from LS340 to K2700
13 
14 ********************************************************************/
15 
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <stdarg.h>
19 #include <string.h>
20 #include <math.h>
21 
22 #include "midas.h"
23 #include "steppermotor.h"
24 
25 #include "ets_logout.h"
26 #include "lemSCWatchdog.h"
27 
28 /*---- globals -----------------------------------------------------*/
29 
31 #define SM_ETS_LOGOUT_SLEEP 10000
32 
33 #define SM_TIME_OUT 2000
34 #define SM_TIME_BETWEEN_SETS 10
35 #define SM_ACCURACY 1.0
36 
37 /* --------- to handle error messages ------------------------------*/
38 
40 #define SM_RECONNECTION_TIMEOUT 5
41 #define SM_MAX_READBACK_FAILURE 5
43 #define SM_MAX_RECONNECTION_FAILURE 5
45 
46 
47 #define SM_MAX_ERROR 3
48 #define SM_DELTA_TIME_ERROR 3600
49 #define SM_MAX_TRY 10
50 #define SM_WAIT 500
51 #define SM_INIT_ERROR -2
52 #define SM_READ_ERROR -1
53 
54 #define SM_DEBUG 0
56 
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
66 
68 typedef struct {
69  INT odb_offset;
71  INT ets_in_use;
72  INT scw_in_use;
76 } SM_INTERNAL;
77 
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"
87 
89 typedef struct {
90  float pcurve[3];
91  float valve_range;
93  float mhc;
94  float mac_open;
95  float mac_close;
96  float mrc_open;
97  float mrc_close;
98  float signature;
99  } SM_INDIVIDUAL;
100 
101 /*---------------------------------------------------------------------*/
102 
104 typedef struct {
105  char read_back_device[NAME_LENGTH];
109  float Tau_PID[4];
110  SM_INDIVIDUAL individual[5];
111 } SM_SETTINGS;
112 
113 /*---------------------------------------------------------------------*/
114 
117 typedef struct {
119  LEM_SC_WATCHDOG scw;
120  HNDLE hDB;
121  HNDLE hkey;
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, ...);
127  void *bd_info;
129  int sm_in_use;
130  int modus;
136  float signature;
137  float setpoint;
138  float position;
139  float velocity;
140  float voltage;
141  float *data;
143 } SM_INFO;
144 
145 // predeclarations of local functions:
146 INT sm_send_rcv(SM_INFO *info, char *cmd, char *str);
147 INT sm_send(SM_INFO *info, char *cmd);
148 void sm_no_connection(SM_INFO *info, INT value);
150 
151 // global variable
153 
154 /*---- support routines --------------------------------------------*/
162 INT sm_send_rcv(SM_INFO *info, char *cmd, char *str)
163 {
164  char tmpstr[128];
165  INT status, i;
166  char msg[256];
167 
168  if (!info->bd_connected) { // bus driver not connected at the moment
169  return 0;
170  }
171 
172  status = 0;
173  i = 0;
174  do {
175  BD_PUTS(cmd);
176  if (info->sm_settings.intern.detailed_msg) {
177  cm_msg(MINFO,"sm_send_rcv", "sm_send_rcv: trial %d, cmd = %s", i, cmd);
178  }
179  status = BD_GETS(tmpstr, sizeof(tmpstr), "\r\n", SM_TIME_OUT);
180  if (info->sm_settings.intern.detailed_msg) {
181  cm_msg(MINFO,"sm_send_rcv", "sm_send_rcv: trial %d, status = %d, str = %s", i, status, tmpstr);
182  }
183  i = i + 1;
184 
185  if (status<=0) {
186  ss_sleep(SM_WAIT);
187  }
188  } while ((status<=0) && (i<SM_MAX_TRY));
189 
190  if (i==SM_MAX_TRY) {
191  cm_msg(MINFO, "sm_send_rcv", "sm_send_rcv: %d time Time_out after sending %s", i, cmd);
192  sm_no_connection( info, 1 ); // kill any further action
193  // set alarm
194  sprintf( msg, "Steppermotor of Transferline does not respond");
195  al_trigger_alarm("sm_send_rcv", msg, "Warning", msg, AT_INTERNAL);
196  return status;
197  }
198 
199  strcpy(str, tmpstr);
200  return status;
201 }
202 
203 
204 /*---- support routines --------------------------------------------*/
211 INT sm_send(SM_INFO *info, char *cmd)
212 {
213 
214  if (!info->bd_connected) { // bus driver not connected at the moment
215  return 0;
216  }
217 
218  BD_PUTS(cmd);
219 
220  if (info->sm_settings.intern.detailed_msg) {
221  cm_msg(MINFO,"sm_send", "sm_send: str = %s", cmd);
222  }
223 
224  ss_sleep(100); // to leat the steppermotor control digest the command.
225 
226  return FE_SUCCESS;
227 }
228 
229 /*------------------------------------------------------------------*/
236 void sm_no_connection(SM_INFO *info, INT value)
237 {
238  db_set_data(info->hDB, info->hkey_no_connection, &value, sizeof(value), 1, TID_INT);
239  if (value == 0) {
240  info->bd_connected = 1;
241  } else {
242  info->bd_connected = 0;
243  }
244 }
245 
246 /*------------------------------------------------------------------*/
257 {
258  char res[256];
259  char s[256];
260  int l_serial = 17;
261  int stat;
262 
263  if (info->bd_connected == 0) {
264  return -999;
265  }
266 
267  sprintf( s, "PRINT SER\r\n");
268  stat = sm_send_rcv(info, s, res); // get reponse
269 
270  if ( stat < 1 ) {
271  cm_msg(MERROR,"sm_check_serialnumber", "sm_check_serialnumber: no response, stat = %d", stat);
272  return 1;
273  }
274  cm_msg(MINFO,"sm_check_serialnumber", "sm_check_serialnumber: %s", res);
275 
276  if ((stat != l_serial) || (res[14] != 'A')) {
277  return 2;
278  }
279 
280  // set correct holding current
281  sprintf(s, "MHC=%e\r\n", info->sm_settings.individual[info->sm_in_use].mhc);
282  sm_send(info, s);
283  ss_sleep(100); // to leat the steppermotor control digest the command.
284 
285  return 0;
286 }
287 
288 /*------------------------------------------------------------------*/
296 {
297  char res[256];
298  char s[256];
299  int stat = 0;
300  float position = 9.999e+11;
301 
302  if (info->bd_connected == 0) {
303  return position;
304  }
305 
306  sprintf( s, "PRINT POS\r\n");
307  stat = sm_send_rcv(info, s, res);
308  if (stat > 0) {
309  position = atof(res);
310  }
311 
312  if (info->sm_settings.intern.detailed_msg) {
313  cm_msg(MINFO, "sm_read_position", "sm_read_position: position = %e", position );
314  }
315 
316  return position;
317 }
318 
319 /*------------------------------------------------------------------*/
327 {
328  char res[256];
329  char s[256];
330  int stat = 0;
331  float velocity = 9.999e+11;
332 
333  if (info->bd_connected == 0) {
334  return velocity;
335  }
336 
337  sprintf( s, "PRINT VM\r\n");
338  stat = sm_send_rcv(info, s, res);
339  if (stat > 0) {
340  velocity = atof(res);
341  }
342 
343  if (info->sm_settings.intern.detailed_msg) {
344  cm_msg(MINFO, "sm_read_velocity", "sm_read_velocity: velocity = %e", velocity );
345  }
346 
347  return velocity;
348 }
349 
350 
351 /*---- device driver routines --------------------------------------*/
362 INT sm_in_init(HNDLE hKey, void **pinfo, INT channels, INT (*bd)(INT cmd, ...))
363 {
364  INT status, i;
365  int size = sizeof(float);
366  HNDLE hDB, hkeydd;
367  float value;
368  int ivalue;
369  int isize = sizeof(int);
370 
371  cm_get_experiment_database(&hDB, NULL);
372 
373  // allocate info structure
374  info = calloc(1, sizeof(SM_INFO));
375  *pinfo = info;
376 
377  // create SM internal record
378  status = db_create_record(hDB, hKey, "DD/Internal", SM_INTERNAL_STR);
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);
381  cm_yield(0);
382  info->startup_error = 1;
383  return FE_SUCCESS;
384  }
385 
386  // find SM DD record
387  cm_msg(MINFO, "sm_in_init", "sm_in_init: start init, db_find_DD = %d",
388  db_find_key(hDB, hKey, "DD", &hkeydd));
389  cm_yield(0);
390  status = db_open_record(hDB, hkeydd, (void *)&info->sm_settings, sizeof(SM_SETTINGS), MODE_READ,
391  NULL, NULL);
392  if (status != DB_SUCCESS) {
393  cm_msg(MINFO, "sm_in_init", "sm_in_init: start init, open record DD = %d", status);
394  cm_yield(0);
395  info->startup_error = 1;
396  return FE_SUCCESS;
397  }
398 
399 
400  cm_msg(MINFO, "sm_in_init", "sm_in_init: read_back_device = %s", info->sm_settings.read_back_device);
401  cm_yield(0);
402 
403  if (strstr(info->sm_settings.read_back_device, "K2700")) { // reading voltage via K2700 channel C3
404  // allocate memory for data
405  info->data = (float *)malloc(SM_K2700_CH*sizeof(float));
406  if (info->data == NULL) {
407  cm_msg(MERROR, "sm_in_init", "sm_in_init: couldn't allocate data memory.");
408  cm_yield(0);
409  info->startup_error = 1;
410  return FE_SUCCESS;
411  }
412 
413  // open hot-links to LS340 raw voltage 5 (is channel C3)
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);
416 
417  info->signature = info->data[SM_K2700_SIG_CH];
418  info->sm_in_use = -1;
419 
420  for (i=0; i<5; i++) {
421  if (fabs( info->signature - info->sm_settings.individual[i].signature ) < 0.2) {
422  info->sm_in_use = i;
423  }
424  }
425 
426  if (info->sm_in_use >= 0) {
427  cm_msg(MINFO, "sm_in_init" ,"sm_in_init: You are using transferline %d ", info->sm_in_use);
428  cm_yield(0);
429  } else {
430  cm_msg(MINFO, "sm_in_init" ,"sm_in_init: No valid signature found" );
431  cm_yield(0);
432  info->startup_error = 1;
433  return FE_SUCCESS;
434  }
435 
436  info->voltage = info->data[SM_K2700_POT_CH];
437 
438  if (SM_DEBUG) {
439  cm_msg(MINFO, "sm_in_init" ,"sm_in_init: initial values : %e", info->voltage );
440  cm_yield(0);
441  }
442  } else if (strstr(info->sm_settings.read_back_device, "SCS900")) { // reading voltage via SCS-900, ADC1-2
443  // allocate memory for data
444  info->data = (float *)malloc(SM_SCS900_CH*sizeof(float));
445  if (info->data == NULL) {
446  cm_msg(MERROR, "sm_in_init", "sm_in_init: couldn't allocate data memory.");
447  cm_yield(0);
448  info->startup_error = 1;
449  return FE_SUCCESS;
450  }
451 
452  // open hot-links to SCS900 input
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);
455 
456  info->signature = info->data[SM_SCS900_SIG_CH];
457  info->sm_in_use = -1;
458 
459  for (i=0; i<5; i++) {
460  if (fabs( info->signature - info->sm_settings.individual[i].signature ) < 0.2) {
461  info->sm_in_use = i;
462  }
463  }
464 
465  if ( info->sm_in_use >= 0 ) {
466  cm_msg(MINFO, "sm_in_init" ,"sm_in_init: You are using transferline %d ", info->sm_in_use);
467  cm_yield(0);
468  } else {
469  cm_msg(MINFO, "sm_in_init" ,"sm_in_init: No valid signature found" );
470  cm_yield(0);
471  info->startup_error = 1;
472  return FE_SUCCESS;
473  }
474 
475  info->voltage = info->data[SM_SCS900_POT_CH];
476 
477  if (SM_DEBUG) {
478  cm_msg(MINFO, "sm_in_init" ,"sm_in_init: initial values : %e", info->voltage);
479  cm_yield(0);
480  cm_msg(MINFO, "sm_in_init", "sm_in_int: SCS900/Variables/Input %d ? %d, %e",
481  status, DB_SUCCESS, info->data[SM_SCS900_POT_CH]);
482  cm_yield(0);
483  }
484  } else if (strstr(info->sm_settings.read_back_device, "SCS2001M")) {
485  // allocate memory for data
486  info->data = (float *)malloc(SM_SCS2001M_CH*sizeof(float));
487  if (info->data == NULL) {
488  cm_msg(MERROR, "sm_in_init", "sm_in_init: couldn't allocate data memory.");
489  cm_yield(0);
490  info->startup_error = 1;
491  return FE_SUCCESS;
492  }
493 
494  // open hot-links to SCS2001M input
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);
497 
498  info->signature = info->data[SM_SCS2001M_SIG_CH];
499  info->sm_in_use = -1;
500 
501  for (i=0; i<5; i++) {
502  if (fabs( info->signature - info->sm_settings.individual[i].signature ) < 0.2) {
503  info->sm_in_use = i;
504  }
505  }
506 
507  if ( info->sm_in_use >= 0 ) {
508  cm_msg(MINFO, "sm_in_init" ,"sm_in_init: You are using transferline %d ", info->sm_in_use);
509  cm_yield(0);
510  } else {
511  cm_msg(MINFO, "sm_in_init" ,"sm_in_init: No valid signature found" );
512  cm_yield(0);
513  info->startup_error = 1;
514  return FE_SUCCESS;
515  }
516 
517  info->voltage = info->data[SM_SCS2001M_POT_CH];
518 
519  if (SM_DEBUG) {
520  cm_msg(MINFO, "sm_in_init" ,"sm_in_init: initial values : %e", info->voltage);
521  cm_yield(0);
522  cm_msg(MINFO, "sm_in_init", "sm_in_int: SCS2001M/Variables/Input %d ? %d, %e",
523  status, DB_SUCCESS, info->data[SM_SCS2001M_POT_CH]);
524  cm_yield(0);
525  }
526  } else { // neither K2700 nor SCS900
527  info->sm_in_use = -1; // read_back_device not found, so apparently steppermotor not 'in_use'
528  return FE_SUCCESS;
529  }
530 
531  // open hot-link to Needle_Valve(setpoint)
532  db_find_key(hDB, 0,"/Equipment/SampleCryo/Variables/Output", &hkeydd);
533  info->modus = 0; // default value
534  db_get_data_index(hDB, hkeydd, (void *)&value, &size, info->sm_settings.intern.odb_offset+1, TID_FLOAT);
535  info->modus = (int) value;
536 
537  // initialize "present setpoint from potmeter reading".
538  info->setpoint = sm_read_potmeter(info);
539 
540  cm_msg(MINFO,"sm_in_init", "sm_in_init: present setpoint = %e", info->setpoint);
541  cm_yield(0);
542 
543  size = sizeof(float);
544  db_get_data_index(hDB, hkeydd, (void *)&value, &size, info->sm_settings.intern.odb_offset, TID_FLOAT);
545  if (SM_DEBUG) {
546  cm_msg(MINFO,"sm_in_init","sm_in_init: Demand value = %e", value);
547  cm_yield(0);
548  }
549 
550  if (fabs( value - info->setpoint ) > SM_ACCURACY) {
551  cm_msg(MINFO,"sm_in_init", "sm_in_init: Will change demand value from %e to %e",
552  value, info->setpoint);
553  cm_yield(0);
554  db_set_data_index(hDB, hkeydd, (void *)&info->setpoint, sizeof(float), info->sm_settings.intern.odb_offset, TID_FLOAT);
555  }
556 
557  // initialize driver0
558  info->hDB = hDB;
559  info->hkey = hKey;
560  info->bd = bd;
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)");
564  info->startup_error = 0;
565  info->bd_connected = 0;
566  info->last_reconnect = ss_time();
567  info->first_bd_error = 1;
568  info->last_set_time = 0; // otherwise the first call to set fails (at initialization)
569 
570  // find bd connected dd entry
571  status = db_find_key(hDB, hKey, "DD/Internal/No Connection", &info->hkey_no_connection);
572 
573  if (!bd) {
574  cm_msg(MERROR, "sm_in_init" , "sm_in_init: couldn't establish the bus driver connection.");
575  cm_yield(0);
576  return FE_SUCCESS;
577  }
578 
579  if (SM_DEBUG) {
580  cm_msg(MINFO,"sm_in_init" , "sm_in_init: Found: DD/Internal/No Connection");
581  cm_yield(0);
582  }
583 
584  if (info->modus == 0) { // if modus is read-only stop here
585  return FE_SUCCESS;
586  }
587 
588  if (info->modus == 3) {
589  if (info->FromAutoPress == 0) {
590  // signal AutoPress to stop
591  db_find_key(info->hDB, info->hkey,"DD/ToAutoPress", &hkeydd);
592  ivalue = 1;
593  db_set_data(info->hDB, hkeydd, (void *)&ivalue, isize, 1, TID_INT);
594  status = 0;
595  // wait for AutoPress to answer
596  while ((status < 5) && (info->FromAutoPress == 0)) {
597  status = status + 1;
598  }
599  if (status < 5) {
600  cm_msg(MINFO,"sm_init","sm_init: Activated AutoPress");
601  cm_yield(0);
602  } else {
603  cm_msg(MINFO,"sm_init","sm_init: AutoPress could not be activated");
604  cm_yield(0);
605  }
606  } else {
607  cm_msg(MINFO,"sm_init","sm_init: AutoPress could not be activated, while it is not running");
608  cm_yield(0);
609  }
610  return FE_SUCCESS; // directly into PID, so stop here
611  }
612 
613  // initialize bus driver
614  status = info->bd(CMD_INIT, hKey, &info->bd_info);
615  if (status != FE_SUCCESS) {
616  info->startup_error = 1;
617  return status;
618  }
619 
620  if (info->sm_settings.intern.detailed_msg) {
621  cm_msg(MINFO,"sm_in_init", "sm_in_init: Bus driver initialized.");
622  cm_yield(0);
623  }
624 
625  // set bd connected flag in DD entry
626  sm_no_connection(info, 0);
627 
628  // check the serial_number and the maximum currents of the motor-drive.
629  // if NOT OK set no_connection TRUE so that no further commands will be send
630  status = check_serialnumber_and_maxima(info);
631  if (status != 0) {
632  cm_msg(MERROR, "sm_in_init", "sm_in_int: ERROR: check_serial_number_and_maxima = %d", status);
633  cm_yield(0);
634  info->startup_error = 1;
635  return FE_SUCCESS;
636  } else {
637  if (info->sm_settings.intern.detailed_msg) {
638  cm_msg(MINFO, "sm_in_init", "sm_in_int: INFO: check_serial_number_and_maxima = %d", status);
639  cm_yield(0);
640  }
641  }
642 
643 
644  // initialize present position
645  info->position = sm_read_position(info);
646 
647  if (info->sm_settings.intern.detailed_msg) {
648  cm_msg(MINFO,"sm_in_init", "sm_in_int: Initial position = %e", info->position);
649  cm_yield(0);
650  }
651 
652  // initialize maximum velocity
653  info->velocity = sm_read_velocity(info);
654 
655  if (info->sm_settings.intern.detailed_msg) {
656  cm_msg(MINFO,"sm_in_init", "sm_in_int: Initial velocity = %e", info->velocity);
657  cm_yield(0);
658  }
659 
660  return FE_SUCCESS;
661 }
662 
663 /*----------------------------------------------------------------------------*/
673 INT sm_out_init(HNDLE hKey, void **pinfo, INT channels, INT (*bd)(INT cmd, ...))
674 {
675  HNDLE hDB;
676 
677  cm_get_experiment_database(&hDB, NULL);
678 
679  *pinfo = info;
680 
681  return FE_SUCCESS;
682 }
683 
684 /*----------------------------------------------------------------------------*/
691 INT sm_set(SM_INFO *info, float setpoint)
692 {
693  char cmd[128], str[128];
694  float position, value, target;
695  int status, ii, delay;
696 
697  // check for startup error's, if present get out of here
698  if (info->startup_error) {
699  ss_sleep(10); // to keep CPU happy
700  return FE_SUCCESS;
701  }
702 
703  if (info->sm_settings.intern.detailed_msg) {
704  cm_msg(MINFO, "SM_set", "SM_set entered to set %f percent", setpoint);
705  }
706 
707  // if not in_use quit
708  if ((info->sm_in_use < 0) || (info->modus == 0) || (info->modus == 3)) {
709  return FE_SUCCESS;
710  }
711 
712  // check if they where too many reconnection failures
715  cm_msg(MERROR, "SM_set", "too many reconnection failures in sm_set, bailing out :-(");
716  info->reconnection_failures++;
717  }
718  return FE_SUCCESS;
719  }
720 
721  if (info->sm_settings.intern.scw_in_use) { // slowcontrol watchdog in use
722  // feed slowcontrol watchdog
723  info->scw.last_updated = ss_time();
724  lem_scw_update(&info->scw);
725  }
726 
727  // if disconnected, try to reconnect after a timeout
728  if (info->bd_connected == 0) {
729  if (ss_time()-info->last_reconnect > SM_RECONNECTION_TIMEOUT) { // timeout expired
730  if (info->sm_settings.intern.detailed_msg) {
731  cm_msg(MINFO, "SM_set", "Steppermotor: reconnection trial ...");
732  }
733  status = info->bd(CMD_INIT, info->hkey, &info->bd_info);
734  if (status != FE_SUCCESS) {
735  info->reconnection_failures++;
736  if (info->sm_settings.intern.detailed_msg)
737  cm_msg(MINFO, "SM_set", "Steppermotor: reconnection attempted failed");
738  return FE_SUCCESS;
739  } else {
740  info->bd_connected = 1; // bus driver is connected again
741  info->last_reconnect = ss_time();
742  info->reconnection_failures = 0;
743  info->first_bd_error = 1;
744  if (info->sm_settings.intern.detailed_msg) {
745  cm_msg(MINFO, "SM_get", "Steppermotor: successfully reconnected");
746  }
747  }
748  } else { // timeout still running
749  ss_sleep(10); // to keep CPU happy
750  return FE_SUCCESS;
751  }
752  }
753 
754  // if to quick after last set: do nothing for the impatient user
755  if ( ss_time() - info->last_set_time < SM_TIME_BETWEEN_SETS ) {
756  if (info->sm_settings.intern.detailed_msg) {
757  cm_msg(MINFO,"SM_set","SM_set: too less time between the set commands");
758  }
759  ss_sleep(10); // to keep CPU happy
760  return FE_SUCCESS;
761  }
762 
763  info->last_set_time = ss_time();
764 
765  value = sm_read_potmeter(info);
766 
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);
771  return FE_SUCCESS;
772  }
773 
774  if (info->sm_settings.intern.detailed_msg) {
775  cm_msg(MINFO,"sm_set", "sm_set: Changing the NeedleValve from %e to %e percent opening",
776  value, setpoint);
777  }
778 
779  if (fabs(value - info->setpoint) > SM_ACCURACY) {
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 !!",
782  info->setpoint, value );
783  cm_msg(MINFO, "sm_set", "sm_set: assuming %e to be correct !!", value );
784 //
785  sprintf( str, "Transferline_Needle_Valve has been changed manually ?");
786 // al_trigger_alarm("sm_set", str, "Warning", str, AT_INTERNAL);
787  info->setpoint = value;
788  }
789 
790  position = sm_read_position(info);
791 
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 !!");
796  info->position = 0.0;
797  }
798 
799 
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 !!",
803  info->position, position);
804  }
805  info->position = position;
806 
807 
808  // after all these checks finally come to business
809 
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);
814  return FE_SUCCESS;
815  }
816 
817  // set currents
818  if (setpoint > info->setpoint) { // opening valve
819  sprintf(cmd, "MAC=%f\r\n", info->sm_settings.individual[info->sm_in_use].mac_open);
820  sm_send(info, cmd);
821  sprintf(cmd, "MRC=%f\r\n", info->sm_settings.individual[info->sm_in_use].mrc_open);
822  sm_send(info, cmd);
823  } else {
824  sprintf(cmd, "MAC=%f\r\n", info->sm_settings.individual[info->sm_in_use].mac_close);
825  sm_send(info, cmd);
826  sprintf(cmd, "MRC=%f\r\n", info->sm_settings.individual[info->sm_in_use].mrc_close);
827  sm_send(info, cmd);
828  }
829 
830  // calculate relative movement in degrees
831  value = info->sm_settings.individual[info->sm_in_use].valve_range * ( (setpoint - info->setpoint) / 100.0 );
832  sprintf( cmd, "MOVR %f\r\n", value);
833  target = position + value;
834 
835  if (info->sm_settings.intern.detailed_msg) {
836  cm_msg(MINFO, "sm_set", "sm_set: Sending: %s", cmd);
837  }
838 
839  sm_send(info, cmd);
840 
841  // wait until ready
842 
843  // calculate waittime based on velocity and stap + 20 in untis of 0.5 second.
844  delay = 2 * (int) (fabs(value) / info->velocity) + 20;
845  ii = 0;
846  while ((ii < delay) && (fabs(target - sm_read_position(info)) > 5.0)) {
847  ss_sleep(500);
848  ii = ii + 1;
849  if (info->sm_settings.intern.detailed_msg) {
850  cm_msg(MINFO," sm_set","sm_set: needlvevalve moved to %.2f degrees in %.1f seconds reaching %.2f percent",
851  sm_read_position(info), (float) ii/2.0, target);
852  }
853  }
854 
855  if (ii < delay) {
856  info->position = sm_read_position(info);
857  if (info->sm_settings.intern.detailed_msg) {
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);
860  }
861  } else {
862  info->position = -9.9E+11;
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);
867  }
868 
869  info->setpoint = setpoint;
870 
871  return FE_SUCCESS;
872 }
873 
874 /*----------------------------------------------------------------------------*/
884 INT sm_get(SM_INFO *info, float *pvalue)
885 {
886  // check for startup error's, if present get out of here
887  if (info->startup_error) {
888  ss_sleep(10); // to keep CPU happy
889  return FE_SUCCESS;
890  }
891 
892  if (info->sm_in_use >= 0 ) {
893  *pvalue = sm_read_potmeter(info);
894  if ((*pvalue < -20.0) || (*pvalue > 120.0)) {
895  *pvalue = *pvalue - 1000.0;
896  }
897  } else {
898  *pvalue = -300.0;
899  }
900 
901  if (SM_DEBUG) {
902  cm_msg(MINFO, "sm_get", "sm_get: Getting value = %e", *pvalue);
903  }
904 
905  ss_sleep(10);
906 
907  return FE_SUCCESS;
908 }
909 
910 /*----------------------------------------------------------------------------*/
919  {
920  float value;
921 
922  if (strstr(info->sm_settings.read_back_device, "K2700")) {
923  info->voltage = info->data[SM_K2700_POT_CH];
924  } else if (strstr(info->sm_settings.read_back_device, "SCS900")) {
925  info->voltage = info->data[SM_SCS900_POT_CH];
926  } else if (strstr(info->sm_settings.read_back_device, "SCS2001M")) {
927  info->voltage = info->data[SM_SCS2001M_POT_CH];
928  }
929 
930  value = info->sm_settings.individual[info->sm_in_use].pcurve[0] +
931  info->sm_settings.individual[info->sm_in_use].pcurve[1] * info->voltage +
932  info->sm_settings.individual[info->sm_in_use].pcurve[2] * info->voltage * info->voltage;
933 
934  if (SM_DEBUG) {
935  cm_msg(MINFO, "sm_read_potmeter", "sm_read_potmeter: voltage = %e, value = %e", info->voltage, value);
936  }
937 
938  return value;
939  }
940 
941 
942 /*----------------------------------------------------------------------------------*/
951 INT sm_out_get_default_name(SM_INFO *info, INT channel, char *name)
952 {
953  if (channel == 0) {
954  strncpy(name, info->sm_out_name, sizeof(name));
955  }
956 
957  if (channel == 1) {
958  strncpy(name, info->sm_modus_name, sizeof(name));
959  }
960 
961  return FE_SUCCESS;
962 }
963 
964 /*----------------------------------------------------------------------------------*/
973 INT sm_in_get_default_name(SM_INFO *info, INT channel, char *name)
974 {
975  strncpy(name, info->sm_in_name, sizeof(name));
976  return FE_SUCCESS;
977 }
978 
979 /*----------------------------------------------------------------------------*/
987 INT sm_switch(SM_INFO *info, float floatmodus)
988 {
989  int status;
990  HNDLE hkeydd;
991  float value;
992  int ivalue;
993  int size = sizeof(float);
994  int isize = sizeof(int);
995  int modus;
996 
997  modus = (int) floatmodus;
998 
999  if (info->startup_error || info->sm_in_use < 0 ) {
1000  ss_sleep(10); // keeps the CPU happy
1001  return FE_SUCCESS;
1002  }
1003 
1004 
1005  // info->modus == 3 then deactivate AutoPress
1006  if ((info->modus == 3) && (info->FromAutoPress == 1)) {
1007  // signal AutoPress to stop
1008  db_find_key(info->hDB, info->hkey,"DD/ToAutoPress", &hkeydd);
1009  ivalue = 0;
1010  db_set_data(info->hDB, hkeydd, (void *)&ivalue, sizeof(ivalue), 1, TID_INT);
1011  status = 0;
1012  // wait for AutoPress to answer
1013  while ((status < 5) && (info->FromAutoPress > 0)) {
1014  status = status + 1;
1015  }
1016  if ( status < 5 ) {
1017  cm_msg(MINFO,"sm_switch","sm_switch: Deactivated AutoPress");
1018  } else {
1019  cm_msg(MINFO,"sm_switch","sm_switch: AutoPress could not be deactivated");
1020  }
1021  }
1022 
1023  // Steppermotor should go to read_only mode
1024  if (modus == 0) {
1025  switch (info->modus) {
1026  case 1 :
1027  cm_msg(MINFO,"sm_switch","sm_switch: Setting steppermotor from read-write to read-only");
1028  break;
1029  case 2 :
1030  cm_msg(MINFO,"sm_switch","sm_switch: Setting steppermotor from auto to read-only");
1031  break;
1032  case 3 :
1033  cm_msg(MINFO,"sm_switch","sm_switch: Setting steppermotor from PID to read-only");
1034  break;
1035  default:
1036  break;
1037  }
1038 
1039  // disconnect bus (if info->modus == 3 it should already be disconnected, but anyway
1040  if (info->bd_connected) {
1041  info->bd(CMD_EXIT, info->bd_info);
1042  }
1043  sm_no_connection(info, 1);
1044  } // end of modus = 0
1045 
1046 
1047  // Steppermotor should go from read_only or PID to write or auto
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");
1057 
1058  // open hot-link to Needle_Valve(setpoint)
1059  db_find_key(info->hDB, 0,"/Equipment/SampleCryo/Variables/Output", &hkeydd);
1060 
1061  // initialize "present setpoint from potmeter reading".
1062  info->setpoint = sm_read_potmeter(info);
1063 
1064  cm_msg(MINFO,"sm_switch", "sm_switch: present setpoint = %e", info->setpoint);
1065 
1066  size = sizeof(float);
1067  db_get_data_index(info->hDB, hkeydd, (void *)&value, &size, info->sm_settings.intern.odb_offset, TID_FLOAT);
1068  if (SM_DEBUG) cm_msg(MINFO,"sm_switch","sm_switch: Demand value = %e", value);
1069 
1070  if ( fabs( value - info->setpoint ) > SM_ACCURACY ) {
1071  cm_msg(MINFO,"sm_in_switch", "sm_switch: Will change demand value from %e to %e",
1072  value, info->setpoint);
1073  db_set_data_index(info->hDB, hkeydd, (void *)&info->setpoint, sizeof(float), info->sm_settings.intern.odb_offset, TID_FLOAT);
1074  }
1075 
1076  // initialize bus driver
1077  status = info->bd(CMD_INIT, info->hkey, &info->bd_info);
1078  if (status != FE_SUCCESS) {
1079  info->startup_error = 1;
1080  return status;
1081  }
1082 
1083  if (info->sm_settings.intern.detailed_msg) {
1084  cm_msg(MINFO,"sm_switch", "sm_switch: Bus driver initialized.");
1085  }
1086 
1087  // set bd connected flag in DD entry
1088  sm_no_connection(info, 0);
1089 
1090  // check the serial_number and the maximum currents of the motor-drive.
1091  // if NOT OK set no_connection TRUE so that no further commands will be send
1092  status = check_serialnumber_and_maxima(info);
1093  if ( status != 0 ) {
1094  cm_msg(MERROR, "sm_switch", "sm_switch: ERROR: check_serial_number_and_maxima = %d", status);
1095  info->startup_error = 1;
1096  return FE_SUCCESS;
1097  } else {
1098  if (info->sm_settings.intern.detailed_msg)
1099  cm_msg(MINFO,
1100  "sm_switch", "sm_switch: INFO: check_serial_number_and_maxima = %d", status);
1101  }
1102 
1103 
1104  // initialize present position
1105  info->position = sm_read_position(info);
1106 
1107  if (info->sm_settings.intern.detailed_msg) {
1108  cm_msg(MINFO,"sm_switch", "sm_switch: Initial position = %e", info->position);
1109  }
1110 
1111  // initialize maximum velocity
1112  info->velocity = sm_read_velocity(info);
1113 
1114  if (info->sm_settings.intern.detailed_msg) {
1115  cm_msg(MINFO,"sm_switch", "sm_switch: Initial velocity = %e", info->velocity);
1116  }
1117 
1118  } // end of modus = 1 or modus = 2
1119 
1120  // Steppermotor should go from auto to read-write
1121  if ((info->modus == 2) && (modus == 1)) {
1122  cm_msg(MINFO,"sm_switch","sm_switch: Setting steppermotor from auto to read-write");
1123  }
1124 
1125  // Steppermotor should go from read-write to auto
1126  if ((info->modus == 1) && (modus == 2)) {
1127  cm_msg(MINFO,"sm_switch","sm_switch: Setting steppermotor from read-write to auto");
1128  }
1129 
1130 
1131  // modus == 3 then activate AutoPress
1132  if (modus == 3) {
1133  // disconnect bus (if info->modus == 0 it should already be disconnected, but anyway
1134  if (info->bd_connected) {
1135  info->bd(CMD_EXIT, info->bd_info);
1136  }
1137  sm_no_connection(info, 1);
1138 
1139  if (info->FromAutoPress == 0) {
1140  // signal AutoPress to stop
1141  db_find_key(info->hDB, info->hkey,"DD/ToAutoPress", &hkeydd);
1142  ivalue = 1;
1143  db_set_data(info->hDB, hkeydd, (void *)&ivalue, isize, 1, TID_INT);
1144  status = 0;
1145  // wait for AutoPress to answer
1146  while ((status < 5) && (info->FromAutoPress == 0))
1147  status = status + 1;
1148  if (status < 5) {
1149  cm_msg(MINFO,"sm_switch","sm_switch: Activated AutoPress");
1150  } else {
1151  cm_msg(MINFO,"sm_switch","sm_switch: AutoPress could not be activated");
1152  }
1153  } else {
1154  cm_msg(MINFO,"sm_switch","sm_switch: AutoPress could not be activated, while it is not running");
1155  }
1156  }
1157 
1158  info->modus = modus;
1159  return FE_SUCCESS;
1160 }
1161 
1162 
1163 /*----------------------------------------------------------------------------*/
1170 INT sm_exit(SM_INFO *info)
1171 {
1172  // call EXIT function of bus driver, usually closes device
1173  if (info->bd_connected) {
1174  info->bd(CMD_EXIT, info->bd_info);
1175  }
1176 
1177  free(info->data);
1178  free(info);
1179 
1180  return FE_SUCCESS;
1181 }
1182 
1183 
1184 
1185 /*---- device driver entry point -----------------------------------*/
1186 INT SM_in(INT cmd, ...)
1187 {
1188  va_list argptr;
1189  HNDLE hKey;
1190  INT channel, status;
1191  float *pvalue;
1192  void *info, *bd;
1193  char *name;
1194  DWORD flags;
1195 
1196  va_start(argptr, cmd);
1197  status = FE_SUCCESS;
1198 
1199  switch (cmd) {
1200  case CMD_INIT:
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);
1207  break;
1208 
1209  case CMD_EXIT:
1210  info = va_arg(argptr, void *);
1211  status = sm_exit(info);
1212  break;
1213 
1214  case CMD_GET:
1215  info = va_arg(argptr, void *);
1216  channel = va_arg(argptr, INT);
1217  pvalue = va_arg(argptr, float*);
1218  status = sm_get(info, pvalue);
1219  break;
1220 
1221  case CMD_GET_LABEL:
1222  info = va_arg(argptr, void *);
1223  channel = va_arg(argptr, INT);
1224  name = va_arg(argptr, char *);
1225  status = sm_in_get_default_name(info, channel, name);
1226  break;
1227 
1228  default:
1229  break;
1230  }
1231 
1232  va_end(argptr);
1233  return status;
1234 }
1235 
1236 INT SM_out(INT cmd, ...)
1237 {
1238  va_list argptr;
1239  HNDLE hKey;
1240  INT channel, status;
1241  float value;
1242  void *info, *bd;
1243  char *name;
1244  DWORD flags;
1245 
1246  va_start(argptr, cmd);
1247  status = FE_SUCCESS;
1248 
1249  switch (cmd) {
1250  case CMD_INIT:
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 *);
1256  status = sm_out_init(hKey, info, channel, bd);
1257  break;
1258 
1259  case CMD_SET:
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);
1265  break;
1266 
1267  case CMD_GET_LABEL:
1268  info = va_arg(argptr, void *);
1269  channel = va_arg(argptr, INT);
1270  name = va_arg(argptr, char *);
1271  status = sm_out_get_default_name(info, channel, name);
1272  break;
1273 
1274  default:
1275  break;
1276  }
1277 
1278  va_end(argptr);
1279 
1280  return status;
1281 }
1282 
INT reconnection_failures
how many reconnection failures took place
Definition: steppermotor.c:134
#define SM_ACCURACY
condition for alarm on manual changes
Definition: steppermotor.c:35
#define SM_K2700_SIG_CH
Definition: steppermotor.c:58
int first_bd_error
flag showing if the bus driver error message is already given
Definition: steppermotor.c:132
float mrc_open
maximum steady current on opening the valve
Definition: steppermotor.c:96
INT sm_switch(SM_INFO *info, float floatmodus)
Definition: steppermotor.c:987
INT ets_in_use
flag indicating if the rs232 terminal server is in use
Definition: steppermotor.c:71
float sm_read_potmeter(SM_INFO *info)
Definition: steppermotor.c:918
INT sm_send_rcv(SM_INFO *info, char *cmd, char *str)
Definition: steppermotor.c:162
float sm_read_position(SM_INFO *info)
Definition: steppermotor.c:295
INT SM_in(INT cmd,...)
#define SM_K2700_POT_CH
Definition: steppermotor.c:59
DWORD last_set_time
time at the last setting of the valve
Definition: steppermotor.c:135
float position
prevailing position (filled by sm_in_init
Definition: steppermotor.c:138
#define SM_K2700_CH
Definition: steppermotor.c:57
char read_back_device[NAME_LENGTH]
device used to read the potentiometer, K2700 or SCS900
Definition: steppermotor.c:105
INT no_connection
flag showing that there is no connection at the moment
Definition: steppermotor.c:73
#define SM_SCS900_POT_CH
Definition: steppermotor.c:62
INT sm_exit(SM_INFO *info)
INT sm_out_init(HNDLE hKey, void **pinfo, INT channels, INT(*bd)(INT cmd,...))
Definition: steppermotor.c:673
float mac_open
maximum accelaration current on opening the valve
Definition: steppermotor.c:94
#define SM_RECONNECTION_TIMEOUT
timeout in (sec) between logout terminal server an reconnection trial
Definition: steppermotor.c:40
#define SM_TIME_BETWEEN_SETS
minimum time between settings of steppermotor to allow odb updates
Definition: steppermotor.c:34
char sm_in_name[NAME_LENGTH]
Definition: steppermotor.c:123
float valve_range
total number of degrees that the valve cvan turn
Definition: steppermotor.c:92
#define SM_WAIT
time (ms) to wait between commands
Definition: steppermotor.c:50
#define SM_SCS2001M_CH
Definition: steppermotor.c:63
#define SM_MAX_TRY
maximum number of communication attempts
Definition: steppermotor.c:49
INT sm_send(SM_INFO *info, char *cmd)
Definition: steppermotor.c:211
float voltage
voltage over the potentiometer
Definition: steppermotor.c:140
int check_serialnumber_and_maxima(SM_INFO *info)
Definition: steppermotor.c:256
INT sm_in_get_default_name(SM_INFO *info, INT channel, char *name)
Definition: steppermotor.c:973
char sm_out_name[NAME_LENGTH]
Definition: steppermotor.c:124
INT scw_in_use
flag indicating if the slowcontrol watchdog shall be used
Definition: steppermotor.c:72
INFO info
Definition: analyzer.cxx:94
int FromAutoPress
ODB map of NeedleValve/DD/FromAutoPress.
Definition: steppermotor.c:142
INT sm_get(SM_INFO *info, float *pvalue)
Definition: steppermotor.c:884
int sm_in_use
flag signalling &#39;in use&#39; of the steppermotor
Definition: steppermotor.c:129
INT sm_set(SM_INFO *info, float setpoint)
Definition: steppermotor.c:691
void sm_no_connection(SM_INFO *info, INT value)
Definition: steppermotor.c:236
#define SM_DEBUG
debug tag, if set to TRUE, additional messages will be displayed at execution time ...
Definition: steppermotor.c:55
INT startup_error
startup error tag
Definition: steppermotor.c:128
INT SM_out(INT cmd,...)
#define SM_MAX_RECONNECTION_FAILURE
maximum number of reconnections before bailing off
Definition: steppermotor.c:44
float signature
signature of the steppermotor
Definition: steppermotor.c:136
INT read_timeout
get data every read_timeout (sec), if zero midas has the timing control
Definition: steppermotor.c:75
int modus
modus: readonly = 0, readwrite = 1, auto = 2, PID = 3
Definition: steppermotor.c:130
stores internal informations within the DD.
Definition: steppermotor.c:104
void * bd_info
private info of bus driver
Definition: steppermotor.c:127
float mhc
maximum holding current
Definition: steppermotor.c:93
INT ToAutoPress
handshake to auto pressure program
Definition: steppermotor.c:108
float setpoint
prevailing setpoint
Definition: steppermotor.c:137
float velocity
maximum velocity of the motor
Definition: steppermotor.c:139
SM_INDIVIDUAL individual[5]
parameters for each steppermotor
Definition: steppermotor.c:110
float mac_close
maximum accelaration current on closing the valve
Definition: steppermotor.c:95
#define SM_SCS2001M_SIG_CH
Definition: steppermotor.c:64
int bd_connected
flag showing if bus driver is connected
Definition: steppermotor.c:131
#define SM_SCS900_SIG_CH
Definition: steppermotor.c:61
float signature
(unique) voltage read from line 3 of the transferline
Definition: steppermotor.c:98
HNDLE hKey
char sm_modus_name[NAME_LENGTH]
Definition: steppermotor.c:125
INT FromAutoPress
handshake from auto pressure program
Definition: steppermotor.c:107
HNDLE hkey
handle to the BD key
Definition: steppermotor.c:121
INT odb_offset
what is the odb offset of the DD. Needed for absolut addressing of the ODB
Definition: steppermotor.c:69
stores internal information
Definition: steppermotor.c:68
float mrc_close
maximum steady current on closing the valve
Definition: steppermotor.c:97
HNDLE hDB
main handle to the ODB
Definition: steppermotor.c:120
#define SM_SCS2001M_POT_CH
Definition: steppermotor.c:65
INT sm_out_get_default_name(SM_INFO *info, INT channel, char *name)
Definition: steppermotor.c:951
HNDLE hDB
structure to store information on individual steppermotor
Definition: steppermotor.c:89
#define SM_TIME_OUT
time out in msecs for read (rs232)
Definition: steppermotor.c:33
INT(* bd)(INT cmd,...)
bus driver entry function
Definition: steppermotor.c:126
float sm_read_velocity(SM_INFO *info)
Definition: steppermotor.c:326
INT sm_in_init(HNDLE hKey, void **pinfo, INT channels, INT(*bd)(INT cmd,...))
Definition: steppermotor.c:362
float pcurve[3]
Definition: steppermotor.c:90
#define SM_INTERNAL_STR
initializing string for SM_INTERNAL
Definition: steppermotor.c:79
INT reconnect_timeout
reconnection timeout in (sec)
Definition: steppermotor.c:74
SM_INTERNAL intern
internal data for device driver
Definition: steppermotor.c:106
SM_SETTINGS sm_settings
ODB data etc.
Definition: steppermotor.c:118
HNDLE hkey_no_connection
handle to the no connection flag
Definition: steppermotor.c:122
LEM_SC_WATCHDOG scw
slowcontrol watchdog info structure
Definition: steppermotor.c:119
INT detailed_msg
flag indicating if detailed status/error messages are wanted
Definition: steppermotor.c:70
DWORD last_reconnect
timer for bus driver reconnect error
Definition: steppermotor.c:133
#define SM_SCS900_CH
Definition: steppermotor.c:60
float * data
pointer to data to obtain TFL signature and pot.meter reading
Definition: steppermotor.c:141