EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: how to put value to other record in subroutine record
From: Emmanuel Mayssat <[email protected]>
To: marco_hair <[email protected]>, tech-talk <[email protected]>
Date: Mon, 21 Oct 2013 14:41:30 -0700
This is the code for a gensub record (asub record are said to be 100% compatible with gensub)
Here is the code for a simple status code translation
Note that the asub and gensub have input and output records
In the example below:
1/ read the input (status code)
2/ write output (status string)


record(genSub,      "$(deviceName)$(_)StsGS") {
    field(DESC, "Status Translator")
    field(SCAN, "Passive")
    field(SCAN, "1 second")
    field(INAM, "")
    field(SNAM, "SNOVA_funcTranslateStatusCodes")
    #field(SNAM, "SNOVA_funcIdle")
    field(EFLG, "ON CHANGE")
    #--- input
    field(INPA, "$(deviceName)$(_)Main$(_)StsLI")
    field(FTA,  "LONG")
    field(UFA,  "")
    field(NOA,  "1")
    field(INPB, "$(deviceName)$(_)HighVltg$(_)StsLI")
    field(FTB,  "LONG")
    field(UFB,  "")
    field(NOB,  "1")
    field(INPC, "$(deviceName)$(_)Flmnt$(_)StsLI")
    field(FTC,  "LONG")
    field(UFC,  "")
    field(NOC,  "1")
    field(INPD, "$(deviceName)$(_)Cmnctn$(_)StsLI")
    field(FTD,  "LONG")
    field(UFD,  "")
    field(NOD,  "1")
    field(INPE, "$(deviceName)$(_)Reset$(_)StsLI")
    field(FTE,  "LONG")
    field(UFE,  "")
    field(NOE,  "1")
    field(INPF, "$(deviceName)$(_)Mode$(_)StsLI")
    field(FTF,  "LONG")
    field(UFF,  "")
    field(NOF,  "1")
    #gensub counter
    field(INPU, "$(deviceName)$(_)StsGS NPP NMS")
    field(FTU,  "LONG")
    field(NOU,  "1")
    field(UFU,  "")
    #--- ouput
    field(OUTA, "$(deviceName)$(_)Main$(_)StsSI PP")
    field(FTVA, "STRING")
    field(NOVA, "40")
    field(OUTB, "$(deviceName)$(_)HighVltg$(_)StsSI PP")
    field(FTVB, "STRING")
    field(NOVB, "40")
    field(OUTC, "$(deviceName)$(_)Flmnt$(_)StsSI PP")
    field(FTVC, "STRING")
    field(NOVC, "40")
    field(OUTD, "$(deviceName)$(_)Cmnctn$(_)StsSI PP")
    field(FTVD, "STRING")
    field(NOVD, "40")
    field(OUTE, "$(deviceName)$(_)Reset$(_)StsSI PP")
    field(FTVE, "STRING")
    field(NOVE, "40")
    field(OUTF, "$(deviceName)$(_)Mode$(_)StsSI PP")
    field(FTVF, "STRING")
    field(NOVF, "40")
    field(OUTG, "$(deviceName)$(_)WrnngBI PP")
    field(FTVG, "SHORT")
    field(NOVG, "1")
    field(OUTH, "$(deviceName)$(_)AlarmBI PP")
    field(FTVH, "SHORT")
    field(NOVH, "1")
}


#include <math.h>
#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

#include "dbCommon.h"
#include "dbDefs.h"
#include "dbEvent.h"
#include "epicsExport.h"
#include "genSubRecord.h"
#include "recSup.h"
#include "registryFunction.h"

#define SUCCESS 0
#define ERROR -1
#define BUFLEN 40

int SNOVA_funcTranslateStatusCodes_LOG=1;
epicsExportAddress(int, SNOVA_funcTranslateStatusCodes_LOG);

