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