Add AFTC flag for bi record and fix mbbi AFTC bug (#817)
* Add AFTC feature to bi record with tests. * Fix broken AFTC handling for mbbi record, also fix bug in COSV and LALM handling. * Add release notes and update record docs.
This commit is contained in:
1 parent
631c8831b9
commit
c9817fa591
9 files changed
+371
-17
No files matched your search
@@ -23,6 +23,7 @@
|
||||
|
||||
#include "dbDefs.h"
|
||||
#include "epicsPrint.h"
|
||||
#include "epicsMath.h"
|
||||
#include "alarm.h"
|
||||
#include "callback.h"
|
||||
#include "dbAccess.h"
|
||||
@@ -40,6 +41,9 @@
|
||||
#undef GEN_SIZE_OFFSET
|
||||
#include "epicsExport.h"
|
||||
|
||||
/* Hysteresis for alarm filtering: 1-1/e */
|
||||
#define THRESHOLD 0.6321
|
||||
|
||||
/* Create RSET - Record Support Entry Table*/
|
||||
#define report NULL
|
||||
#define initialize NULL
|
||||
@@ -80,7 +84,7 @@ rset biRSET={
|
||||
};
|
||||
epicsExportAddress(rset,biRSET);
|
||||
|
||||
static void checkAlarms(biRecord *);
|
||||
static void checkAlarms(biRecord *, epicsTimeStamp *);
|
||||
static void monitor(biRecord *);
|
||||
static long readValue(biRecord *);
|
||||
|
||||
@@ -119,6 +123,7 @@ static long process(struct dbCommon *pcommon)
|
||||
bidset *pdset = (bidset *)(prec->dset);
|
||||
long status;
|
||||
unsigned char pact=prec->pact;
|
||||
epicsTimeStamp timeLast;
|
||||
|
||||
if( (pdset==NULL) || (pdset->read_bi==NULL) ) {
|
||||
prec->pact=TRUE;
|
||||
@@ -126,6 +131,8 @@ static long process(struct dbCommon *pcommon)
|
||||
return(S_dev_missingSup);
|
||||
}
|
||||
|
||||
timeLast = prec->time;
|
||||
|
||||
status=readValue(prec); /* read the new value */
|
||||
/* check if device support set pact */
|
||||
if ( !pact && prec->pact ) return(0);
|
||||
@@ -140,7 +147,7 @@ static long process(struct dbCommon *pcommon)
|
||||
}
|
||||
else if(status==2) status=0;
|
||||
/* check for alarms */
|
||||
checkAlarms(prec);
|
||||
checkAlarms(prec, &timeLast);
|
||||
/* check event list */
|
||||
monitor(prec);
|
||||
/* process the forward scan link record */
|
||||
@@ -217,27 +224,52 @@ static long put_enum_str(const DBADDR *paddr, const char *pstring)
|
||||
}
|
||||
|
||||
|
||||
static void checkAlarms(biRecord *prec)
|
||||
static void checkAlarms(biRecord *prec, epicsTimeStamp *timeLast)
|
||||
{
|
||||
epicsEnum16 asev;
|
||||
unsigned short val = prec->val;
|
||||
|
||||
|
||||
if(prec->udf == TRUE){
|
||||
recGblSetSevr(prec,UDF_ALARM,prec->udfs);
|
||||
return;
|
||||
}
|
||||
|
||||
if(val>1)return;
|
||||
/* check for state alarm */
|
||||
if (val == 0){
|
||||
recGblSetSevr(prec,STATE_ALARM,prec->zsv);
|
||||
}else{
|
||||
recGblSetSevr(prec,STATE_ALARM,prec->osv);
|
||||
|
||||
if (val == 0) {
|
||||
asev = prec->zsv;
|
||||
} else {
|
||||
asev = prec->osv;
|
||||
}
|
||||
|
||||
/* check for cos alarm */
|
||||
unsigned short alarm = asev; /* Initialize alarm with current state severity */
|
||||
double aftc = prec->aftc;
|
||||
double afvl = 0;
|
||||
|
||||
if (aftc > 0) {
|
||||
afvl = prec->afvl;
|
||||
if (afvl == 0) {
|
||||
afvl = (double) alarm;
|
||||
} else {
|
||||
double t = epicsTimeDiffInSeconds(&prec->time, timeLast);
|
||||
double alpha = aftc / (t + aftc);
|
||||
|
||||
afvl = alpha * afvl +
|
||||
((afvl > 0) ? (1.0 - alpha) : (alpha - 1.0)) * alarm;
|
||||
if (afvl - floor(afvl) > THRESHOLD)
|
||||
afvl = -afvl;
|
||||
|
||||
alarm = abs((int)floor(afvl));
|
||||
}
|
||||
}
|
||||
prec->afvl = afvl;
|
||||
|
||||
asev = alarm;
|
||||
recGblSetSevr(prec,STATE_ALARM,asev);
|
||||
|
||||
/* check for cos alarm */
|
||||
if(val == prec->lalm) return;
|
||||
recGblSetSevr(prec,COS_ALARM,prec->cosv);
|
||||
recGblSetSevr(prec,COS_ALARM,prec->cosv);
|
||||
prec->lalm = val;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -107,13 +107,20 @@ C<MAJOR>. The ZSV field holds the severity for the zero state; OSV, for
|
||||
the one state. COSV causes an alarm whenever the state changes between
|
||||
0 and 1 and the severity is configured as MINOR or MAJOR.
|
||||
|
||||
Since UNRELEASED, the alarm filter time constant (AFTC) is available for the bi record.
|
||||
The AFTC field sets the time constant on a low-pass filter that delays the
|
||||
reporting of limit alarms until the signal has been within the alarm range for
|
||||
that number of seconds (the default AFTC value of zero retains the previous
|
||||
behavior). Be sure that the bi record is processed at a reasonably fast rate
|
||||
when using AFTC, so that the record can respond to changes in the input signal
|
||||
within the time constant.
|
||||
|
||||
See L<Alarm Specification|https://docs.epics-controls.org/en/latest/process-database/EPICS_Process_Database_Concepts.html#alarm-specification>
|
||||
for a complete explanation of record alarms and of the standard fields.
|
||||
L<Alarm Fields|dbCommonRecord/Alarm Fields> lists other fields related
|
||||
to alarms that are common to all record types.
|
||||
|
||||
=fields ZSV, OSV, COSV
|
||||
|
||||
=fields ZSV, OSV, COSV, AFTC
|
||||
=head3 Run-time Parameters
|
||||
|
||||
These parameters are used by the run-time code for processing the binary
|
||||
@@ -220,6 +227,16 @@ is not equal to VAL.
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
field(AFTC, DBF_DOUBLE) {
|
||||
prompt("Alarm Filter Time Constant")
|
||||
promptgroup("70 - Alarm")
|
||||
interest(1)
|
||||
}
|
||||
field(AFVL, DBF_DOUBLE) {
|
||||
prompt("Alarm Filter Value")
|
||||
special(SPC_NOMOD)
|
||||
interest(3)
|
||||
}
|
||||
|
||||
=head3 Simulation Mode Parameters
|
||||
|
||||
|
||||
@@ -336,15 +336,15 @@ static void checkAlarms(mbbiRecord *prec, epicsTimeStamp *timeLast)
|
||||
alarm = abs((int)floor(afvl));
|
||||
}
|
||||
}
|
||||
prec->afvl = afvl;
|
||||
|
||||
asev = alarm;
|
||||
recGblSetSevr(prec, STATE_ALARM, asev);
|
||||
|
||||
/* Check for COS alarm */
|
||||
if (val == prec->lalm ||
|
||||
recGblSetSevr(prec, COS_ALARM, prec->cosv))
|
||||
if (val == prec->lalm)
|
||||
return;
|
||||
|
||||
recGblSetSevr(prec, COS_ALARM, prec->cosv);
|
||||
prec->lalm = val;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user