- various improvements in SE drivers
This commit is contained in:
21
arrobj.c
21
arrobj.c
@ -31,6 +31,7 @@ static ParClass arrayObjClass = { "array", sizeof(ArrayObj) };
|
||||
|
||||
typedef struct WrtObjContext {
|
||||
FILE *file;
|
||||
int pos;
|
||||
char filename[PATH_MAX];
|
||||
} WrtObjContext;
|
||||
|
||||
@ -38,9 +39,17 @@ typedef struct WrtObjContext {
|
||||
int WrtObjOpen(WrtObjContext *ctx, char *fileName) {
|
||||
|
||||
int iret;
|
||||
|
||||
char *slashpos;
|
||||
|
||||
/* create a temporary file first */
|
||||
iret = snprintf(ctx->filename, sizeof(ctx->filename), ".%s", fileName);
|
||||
slashpos = strrchr(fileName, '/');
|
||||
if (slashpos == NULL) {
|
||||
ctx->pos = 0;
|
||||
} else {
|
||||
ctx->pos = slashpos - fileName + 1;
|
||||
}
|
||||
iret = snprintf(ctx->filename, sizeof(ctx->filename), "%.*s.%s"
|
||||
, ctx->pos, fileName, fileName + ctx->pos);
|
||||
if (iret < 0 || iret >= sizeof(ctx->filename)) {
|
||||
return 0;
|
||||
}
|
||||
@ -66,9 +75,13 @@ void WrtObj(WrtObjContext *ctx, char *objectName) {
|
||||
}
|
||||
/*-----------------------------------------------------------------------*/
|
||||
void WrtObjClose(WrtObjContext *ctx) {
|
||||
char finalName[PATH_MAX];
|
||||
|
||||
if (ctx) {
|
||||
fclose(ctx->file);
|
||||
rename(ctx->filename, ctx->filename+1);
|
||||
snprintf(finalName, sizeof finalName, "%.*s%s"
|
||||
, ctx->pos, ctx->filename, ctx->filename + ctx->pos + 1);
|
||||
rename(ctx->filename, finalName);
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -277,5 +290,5 @@ static int ArrayObjInit(SConnection *con, int argc, char *argv[], int dynamic) {
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void ArrayObjStartup(void) {
|
||||
ParMakeClass(&arrayObjClass, NULL);
|
||||
MakeDriver("array", ArrayObjInit, 0);
|
||||
MakeDriver("array", ArrayObjInit, 0, "String Array Object");
|
||||
}
|
||||
|
16
ease.c
16
ease.c
@ -44,6 +44,7 @@ EaseDriv *EaseDrivCast(void *object) {
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void EaseStop(EaseBase *eab) {
|
||||
FsmStop(eab->task, eab->idle);
|
||||
closeRS232(eab->ser);
|
||||
eab->state = EASE_notconnected;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -105,6 +106,7 @@ void EaseWrite(EaseBase *eab, char *cmd) {
|
||||
snprintf(eab->msg, sizeof eab->msg,
|
||||
"connection to %s:%d lost", eab->ser->pHost, eab->ser->iPort);
|
||||
ParPrintf(eab, eError, "ERROR: %s", eab->msg);
|
||||
closeRS232(eab->ser);
|
||||
eab->state = EASE_notconnected;
|
||||
eab->errCode = iRet;
|
||||
return;
|
||||
@ -205,9 +207,11 @@ int EaseHandler(EaseBase *eab) {
|
||||
snprintf(eab->msg, sizeof eab->msg,
|
||||
"connection for %s failed", eab->p.name);
|
||||
ParPrintf(eab, eError, "%s", eab->msg);
|
||||
closeRS232(eab->ser);
|
||||
eab->state = EASE_notconnected;
|
||||
return 0;
|
||||
} else {
|
||||
eab->tmo = 20;
|
||||
snprintf(eab->msg, sizeof eab->msg,
|
||||
"get a first answer from %s", eab->p.name);
|
||||
eab->state = EASE_idle;
|
||||
@ -345,7 +349,7 @@ int EaseUpdate(int flag) {
|
||||
assert(flag >= 0);
|
||||
assert(flag <= eab->maxflag);
|
||||
eab->updateFlags[flag / EASE_FLAGBITS] |= 1 << (flag % EASE_FLAGBITS);
|
||||
FsmSpeed(eab->task);
|
||||
if (eab->task) FsmSpeed(eab->task);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
@ -614,6 +618,7 @@ static int EaseInit(SConnection *pCon, EaseBase *eab, int argc, char *argv[],
|
||||
eab->version[0] = '\0';
|
||||
eab->maxflag = maxflag;
|
||||
eab->sendCmd = NULL;
|
||||
eab->tmo = 20;
|
||||
eab->updateFlags = calloc(maxflag / EASE_FLAGBITS + 1, sizeof (*eab->updateFlags));
|
||||
if (eab->updateFlags == NULL) {
|
||||
SCWrite(pCon, "out of memory", eError);
|
||||
@ -723,7 +728,14 @@ void *EaseMakeDriv(SConnection *con, void *class, int argc, char *argv[],
|
||||
ead->drivInt->SetValue = EaseRun;
|
||||
ead->drivInt->CheckStatus = EaseCheckStatus;
|
||||
ead->drivInt->GetValue = EaseGetValue;
|
||||
|
||||
|
||||
ead->maxwait = -1;
|
||||
ead->lowerLimit = 0;
|
||||
ead->upperLimit = 1000;
|
||||
ead->settle = 0;
|
||||
ead->tolerance = 1;
|
||||
ead->targetValue = 0;
|
||||
|
||||
/* EMon interface to be implemented */
|
||||
return ead;
|
||||
}
|
||||
|
1
ease.h
1
ease.h
@ -49,6 +49,7 @@ typedef struct {
|
||||
unsigned long *updateFlags;
|
||||
int startOk;
|
||||
char *sendCmd;
|
||||
int tmo;
|
||||
} EaseBase;
|
||||
|
||||
typedef struct {
|
||||
|
78
euro2kdriv.c
78
euro2kdriv.c
@ -32,6 +32,7 @@ Markus Zolliker, August 2005
|
||||
|
||||
#define EURO2K_SET 1
|
||||
#define EURO2K_MODE 2
|
||||
#define EURO2K_PAR 3
|
||||
|
||||
typedef enum {read_only, settable, to_set} Euro2kAccess;
|
||||
|
||||
@ -49,13 +50,17 @@ typedef struct Euro2kPar {
|
||||
typedef struct {
|
||||
EaseDriv d;
|
||||
char *unit;
|
||||
int mode, manual;
|
||||
int mode;
|
||||
char *script;
|
||||
int warned;
|
||||
float temperature;
|
||||
float output;
|
||||
float position;
|
||||
float range;
|
||||
float asymmetry;
|
||||
float setpoint;
|
||||
Euro2kPar *pars, *readPar;
|
||||
Statistics *stat;
|
||||
} Euro2k;
|
||||
|
||||
static ParClass euro2kClass = { "EURO2K", sizeof(Euro2k) };
|
||||
@ -68,7 +73,7 @@ static int Euro2kMakePar(void *object, void *userarg, int argc, char *argv[])
|
||||
int iarg;
|
||||
|
||||
assert(drv);
|
||||
if (argc < 1) goto Usage;
|
||||
if (argc < 2) goto Usage;
|
||||
last = &drv->pars;
|
||||
for (par = drv->pars; par != NULL; par = par->next) {
|
||||
if (strcasecmp(argv[0], par->name) == 0) {
|
||||
@ -155,11 +160,17 @@ void Euro2kParDef(void *object) {
|
||||
ParName("mode"); ParEnum(modeList); ParList(0); EaseUpdate(EURO2K_MODE);
|
||||
ParInt(&drv->mode, 1);
|
||||
|
||||
ParName("manual"); ParEnum(modeList);
|
||||
ParInt(&drv->manual, 1);
|
||||
|
||||
ParName("output"); ParTail("%");
|
||||
ParFloat(&drv->output, PAR_NAN);
|
||||
|
||||
ParName("position"); ParTail("%");
|
||||
ParFloat(&drv->position, PAR_NAN);
|
||||
|
||||
ParName("asymmetry"); ParAccess(usUser);
|
||||
ParFloat(&drv->asymmetry, PAR_NAN);
|
||||
|
||||
ParName("range"); ParAccess(usUser);
|
||||
ParFloat(&drv->range, PAR_NAN);
|
||||
|
||||
ParName("set"); ParTail(drv->unit); EaseUpdate(EURO2K_SET);
|
||||
ParFloat(&drv->setpoint, PAR_NAN);
|
||||
@ -206,7 +217,7 @@ void Euro2kParDef(void *object) {
|
||||
ParFmt(par->fmt);
|
||||
}
|
||||
if (par->set >= settable) {
|
||||
if (EaseUpdate(EURO2K_SET)) {
|
||||
if (EaseUpdate(EURO2K_PAR)) {
|
||||
par->set = to_set;
|
||||
}
|
||||
}
|
||||
@ -217,7 +228,7 @@ void Euro2kParDef(void *object) {
|
||||
ParName("makepar"); ParAccess(usUser); ParCmd(Euro2kMakePar, NULL);
|
||||
|
||||
EaseBasePar(drv);
|
||||
EaseDrivPar(drv, "%#.5g", drv->unit);
|
||||
EaseDrivPar(drv, "%.5g", drv->unit);
|
||||
ParStdDef();
|
||||
EaseMsgPar(drv);
|
||||
if (ParActionIs(PAR_KILL)) {
|
||||
@ -239,6 +250,9 @@ void Euro2kParDef(void *object) {
|
||||
free(par);
|
||||
}
|
||||
drv->pars = NULL;
|
||||
if (drv->stat) {
|
||||
StatisticsKill(drv->stat);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -249,13 +263,16 @@ static long Euro2kRead(long pc, void *object) {
|
||||
Tcl_Interp *pTcl = NULL;
|
||||
char *p;
|
||||
int l, m, iRet;
|
||||
float dif;
|
||||
float dif, a;
|
||||
char buf[4];
|
||||
|
||||
Statistics *old;
|
||||
|
||||
switch (pc) { default: /* FSM BEGIN *******************************/
|
||||
if (drv->script && drv->script[0] != '\0' && 0 != strcmp(drv->script, "0")) {
|
||||
pTcl = InterpGetTcl(pServ->pSics);
|
||||
old = StatisticsBegin(drv->stat);
|
||||
iRet = Tcl_Eval(pTcl,drv->script);
|
||||
StatisticsEnd(old);
|
||||
if (iRet == TCL_OK) {
|
||||
if (drv->warned > 0) drv->warned--;
|
||||
} else if (drv->warned<3) {
|
||||
@ -263,13 +280,18 @@ static long Euro2kRead(long pc, void *object) {
|
||||
ParPrintf(drv, eError, "ERROR: %s in %s.task '%s'", pTcl->result, eab->p.name, drv->script);
|
||||
}
|
||||
}
|
||||
ModBusRequestValue(eab, 273); /* get manual or auto */
|
||||
if (EaseGetUpdate(drv, EURO2K_MODE)) goto skipMode;
|
||||
ModBusRequestValue(eab, 273, modBusInt); /* get manual or auto */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
m = ModBusGetValue(eab, modBusInt);
|
||||
if (m != drv->manual) { /* mode changed manually */
|
||||
drv->mode = m;
|
||||
if (!EaseGetUpdate(drv, EURO2K_MODE)) {
|
||||
m = ModBusGetValue(eab, modBusInt);
|
||||
if (m != drv->mode) { /* mode changed manually -> change disp */
|
||||
drv->mode = m;
|
||||
EaseSetUpdate(drv, EURO2K_MODE, 1);
|
||||
}
|
||||
}
|
||||
drv->manual= m;
|
||||
skipMode:
|
||||
|
||||
ModBusRequestFloats(eab, 1, 3);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
drv->temperature = ModBusGetFloat(eab, 1);
|
||||
@ -277,11 +299,19 @@ static long Euro2kRead(long pc, void *object) {
|
||||
drv->setpoint = ModBusGetFloat(eab, 2);
|
||||
}
|
||||
drv->output = ModBusGetFloat(eab, 3);
|
||||
a = drv->output * eab->p.period / drv->range;
|
||||
if ((drv->position > 50.) == (drv->output > 0)) {
|
||||
drv->position += a * (1 - drv->asymmetry * 0.01);
|
||||
} else {
|
||||
drv->position += a * (1 + drv->asymmetry * 0.01);
|
||||
}
|
||||
if (drv->position < 0) drv->position = 0;
|
||||
if (drv->position > 100) drv->position = 100;
|
||||
par = drv->pars;
|
||||
loop:
|
||||
if (par == NULL) goto finish;
|
||||
if (par->adr == 0 || par->set == to_set) goto skipPar;
|
||||
ModBusRequestValue(eab, par->adr);
|
||||
ModBusRequestValue(eab, par->adr, par->type);
|
||||
drv->readPar = par;
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
par = drv->readPar;
|
||||
@ -333,8 +363,10 @@ static long Euro2kSet(long pc, void *object) {
|
||||
if (drv->mode == 0) goto loop;
|
||||
drv->mode = 0;
|
||||
mode:
|
||||
drv->manual = drv->mode;
|
||||
ModBusPutValue(eab, 273, 1, drv->manual); /* set manual to 0 */
|
||||
if (drv->mode) drv->mode = 1;
|
||||
ModBusPutValue(eab, 106, modBusInt, drv->mode*5); /* set display std or blank */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
ModBusPutValue(eab, 273, modBusInt, drv->mode); /* set manual to 0 */
|
||||
setIt:
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
goto loop;
|
||||
@ -347,13 +379,17 @@ static long Euro2kStart(long pc, void *object) {
|
||||
EaseBase *eab = object;
|
||||
|
||||
switch (pc) { default: /* FSM BEGIN *******************************/
|
||||
ModBusRequestValue(eab, 1);
|
||||
ModBusRequestValue(eab, 1, modBusFloat);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
if (0 == ModBusGetValue(eab, modBusFloat)) {
|
||||
ParPrintf(drv, eError, "bad or no response on ModBus");
|
||||
goto quit;
|
||||
}
|
||||
ParPrintf(drv, eStatus, "connected to euro2k");
|
||||
ModBusPutValue(eab, 111, modBusFloat, drv->d.upperLimit);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
ModBusPutValue(eab, 112, modBusFloat, drv->d.lowerLimit);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
FsmCall(Euro2kRead);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
|
||||
@ -367,19 +403,21 @@ static int Euro2kInit(SConnection *con, int argc, char *argv[], int dynamic) {
|
||||
<host> <port>
|
||||
*/
|
||||
Euro2k *drv;
|
||||
char sn[64];
|
||||
|
||||
drv = EaseMakeDriv(con, &euro2kClass, argc, argv, dynamic, 7,
|
||||
Euro2kParDef, ModBusHandler, Euro2kStart, NULL, Euro2kRead,
|
||||
Euro2kSet);
|
||||
if (drv == NULL) return 0;
|
||||
drv->pars = NULL;
|
||||
snprintf(sn, sizeof sn, "%s task", argv[1]);
|
||||
drv->stat = StatisticsNew(sn);
|
||||
setRS232ReplyTerminator(drv->d.b.ser,"");
|
||||
setRS232SendTerminator(drv->d.b.ser,"");
|
||||
ParPrintf(drv, eValue, "Eurotherm 2xxx");
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void Euro2kStartup(void) {
|
||||
ParMakeClass(&euro2kClass, EaseDrivClass());
|
||||
MakeDriver("EURO2K", Euro2kInit, 0);
|
||||
MakeDriver("EURO2K", Euro2kInit, 0, "Eurotherm 2xxx");
|
||||
}
|
||||
|
139
ighdriv.c
139
ighdriv.c
@ -34,11 +34,12 @@ Markus Zolliker, May 2005
|
||||
#define OLDIGH -8
|
||||
#define SORBS_FLAG 1
|
||||
#define MIXP_FLAG 2
|
||||
#define STILL_FLAG 3
|
||||
#define SORBP_FLAG 4
|
||||
#define MOT_FLAGS 5
|
||||
#define VALVE_FLAGS 8
|
||||
#define MAX_FLAG 31
|
||||
#define MAXP_FLAG 3
|
||||
#define STILL_FLAG 4
|
||||
#define SORBP_FLAG 5
|
||||
#define MOT_FLAGS 6
|
||||
#define VALVE_FLAGS 9
|
||||
#define MAX_FLAG 32
|
||||
|
||||
static char *valves[]={"V9", "V8", "V7", "V11A", "V13A", "V13B", "V11B", "V12B",
|
||||
" He4", "V1", "V5", "V4", "V3", "V14", "V10", "V2",
|
||||
@ -60,6 +61,7 @@ static char *closedOrOpen[]={"closed", "open", NULL};
|
||||
|
||||
typedef struct {
|
||||
EaseDriv d;
|
||||
float setT;
|
||||
float sorbS;
|
||||
float mixT;
|
||||
float onekT;
|
||||
@ -69,6 +71,8 @@ typedef struct {
|
||||
float sorbP;
|
||||
float press[n_PRESS];
|
||||
float mv[n_MOTOR];
|
||||
float v6pos;
|
||||
time_t v6time;
|
||||
int pdig;
|
||||
int v[n_VALVES];
|
||||
int e; /* heater range */
|
||||
@ -82,12 +86,40 @@ static ParClass ighClass = { "IGH", sizeof(Igh) };
|
||||
|
||||
static long IghSet(long pc, void *object);
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int IghPower2Range(float p) {
|
||||
int e;
|
||||
if (p <= 0) return 0;
|
||||
for (e = 1; e < 5; e++) {
|
||||
if (p < 1.9994) break;
|
||||
p /= 10;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static float IghRange2Max(int e) {
|
||||
static float elist[]={0,2,20,200,2000,20000};
|
||||
if (e < 0) {
|
||||
e = 0;
|
||||
} else if (e > 5) {
|
||||
e = 5;
|
||||
}
|
||||
return elist[e];
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static void IghParDef(void *object) {
|
||||
Igh *drv = ParCast(&ighClass, object);
|
||||
EaseBase *eab = object;
|
||||
int i, flag, l, changed;
|
||||
char *vPos;
|
||||
char *vPos, *val;
|
||||
char fmt[8], vList[80];
|
||||
float maxP;
|
||||
|
||||
ParName(""); ParTail("K"); ParFmt("%.4f");
|
||||
ParFloat(&drv->mixT, PAR_NAN);
|
||||
|
||||
ParName("Tset"); ParTail("K"); ParFmt("%.4f");
|
||||
if (eab->syntax == OLDIGH) ParList("all");
|
||||
ParFloat(&drv->setT, PAR_NAN);
|
||||
|
||||
ParName("TsorbSet");
|
||||
EaseUpdate(SORBS_FLAG); ParTail("K"); ParFmt("%.1f");
|
||||
@ -106,8 +138,7 @@ static void IghParDef(void *object) {
|
||||
ParFloat(&drv->sorbT, PAR_NAN);
|
||||
|
||||
ParName("Pmix");
|
||||
if (drv->e < 1 || drv->e > 5) drv->e=1;
|
||||
if (drv->e == 5) {
|
||||
if (drv->e >= 5 || drv->e < 1) {
|
||||
strcpy(fmt, "%.0f");
|
||||
} else {
|
||||
snprintf(fmt, sizeof fmt, "%%.%df", 4 - drv->e);
|
||||
@ -115,6 +146,14 @@ static void IghParDef(void *object) {
|
||||
EaseUpdate(MIXP_FLAG); ParTail("uW"); ParFmt(fmt);
|
||||
ParFloat(&drv->mixP, PAR_NAN);
|
||||
|
||||
ParName("Pmax");
|
||||
EaseUpdate(MAXP_FLAG); ParTail("uW"); ParFmt("%g");
|
||||
if ((val = ParGetValueArg())) {
|
||||
drv->e = IghPower2Range(atof(val) * 0.9);
|
||||
}
|
||||
maxP = IghRange2Max(drv->e);
|
||||
ParFloat(&maxP, PAR_NAN);
|
||||
|
||||
ParName("Pstill");
|
||||
EaseUpdate(STILL_FLAG); ParTail("mW"); ParFmt("%.3f");
|
||||
ParFloat(&drv->stillP, PAR_NAN);
|
||||
@ -144,11 +183,16 @@ static void IghParDef(void *object) {
|
||||
flag = MOT_FLAGS;
|
||||
for (i=0; i<n_MOTOR; i++) {
|
||||
ParName(motorValves[i]);
|
||||
ParFmt("%.1f");
|
||||
ParTail("%");
|
||||
if (i == V1K) ParList("all");
|
||||
EaseUpdate(flag); flag++;
|
||||
ParFloat(&drv->mv[i], PAR_NAN);
|
||||
}
|
||||
|
||||
ParName("v6pos"); ParFmt("%.1f"); ParTail("%");
|
||||
ParFloat(&drv->v6pos, PAR_NAN);
|
||||
|
||||
assert(flag == VALVE_FLAGS);
|
||||
l = 0;
|
||||
for (i=0; i<n_VALVES; i++) {
|
||||
@ -229,7 +273,13 @@ void IghStatus(Igh *drv) {
|
||||
drv->a = ans[3] - '0';
|
||||
drv->s = ans[16] - '0';
|
||||
drv->o = ans[18] - '0';
|
||||
drv->e = ans[20] - '0';
|
||||
if (EaseGetUpdate(drv, MAXP_FLAG) == 0) {
|
||||
if (drv->a == 0) {
|
||||
drv->e = 0;
|
||||
} else {
|
||||
drv->e = ans[20] - '0';
|
||||
}
|
||||
}
|
||||
if (ans[5] != '3' && drv->remote == 2) {
|
||||
ParPrintf(drv, eError, "IGH switched to local");
|
||||
*code = EASE_FAULT;
|
||||
@ -243,7 +293,8 @@ static long IghRead(long pc, void *object) {
|
||||
EaseBase *eab = object;
|
||||
char *p;
|
||||
int l;
|
||||
time_t thisPeriod;
|
||||
time_t now;
|
||||
float delta;
|
||||
|
||||
switch (pc) { default: /* FSM BEGIN *******************************/
|
||||
EaseWrite(eab, "X");
|
||||
@ -285,6 +336,12 @@ static long IghRead(long pc, void *object) {
|
||||
}
|
||||
if (EaseCheckDoit(eab)) goto quit;
|
||||
|
||||
if (eab->syntax == OLDIGH) goto noSetTemp;
|
||||
EaseWrite(eab, "R33");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
drv->setT = OxiGet(eab, 4, NULL, drv->setT);
|
||||
|
||||
noSetTemp:
|
||||
EaseWrite(eab, "R1");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
drv->sorbT = OxiGet(eab, 1, NULL, drv->sorbT);
|
||||
@ -297,6 +354,10 @@ static long IghRead(long pc, void *object) {
|
||||
|
||||
if (EaseCheckDoit(eab)) goto quit;
|
||||
|
||||
if (drv->e == 0) {
|
||||
drv->mixP = 0;
|
||||
goto skip4;
|
||||
}
|
||||
if (EaseGetUpdate(drv, MIXP_FLAG)) goto skip4;
|
||||
EaseWrite(eab, "R4");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
@ -325,6 +386,16 @@ static long IghRead(long pc, void *object) {
|
||||
EaseWrite(eab, "R7");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
drv->mv[V6] = OxiGet(eab, 1, NULL, drv->mv[V6]);
|
||||
time(&now);
|
||||
delta = (now - drv->v6time) / 2.64; /* speed: 1/2.64 %/sec */
|
||||
drv->v6time = now;
|
||||
if (drv->v6pos > drv->mv[V6] + delta) {
|
||||
drv->v6pos -= delta;
|
||||
} else if (drv->v6pos < drv->mv[V6] - delta) {
|
||||
drv->v6pos += delta;
|
||||
} else {
|
||||
drv->v6pos = drv->mv[V6];
|
||||
}
|
||||
skip7:
|
||||
|
||||
if (EaseCheckDoit(eab)) goto quit;
|
||||
@ -424,6 +495,7 @@ static long IghSet(long pc, void *object) {
|
||||
if (upd == EASE_RUN) goto set_temp;
|
||||
if (upd == SORBS_FLAG) goto set_sorb_temp;
|
||||
if (upd == MIXP_FLAG) goto set_mix_pow;
|
||||
if (upd == MAXP_FLAG) goto set_max_pow;
|
||||
if (upd == STILL_FLAG) goto set_still_pow;
|
||||
if (upd == SORBP_FLAG) goto set_sorb_pow;
|
||||
goto finish;
|
||||
@ -482,33 +554,44 @@ static long IghSet(long pc, void *object) {
|
||||
goto loop;
|
||||
|
||||
set_mix_pow:
|
||||
EaseWrite(eab, "A0");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
if (drv->e <= 1) goto skipe;
|
||||
EaseWrite(eab, "E1");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
|
||||
skipe:
|
||||
if (drv->mixP > 0) {
|
||||
mp = drv->mixP * 0.1;
|
||||
for (i=2; i<6; i++) {
|
||||
if (mp > 199) {
|
||||
break;
|
||||
}
|
||||
mp = mp * 10;
|
||||
}
|
||||
if (mp > 1999) mp = 1999;
|
||||
drv->e = 7-i;
|
||||
drv->e = IghPower2Range(drv->mixP);
|
||||
mp = drv->mixP / IghRange2Max(drv->e) * 2000;
|
||||
} else {
|
||||
mp = 0;
|
||||
mp = 0; /* range unchanged for external heater signal */
|
||||
}
|
||||
OxiSet(eab, "M", mp, 0);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
if (drv->e == 0) goto loop;
|
||||
|
||||
EaseWrite(eab, "A1");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
|
||||
set_max_pow:
|
||||
if (drv->e == 0) goto seta0;
|
||||
snprintf(buf, sizeof buf, "E%d", drv->e);
|
||||
EaseWrite(eab, buf);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "A1");
|
||||
goto loop;
|
||||
|
||||
seta0:
|
||||
EaseWrite(eab, "A0");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
goto loop;
|
||||
|
||||
|
||||
set_temp:
|
||||
/* unknown yet */
|
||||
goto loop;
|
||||
EaseWrite(eab, "A2");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
if (drv->d.targetValue < 0) drv->d.targetValue = 0;
|
||||
if (drv->d.targetValue > 1.999) drv->d.targetValue = 1.999;
|
||||
OxiSet(eab, "T", drv->d.targetValue, 4);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
goto loop;
|
||||
|
||||
@ -521,6 +604,11 @@ static long IghSet(long pc, void *object) {
|
||||
|
||||
set_mot:
|
||||
i = upd - MOT_FLAGS;
|
||||
if (drv->mv[i] > 99.9) {
|
||||
drv->mv[i]=99.9;
|
||||
} else if (drv->mv[i] < 0) {
|
||||
drv->mv[i]=0;
|
||||
}
|
||||
OxiSet(eab, motorCommands[i], drv->mv[i], 1);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
goto loop;
|
||||
@ -544,11 +632,10 @@ static int IghInit(SConnection *con, int argc, char *argv[], int dynamic) {
|
||||
IghParDef, OxiHandler, IghStart, NULL, IghRead,
|
||||
IghSet);
|
||||
if (drv == NULL) return 0;
|
||||
ParPrintf(drv, eValue, "OI Gas Handling System");
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void IghStartup(void) {
|
||||
ParMakeClass(&ighClass, EaseDrivClass());
|
||||
MakeDriver("IGH", IghInit, 0);
|
||||
MakeDriver("IGH", IghInit, 0, "OI Gas Handling System");
|
||||
}
|
||||
|
@ -186,11 +186,10 @@ static int IlmInit(SConnection *con, int argc, char *argv[], int dynamic) {
|
||||
drv = EaseMakeBase(con, &ilmClass, argc, argv, dynamic, 0,
|
||||
IlmParDef, OxiHandler, IlmStart, NULL, IlmRead);
|
||||
if (drv == NULL) return 0;
|
||||
ParPrintf(drv, eValue, "OI Level Meter");
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void IlmStartup(void) {
|
||||
ParMakeClass(&ilmClass, EaseBaseClass());
|
||||
MakeDriver("ILM", IlmInit, 0);
|
||||
MakeDriver("ILM", IlmInit, 0, "OI Level Meter");
|
||||
}
|
||||
|
@ -496,12 +496,11 @@ static int IpsInit(SConnection *con, int argc, char *argv[], int dynamic) {
|
||||
IpsParDef, OxiHandler, IpsStart, NULL, IpsRead,
|
||||
IpsChangeField);
|
||||
if (drv == NULL) return 0;
|
||||
ParPrintf(drv, eValue, "OI Power Supply");
|
||||
drv->d.maxwait = 999999;
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void IpsStartup(void) {
|
||||
ParMakeClass(&ipsClass, EaseDrivClass());
|
||||
MakeDriver("IPS", IpsInit, 0);
|
||||
MakeDriver("IPS", IpsInit, 0, "OI Power Supply");
|
||||
}
|
||||
|
@ -721,7 +721,6 @@ static int ItcInit(SConnection *con, int argc, char *argv[], int dynamic) {
|
||||
ItcSet);
|
||||
if (drv == NULL) return 0;
|
||||
drv->d.b.syntax = 0;
|
||||
ParPrintf(drv, eValue, "OI Temperature Controller");
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -740,12 +739,11 @@ static int ItcInitLc(SConnection *con, int argc, char *argv[], int dynamic) {
|
||||
drv->lastCtrl = 0;
|
||||
drv->lastTdiff = 0;
|
||||
drv->lastPdiff = 0;
|
||||
ParPrintf(drv, eValue, "OI Lambda Controller");
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void ItcStartup(void) {
|
||||
ParMakeClass(&itcClass, EaseDrivClass());
|
||||
MakeDriver("ITC", ItcInit, 0);
|
||||
MakeDriver("LC", ItcInitLc, 0);
|
||||
MakeDriver("ITC", ItcInit, 0, "OI Temperature Controller");
|
||||
MakeDriver("LC", ItcInitLc, 0, "OI Lambda Controller");
|
||||
}
|
||||
|
2
logger.c
2
logger.c
@ -220,7 +220,7 @@ int LoggerWrite0(Logger *log, time_t now, int period, char *value) {
|
||||
}
|
||||
pos1 = ftell(fil);
|
||||
strftime(stim, sizeof stim,"%H:%M:%S", tm);
|
||||
fprintf(fil, "%s\t%s%s\n", stim, value, buf);
|
||||
fprintf(fil, "%s\t%s\n", stim, value);
|
||||
for (p = ftell(fil); p < endPos; p++) { /* overwrite dirt after last line */
|
||||
fprintf(fil, " ");
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
|
||||
#define LOGGER_NAN -999999.
|
||||
#define ONE_YEAR (366*24*3600)
|
||||
#define LLEN 1024
|
||||
|
||||
typedef enum { NUMERIC, TEXT } CompType;
|
||||
|
||||
@ -21,8 +22,8 @@ typedef struct {
|
||||
time_t tlim;
|
||||
time_t tmin, tmax, tlast, told;
|
||||
float ymin, ymax, ylast, yold;
|
||||
char slast[256];
|
||||
char set[256];
|
||||
char slast[LLEN];
|
||||
/* char set[LLEN]; */
|
||||
int np;
|
||||
char *none;
|
||||
} Compressor;
|
||||
@ -43,7 +44,7 @@ static void InitCompressor(Compressor *c, SConnection *pCon, time_t step) {
|
||||
}
|
||||
|
||||
static void OutString(Compressor *c, time_t t, char *str) {
|
||||
char line[256];
|
||||
char line[LLEN];
|
||||
|
||||
/* printf("out %ld %g\n", t, y); */
|
||||
if (0 != strcmp(str, c->slast)) {
|
||||
@ -173,7 +174,7 @@ static int LogReader(SConnection *pCon, SicsInterp *pSics, void *pData,
|
||||
int yday=0;
|
||||
time_t t, startim;
|
||||
struct tm tm;
|
||||
char stim[32], path[256], line[256], lastval[256];
|
||||
char stim[32], path[LLEN], line[LLEN], lastval[LLEN];
|
||||
char *lin, *val, *stp;
|
||||
FILE *fil;
|
||||
Compressor c={0};
|
||||
|
3
make_gen
3
make_gen
@ -20,7 +20,8 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \
|
||||
dgrambroadcast.o sinq.o tabledrive.o tcpdocho.o julcho.o
|
||||
|
||||
MZOBJ=fsm.o logger.o sugar.o pardef.o ease.o strobj.o oxinst.o logreader.o \
|
||||
ipsdriv.o ilmdriv.o itcdriv.o ighdriv.o euro2kdriv.o modbus.o arrobj.o
|
||||
ipsdriv.o ilmdriv.o itcdriv.o ighdriv.o euro2kdriv.o modbus.o arrobj.o \
|
||||
lscsupport.o lsc370driv.o
|
||||
|
||||
libpsi.a: $(OBJ)
|
||||
rm -f libpsi.a
|
||||
|
21
modbus.c
21
modbus.c
@ -337,12 +337,17 @@ float ModBusGetFloat(EaseBase *eab, int adr) {
|
||||
return ieee2double(eab->ans + 3 + i * 4);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void ModBusRequestValue(EaseBase *eab, int adr) {
|
||||
void ModBusRequestValue(EaseBase *eab, int adr, int type) {
|
||||
|
||||
eab->cmd[0] = 1; /* device address */
|
||||
eab->cmd[1] = 3; /* read n words */
|
||||
fadr2word(adr, eab->cmd + 2);
|
||||
uint2word(2, eab->cmd + 4);
|
||||
if (type == modBusInt) {
|
||||
uint2word(adr, eab->cmd + 2);
|
||||
uint2word(1, eab->cmd + 4);
|
||||
} else {
|
||||
fadr2word(adr, eab->cmd + 2);
|
||||
uint2word(2, eab->cmd + 4);
|
||||
}
|
||||
ModBusWrite(eab, 6);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -351,13 +356,11 @@ void ModBusPutValue(EaseBase *eab, int adr, int type, float val) {
|
||||
|
||||
eab->cmd[0] = 1; /* device address */
|
||||
eab->cmd[1] = 16; /* write n words */
|
||||
if (type == modBusTime+9) {
|
||||
if (type == modBusInt) {
|
||||
uint2word(adr, eab->cmd + 2);
|
||||
eab->cmd[4] = 2;
|
||||
eab->cmd[5] = 0;
|
||||
eab->cmd[6] = 1;
|
||||
eab->cmd[7] = (int)(val) / 256;
|
||||
eab->cmd[8] = (int)(val) % 256;
|
||||
uint2word(1, eab->cmd + 4);
|
||||
eab->cmd[6] = 2;
|
||||
uint2word((int)(val), eab->cmd+7);
|
||||
ModBusWrite(eab, 9);
|
||||
return;
|
||||
}
|
||||
|
2
modbus.h
2
modbus.h
@ -19,7 +19,7 @@ int ModBusHandler(void *eab);
|
||||
void ModBusPutFloats(EaseBase *eab, int adr, int npar, float val[]);
|
||||
void ModBusRequestFloats(EaseBase *eab, int adr, int npar);
|
||||
float ModBusGetFloat(EaseBase *eab, int adr);
|
||||
void ModBusRequestValue(EaseBase *eab, int adr);
|
||||
void ModBusRequestValue(EaseBase *eab, int adr, int type);
|
||||
float ModBusGetValue(EaseBase *eab, int type);
|
||||
void ModBusPutValue(EaseBase *eab, int adr, int type, float val);
|
||||
|
||||
|
5
oxinst.c
5
oxinst.c
@ -92,10 +92,11 @@ int OxiHandler(void *object) {
|
||||
goto quit;
|
||||
} else if (eab->cmd[2] == 'k') { /* ?ck */
|
||||
} else {
|
||||
eab->tmo = 120;
|
||||
if (eab->syntax <= -8) {
|
||||
corr = OxiCorrect(eab->ans);
|
||||
if (corr) {
|
||||
ParPrintf(eab, eWarning, "corrected bad response from IGH: %s", corr);
|
||||
// ParPrintf(eab, eWarning, "corrected bad response from IGH: %s", corr);
|
||||
}
|
||||
}
|
||||
if (eab->cmd[0] != eab->ans[0]) {
|
||||
@ -110,7 +111,7 @@ int OxiHandler(void *object) {
|
||||
}
|
||||
eab->state = EASE_read;
|
||||
} else if (eab->state == EASE_expect) {
|
||||
if (time(NULL) > eab->cmdtime+20) {
|
||||
if (time(NULL) > eab->cmdtime + eab->tmo) {
|
||||
eab->state = EASE_lost;
|
||||
}
|
||||
} else if (eab->state == EASE_lost) {
|
||||
|
67
pardef.c
67
pardef.c
@ -31,11 +31,12 @@ typedef enum { NO_OP, FMT_OP, SET_OP, GET_OP, INIT_OP } ParOp;
|
||||
typedef struct Context {
|
||||
struct Context *next;
|
||||
ParData *obj;
|
||||
ParAct act;
|
||||
ParAct action;
|
||||
ParAct act; /* action called */
|
||||
ParAct action; /* copy of act, but set to PAR_NOOP when name does not match */
|
||||
char *parName;
|
||||
int argc;
|
||||
char **argv;
|
||||
char *valueArg;
|
||||
char *thisPar;
|
||||
int returnValue;
|
||||
SConnection *con;
|
||||
@ -283,6 +284,19 @@ int ParLog(void *object) {
|
||||
ParEnd();
|
||||
return next;
|
||||
}
|
||||
/*--------------------------------------------------------------------------*/
|
||||
void ParLogForced(void *object) {
|
||||
ParData *o = ParCheck(&parClass, object);
|
||||
int next;
|
||||
|
||||
ParBegin();
|
||||
ctx->now = time(NULL);
|
||||
showTime = 1;
|
||||
ParDo(0, o, PAR_LOG, NULL);
|
||||
o->logTime = ctx->now;
|
||||
o->logPending = 0;
|
||||
ParEnd();
|
||||
}
|
||||
/*-------------------------------------------------------------------------*/
|
||||
static int ParCallBack(int event, void *eventData, void *userData,
|
||||
commandContext cc) {
|
||||
@ -307,7 +321,7 @@ static int ParOutError(SConnection *con, ParData *o) {
|
||||
SCPrintf(con, eError, "ERROR: insufficient privilege for %s.%s", o->name, ctx->thisPar);
|
||||
break;
|
||||
case ILLNUM:
|
||||
SCPrintf(con, eError, "ERROR: illegal value", o->name, ctx->argv[0]);
|
||||
SCPrintf(con, eError, "ERROR: illegal value", o->name, ctx->valueArg);
|
||||
break;
|
||||
case ILLARGC:
|
||||
SCPrintf(con, eError, "ERROR: illegal number of arguments for %s %s", o->name, ctx->thisPar);
|
||||
@ -434,6 +448,7 @@ static int ParExecute(SConnection *con, SicsInterp *sics, void *object, int argc
|
||||
if (strcmp(argv[1], "=") == 0) {
|
||||
ctx->argc = argc - 2;
|
||||
ctx->argv = argv + 2;
|
||||
ctx->valueArg = argv[2];
|
||||
ParDo(con, o, PAR_SET, "");
|
||||
logIt = 1;
|
||||
} else {
|
||||
@ -442,6 +457,7 @@ static int ParExecute(SConnection *con, SicsInterp *sics, void *object, int argc
|
||||
} else {
|
||||
ctx->argc = argc - 2;
|
||||
ctx->argv = argv + 2;
|
||||
ctx->valueArg = argv[2];
|
||||
ParDo(con, o, PAR_SET, argv[1]);
|
||||
logIt = 1;
|
||||
}
|
||||
@ -465,7 +481,7 @@ static int ParExecute(SConnection *con, SicsInterp *sics, void *object, int argc
|
||||
ctx->returnValue = UNKPAR;
|
||||
}
|
||||
iret = ParOutError(con, o);
|
||||
if (logIt) ParLog(o); /* log changes */
|
||||
if (logIt) ParLogForced(o); /* log changes */
|
||||
ParEnd();
|
||||
return iret;
|
||||
}
|
||||
@ -984,15 +1000,17 @@ void ParFloat(float *value, float defValue) {
|
||||
ctx->returnValue = ILLARGC;
|
||||
return;
|
||||
}
|
||||
f = strtod(ctx->argv[0], &endp);
|
||||
if (endp == ctx->argv[0]) {
|
||||
f = ParText2Int(ctx->argv[0]);
|
||||
if (f < 0) {
|
||||
ctx->returnValue = ILLNUM;
|
||||
break;
|
||||
if (ctx->valueArg) {
|
||||
f = strtod(ctx->valueArg, &endp);
|
||||
if (endp == ctx->valueArg) {
|
||||
f = ParText2Int(ctx->valueArg);
|
||||
if (f < 0) {
|
||||
ctx->returnValue = ILLNUM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*value = f;
|
||||
}
|
||||
*value = f;
|
||||
ParHasChanged();
|
||||
/* fall through */
|
||||
case FMT_OP:
|
||||
@ -1030,15 +1048,17 @@ void ParInt(int *value, int defValue) {
|
||||
ctx->returnValue = ILLARGC;
|
||||
return;
|
||||
}
|
||||
i = strtol(ctx->argv[0], &endp, 0);
|
||||
if (endp == ctx->argv[0]) {
|
||||
i = ParText2Int(ctx->argv[0]);
|
||||
if (i < 0) {
|
||||
ctx->returnValue = ILLNUM;
|
||||
break;
|
||||
if (ctx->valueArg) {
|
||||
i = strtol(ctx->valueArg, &endp, 0);
|
||||
if (endp == ctx->valueArg) {
|
||||
i = ParText2Int(ctx->valueArg);
|
||||
if (i < 0) {
|
||||
ctx->returnValue = ILLNUM;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*value = i;
|
||||
}
|
||||
*value = i;
|
||||
ParHasChanged();
|
||||
/* fall through */
|
||||
case FMT_OP:
|
||||
@ -1128,6 +1148,17 @@ int ParActionIs(ParAct a) {
|
||||
return 0;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
char *ParGetValueArg() {
|
||||
char *ret;
|
||||
if (ctx->action == PAR_SET) {
|
||||
ret = ctx->valueArg;
|
||||
ctx->valueArg = NULL;
|
||||
return ret;
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void *ParObject(void) {
|
||||
return ctx->obj;
|
||||
}
|
||||
|
4
pardef.h
4
pardef.h
@ -195,6 +195,9 @@ typedef struct ParData {
|
||||
list */
|
||||
void ParLogReady(ReadyState state); /* set ready state for log */
|
||||
FILE *ParSaveFile(void); /* get the save-file name when action is PAR_SAVE */
|
||||
char *ParGetValueArg(); /* get the set argument for floats and ints. If this function
|
||||
is called, the caller is reponsible for assigning the value
|
||||
to the object parameter */
|
||||
|
||||
/*
|
||||
functions to be used outside pardef:
|
||||
@ -237,5 +240,6 @@ typedef struct ParData {
|
||||
|
||||
void ParInitPar(void *object, char *name);
|
||||
/* inititalize dynamic parameter */
|
||||
|
||||
#endif
|
||||
|
||||
|
1
psi.c
1
psi.c
@ -80,6 +80,7 @@ void SiteInit(void) {
|
||||
INIT(StrObjStartup);
|
||||
INIT(LogReaderInit);
|
||||
INIT(ArrayObjStartup);
|
||||
INIT(Lsc370Startup);
|
||||
|
||||
}
|
||||
|
||||
|
2
strobj.c
2
strobj.c
@ -46,5 +46,5 @@ static int StrObjInit(SConnection *con, int argc, char *argv[], int dynamic) {
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void StrObjStartup(void) {
|
||||
ParMakeClass(&strObjClass, NULL);
|
||||
MakeDriver("string", StrObjInit, 0);
|
||||
MakeDriver("string", StrObjInit, 0, "String Object");
|
||||
}
|
||||
|
18
tecsdriv.c
18
tecsdriv.c
@ -95,6 +95,7 @@ void outFunc(char *str, void *arg) {
|
||||
pTecsDriv pMe;
|
||||
float fVal;
|
||||
Buffer buffer;
|
||||
ObPar *pPar;
|
||||
|
||||
self = (pEVControl)pData;
|
||||
assert(self);
|
||||
@ -136,7 +137,10 @@ void outFunc(char *str, void *arg) {
|
||||
iRet = EVCGetPar(self, "upperlimit", &fVal);
|
||||
if (abs(fVal - atof(result)) > 1.0e-4 * abs(fVal)) {
|
||||
fVal = atof(result);
|
||||
iRet = EVCSetPar(self, "upperlimit", fVal,pCon);
|
||||
pPar = ObParFind(self->pParam,"upperlimit");
|
||||
if (pPar != NULL) {
|
||||
pPar->fVal = fVal;
|
||||
}
|
||||
}
|
||||
iRet = EVControlWrapper(pCon,pSics,pData,argc,argv);
|
||||
if (iRet != 0) {
|
||||
@ -161,7 +165,15 @@ void outFunc(char *str, void *arg) {
|
||||
sprintf(pBueffel,"WARNING: upper limit reduced to maximal allowed value: %g", fVal);
|
||||
SCWrite(pCon,pBueffel,eWarning);
|
||||
}
|
||||
iRet = EVCSetPar(self, "upperlimit", fVal,pCon);
|
||||
if (argc == 3) {
|
||||
iRet = EVCSetPar(self, "upperlimit", fVal,pCon);
|
||||
} else {
|
||||
pPar = ObParFind(self->pParam,"upperlimit");
|
||||
if (pPar != NULL) {
|
||||
pPar->fVal = fVal;
|
||||
}
|
||||
iRet = 1;
|
||||
}
|
||||
if (iRet) {
|
||||
sprintf(pBueffel,"%s.%s = %s\n",self->pName,
|
||||
argv[1],result);
|
||||
@ -478,5 +490,5 @@ void outFunc(char *str, void *arg) {
|
||||
pMe->EVLimits=pEvc->pDrivInt->CheckLimits; /* save original CheckLimits function */
|
||||
pEvc->pDrivInt->CheckLimits=TecsLimits;
|
||||
EVCSetPar(pEvc,"upperlimit",1800.0,pCon);
|
||||
EVCSetPar(pEvc,"lowerlimit",0.01,pCon);
|
||||
EVCSetPar(pEvc,"lowerlimit",0.0,pCon);
|
||||
}
|
||||
|
Reference in New Issue
Block a user