/*----------------------------------------------------------------------*/
static int funcLog(int logLevel, const char *format, ...) {
  va_list args;
  if (    (SNOVA_funcTranslateStatusCodes_LOG % logLevel ) == 0  ) {
     va_start(args, format);
     vfprintf(stderr, format, args);
     va_end(args);
  }
  return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateMainStatus(long mainStatusLI, char *p_mainStatusSI) {
  switch(mainStatusLI) {
    case 1: strncpy(p_mainStatusSI,"HV-TankOpen interlock",40); break;
    case 2: strncpy(p_mainStatusSI,"HV-Temp interlock",40); break;
    case 3: strncpy(p_mainStatusSI,"HV-Oil level interlock",40); break;
    case 4: strncpy(p_mainStatusSI,"HV-Pressure interlock",40); break;
    case 5: strncpy(p_mainStatusSI,"HV-DCPS interlock",40); break;
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
    case 16:
    case 17: strncpy(p_mainStatusSI,"HV-IGBT interlock",40); break;
    case 18: strncpy(p_mainStatusSI,"HV-Voltage interlock",40); break;
    case 19: strncpy(p_mainStatusSI,"HV-Spark interlock",40); break;
    case 20: strncpy(p_mainStatusSI,"HV-Power exceeded interlock",40); break;
    case 21: strncpy(p_mainStatusSI,"HV-DcReset interlock",40); break;
    case 22: strncpy(p_mainStatusSI,"Communication interlock",40); break;
    case 23: strncpy(p_mainStatusSI,"Spark interlock",40); break;
    case 24: strncpy(p_mainStatusSI,"Power exceeded interlock",40); break;
    case 25: strncpy(p_mainStatusSI,"SafetyBus interlock",40); break;
    case 26: strncpy(p_mainStatusSI,"Waterflow interlock",40); break;
    case 27:
    case 99: strncpy(p_mainStatusSI,"HV-Spare",40); break;
    case 100: strncpy(p_mainStatusSI,"Temp interlock",40); break;
    case 101: strncpy(p_mainStatusSI,"LoOil interlock",40); break;
    case 102: strncpy(p_mainStatusSI,"HiOil interlock",40); break;
    case 103: strncpy(p_mainStatusSI,"FilVolt interlock",40); break;
    case 104: strncpy(p_mainStatusSI,"FilCurr interlock",40); break;
    case 105: strncpy(p_mainStatusSI,"Waterflow interlock",40); break;
    case 106:
    case 199: strncpy(p_mainStatusSI,"Spare",40); break;
    case 1000: strncpy(p_mainStatusSI,"Off",40); break;
    case 2000: strncpy(p_mainStatusSI,"Cooling down...",40); break;
    case 7000: strncpy(p_mainStatusSI,"Warming up...",40); break;
    case 7001: strncpy(p_mainStatusSI,"Warm",40); break;
    case 8000: strncpy(p_mainStatusSI,"HV On",40); break;
    case 8001: strncpy(p_mainStatusSI,"HV Trig",40); break;
    default: strncpy(p_mainStatusSI,"Unknown status",40); break;
  }
  return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateHighVoltageStatus(
                long highVoltageStatusLI, char *p_highVoltageStatusSI) {
  switch(highVoltageStatusLI) {
    case 1: strncpy(p_highVoltageStatusSI,"OilTemp interlock",40); break;
    case 2: strncpy(p_highVoltageStatusSI,"LoOilLevel interlock",40); break;
    case 3: strncpy(p_highVoltageStatusSI,"HiOilLevel interlock",40); break;
    case 4: strncpy(p_highVoltageStatusSI,"Dcps interlock",40); break;
    case 5: strncpy(p_highVoltageStatusSI,"DcpsVoltage interlock",40); break;
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
    case 16:
    case 17: strncpy(p_highVoltageStatusSI,"Lgbt interlock",40); break;
    case 18: strncpy(p_highVoltageStatusSI,"Load Current interlock",40); break;
    case 19: strncpy(p_highVoltageStatusSI,"Load Voltage interlock",40); break;
    case 20: strncpy(p_highVoltageStatusSI,"DcResetCurr interlock",40); break;
    case 21: strncpy(p_highVoltageStatusSI,"DcResetVltg interlock",40); break;
    case 22: strncpy(p_highVoltageStatusSI,"Communication interlock",40); break;
    case 23: strncpy(p_highVoltageStatusSI,"Spark interlock",40); break;
    case 24: strncpy(p_highVoltageStatusSI,"Power exceed interlock",40); break;
    case 25: strncpy(p_highVoltageStatusSI,"SafetyBus interlock",40); break;
    case 26: strncpy(p_highVoltageStatusSI,"Waterflow interlock",40); break;
    case 27:
    case 98: strncpy(p_highVoltageStatusSI,"Spare",40); break;
    case 1000: strncpy(p_highVoltageStatusSI,"Off",40); break;
    case 1001: strncpy(p_highVoltageStatusSI,"HV-Cnd",40); break;
    case 2000: strncpy(p_highVoltageStatusSI,"Off requested",40); break;
    case 7000: strncpy(p_highVoltageStatusSI,"On requested",40); break;
    case 7001: strncpy(p_highVoltageStatusSI,"Ramp up HV",40); break;
    case 8000: strncpy(p_highVoltageStatusSI,"HV on",40); break;
    case 8001: strncpy(p_highVoltageStatusSI,"HV trig",40); break;
    default: strncpy(p_highVoltageStatusSI,"Unknown",40);
  }
  return(SUCCESS);
}
   
/*----------------------------------------------------------------------*/
static int translateFilamentStatus(long filamentStatusLI, char *p_filamentStatusSI) {
  switch(filamentStatusLI) {
    case 100: strncpy(p_filamentStatusSI,"Temp interlock",40); break;
    case 101: strncpy(p_filamentStatusSI,"LoOil interlock",40); break;
    case 102: strncpy(p_filamentStatusSI,"HiOil interlock",40); break;
    case 103: strncpy(p_filamentStatusSI,"FilVolt interlock",40); break;
    case 104: strncpy(p_filamentStatusSI,"FilCurr interlock",40); break;
    case 105: strncpy(p_filamentStatusSI,"Waterflow interlock",40); break;
    case 106:
    case 198: strncpy(p_filamentStatusSI,"Spare",40); break;
    case 199: strncpy(p_filamentStatusSI,"Fault",40); break;
    case 1000: strncpy(p_filamentStatusSI,"Off",40); break;
    case 1001: strncpy(p_filamentStatusSI,"FilPs-Cnd",40); break;
    case 2000: strncpy(p_filamentStatusSI,"Off requested",40); break;
    case 7000: strncpy(p_filamentStatusSI,"On requested",40); break;
    case 7001: strncpy(p_filamentStatusSI,"Preheating (0min)",40); break;
    case 7002: strncpy(p_filamentStatusSI,"Preheating (1min)",40); break;
    case 7003: strncpy(p_filamentStatusSI,"Preheating (2min)",40); break;
    case 7004: strncpy(p_filamentStatusSI,"Preheating (3min)",40); break;
    case 7005: strncpy(p_filamentStatusSI,"Preheating (4min)",40); break;
    case 7006: strncpy(p_filamentStatusSI,"Preheating (5min)",40); break;
    case 7007: strncpy(p_filamentStatusSI,"Preheating (6min)",40); break;
    case 7008: strncpy(p_filamentStatusSI,"Preheating (7min)",40); break;
    case 7009: strncpy(p_filamentStatusSI,"Preheating (8min)",40); break;
    case 7010: strncpy(p_filamentStatusSI,"Preheating (9min)",40); break;
    case 7011: strncpy(p_filamentStatusSI,"Preheating (10min)",40); break;
    case 7012: strncpy(p_filamentStatusSI,"Preheating (11min)",40); break;
    case 7013: strncpy(p_filamentStatusSI,"Preheating (12min)",40); break;
    case 7014: strncpy(p_filamentStatusSI,"Preheating (13min)",40); break;
    case 7015: strncpy(p_filamentStatusSI,"Preheating (14min)",40); break;
    case 7016: strncpy(p_filamentStatusSI,"Preheating (15min)",40); break;
    case 8000: strncpy(p_filamentStatusSI,"On",40); break;
    default: strncpy(p_filamentStatusSI,"Unknown Filament",40);
  }
  return(SUCCESS);
}

/*----------------------------------------------------------------------*/
static int translateCommunicationStatus(long communicationStatusLI, char *p_communicationStatusSI) {
  switch(communicationStatusLI) {
    case 1: strncpy(p_communicationStatusSI,"Communication interlock",40); break;
    case 1000: strncpy(p_communicationStatusSI,"Off",40); break;
    case 8000: strncpy(p_communicationStatusSI,"Ok",40); break;
    case 8001: strncpy(p_communicationStatusSI,"One missed reply",40); break;
    case 8002: strncpy(p_communicationStatusSI,"Two missed reply",40); break;
    case 8003: strncpy(p_communicationStatusSI,"Three missed reply",40); break;
    case 8004: strncpy(p_communicationStatusSI,"Four missed reply",40); break;
    default: strncpy(p_communicationStatusSI,"Unknown Com",40);
  }
  return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateResetStatus(long resetStatusLI, char *p_resetStatusSI) {
  switch(resetStatusLI) {
    case 1000: strncpy(p_resetStatusSI,"Off",40); break;
    case 7000: strncpy(p_resetStatusSI,"Reset requested",40); break;
    case 8000: strncpy(p_resetStatusSI,"Resetting",40); break;
    default: strncpy(p_resetStatusSI,"Unknown Reset",40);
  }
  return(SUCCESS);
}
/*----------------------------------------------------------------------*/
static int translateModeStatus(long modeStatusLI, char *p_modeStatusSI) {
  switch(modeStatusLI) {
    case 0: strncpy(p_modeStatusSI,"Off",40); break;
    case 1: strncpy(p_modeStatusSI,"Status 1",40); break;
    case 2: strncpy(p_modeStatusSI,"Status 2",40); break;
    case 3: strncpy(p_modeStatusSI,"Status 3",40); break;
    case 4: strncpy(p_modeStatusSI,"Ready",40); break;
    default: strncpy(p_modeStatusSI,"Unknown Mode",40);
  }
  return(SUCCESS);
}

/*----------------------------------------------------------------------*/
static long SNOVA_funcTranslateStatusCodes( struct genSubRecord *p_gensub ) {
  long mainStatusLI;
  long highVoltageStatusLI;
  long filamentStatusLI;
  long communicationStatusLI;
  long resetStatusLI;
  long modeStatusLI;
  char p_mainStatusSI[BUFLEN];
  char p_highVoltageStatusSI[BUFLEN];
  char p_filamentStatusSI[BUFLEN];
  char p_communicationStatusSI[BUFLEN];
  char p_resetStatusSI[BUFLEN];
  char p_modeStatusSI[BUFLEN];
  long *p_counter;
  short alarmBI;
  short warningBI;

  funcLog( 3, __FILE__ "[%d] --> %s (%s)\n",
                  __LINE__, __func__, p_gensub->name);

  mainStatusLI=*(long *)p_gensub->a;
  translateMainStatus(mainStatusLI,p_mainStatusSI);
  memcpy(p_gensub->vala, p_mainStatusSI, BUFLEN*sizeof(char));

  highVoltageStatusLI=*(long *)p_gensub->b;
  translateHighVoltageStatus(highVoltageStatusLI,p_highVoltageStatusSI);
  memcpy(p_gensub->valb, p_highVoltageStatusSI, BUFLEN*sizeof(char));

  filamentStatusLI=*(long *)p_gensub->c;
  translateFilamentStatus(filamentStatusLI,p_filamentStatusSI);
  memcpy(p_gensub->valc, p_filamentStatusSI, BUFLEN*sizeof(char));

  communicationStatusLI=*(long *)p_gensub->d;
  translateCommunicationStatus(communicationStatusLI,p_communicationStatusSI);
  memcpy(p_gensub->vald, p_communicationStatusSI, BUFLEN*sizeof(char));

  resetStatusLI=*(long *)p_gensub->e;
  translateResetStatus(resetStatusLI,p_resetStatusSI);
  memcpy(p_gensub->vale, p_resetStatusSI, BUFLEN*sizeof(char));

  modeStatusLI=*(long *)p_gensub->f;
  translateModeStatus(modeStatusLI,p_modeStatusSI);
  memcpy(p_gensub->valf, p_modeStatusSI, BUFLEN*sizeof(char));

  alarmBI=0;
  warningBI=0;
  if (mainStatusLI<200) {
   alarmBI=0;
   warningBI=1;
  }
  memcpy(p_gensub->valg, &warningBI, sizeof(short));
  memcpy(p_gensub->valh, &alarmBI, sizeof(short));

  funcLog( 5, __FILE__ "[%d] %s\n", __LINE__, p_gensub->name);
  funcLog( 5, __FILE__ "[%d] mainStatusSI         = >%s< (%d)\n",
                                __LINE__, p_gensub->vala, mainStatusLI);
  funcLog( 5, __FILE__ "[%d] highVoltageStatusSI  = >%s< (%d)\n",
                                __LINE__, p_gensub->valb, highVoltageStatusLI);
  funcLog( 5, __FILE__ "[%d] filamentStatusSI     = >%s< (%d)\n",
                                __LINE__, p_gensub->valc, filamentStatusLI);
  funcLog( 5, __FILE__ "[%d] communicationStatusSI= >%s< (%d)\n",
                                __LINE__, p_gensub->vald, communicationStatusLI);
  funcLog( 5, __FILE__ "[%d] resetStatusSI        = >%s< (%d)\n",
                                __LINE__, p_gensub->vale, resetStatusLI);
  funcLog( 5, __FILE__ "[%d] modeStatusSI         = >%s< (%d)\n",
                                __LINE__, p_gensub->valf, modeStatusLI);
  funcLog( 5, __FILE__ "[%d] warningBI            = %d (%d,%d)\n",
                                __LINE__, *(short *)p_gensub->valg, warningBI, mainStatusLI);
  funcLog( 5, __FILE__ "[%d] alarmBI              = %d (%d,%d)\n",
                                __LINE__, *(short *)p_gensub->valh, alarmBI, mainStatusLI);

  p_counter=(long *)p_gensub->u;
  *p_counter=*p_counter+1;

  funcLog( 3, __FILE__ "[%d] <-- %s (%ld)\n",
                  __LINE__, __func__, *p_counter);

  return(*p_counter);
}

epicsRegisterFunction(SNOVA_funcTranslateStatusCodes);


> Date: Wed, 16 Oct 2013 18:16:44 +0800
> From: [email protected]
> To: [email protected]
> Subject: how to put value to other record in subroutine record
>
> hi, all:
>
> if I want to change another record's value in a subroutine record's process function, can I call dbPutField() or other functions? can anyone show me some examples?
> thanks a lot in advance.
>
>
> --------------
> Best wishes
> Geyang 2013-10-16
>

Replies:
Re: how to put value to other record in subroutine record Martin L. Smith
References:
how to put value to other record in subroutine record Silver

Navigate by Date:
Prev: Re: How to Read Multiple Values using StreamDevice with array_in Dirk Zimoch
Next: Proper initialisation of Motor Record .RMP value Peter Linardakis
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
Navigate by Thread:
Prev: how to put value to other record in subroutine record Silver
Next: Re: how to put value to other record in subroutine record Martin L. Smith
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  2006  2007  2008  2009  2010  2011  2012  <20132014  2015  2016  2017  2018  2019  2020  2021  2022  2023  2024 
ANJ, 20 Apr 2015 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·