diff --git a/ease.c b/ease.c index 238da38..837f3a4 100644 --- a/ease.c +++ b/ease.c @@ -158,7 +158,7 @@ int EaseHandler(EaseBase *eab) { ead->stopped = 0; ead->hwstate = HWIdle; if (FsmStop(eab->task, eab->doit)) { - ParPrintf(eab, -1, "%s stopped", eab->p.name); + ParPrintf(eab, eWarning, "%s stopped", eab->p.name); return 0; } } @@ -203,7 +203,7 @@ int EaseHandler(EaseBase *eab) { if (ead) { if (eab->state == EASE_lost) { if (FsmStop(eab->task, eab->doit)) { - ParPrintf(eab, -1, "stop %s caused by timeout", eab->p.name); + ParPrintf(eab, eWarning, "stop %s caused by timeout", eab->p.name); } return 0; } @@ -226,10 +226,26 @@ int EaseNextFullRead(EaseBase *eab) { return 0; } /*----------------------------------------------------------------------------*/ +static long EaseSendIt(long pc, void *object) { + EaseBase *eab = EaseBaseCast(object); + + switch (pc) { default: /* FSM BEGIN *******************************/ + EaseWrite(eab, eab->sendCmd); + ParPrintf(eab, eWarning, "send cmd> %s", eab->sendCmd); + eab->sendCmd = NULL; + return __LINE__; case __LINE__: /**********************************/ + ParPrintf(eab, eWarning, "response> %s", eab->ans); + return 0; } /* FSM END ********************************************/ +} +/*----------------------------------------------------------------------------*/ int EaseCheckDoit(EaseBase *eab) { int i, n; if (eab->todo == NULL) { + if (eab->sendCmd != NULL) { + eab->todo = EaseSendIt; + return 1; + } n = eab->maxflag / EASE_FLAGBITS; for (i=0; i<=n; i++) { if (eab->updateFlags[i]) { @@ -367,18 +383,18 @@ static long EaseRun(void *obj, SConnection *pCon, float fVal) { SCSave(&eab->p.conn, pCon); if (! eab->doit) { - ParPrintf(ead, -1, "ERROR: missing run function %s", eab->p.name); + ParPrintf(ead, eError, "ERROR: missing run function %s", eab->p.name); return 0; } if (!eab->startOk) { - ParPrintf(ead, -1, "ERROR: %s is not ready to run", eab->p.name); + ParPrintf(ead, eError, "ERROR: %s is not ready to run", eab->p.name); return 0; } if (FsmStop(eab->task, eab->doit)) { - ParPrintf(ead, -1, "running %s cancelled", eab->p.name); + ParPrintf(ead, eWarning, "running %s cancelled", eab->p.name); } if (eab->todo) { - ParPrintf(ead, -1, "ERROR: %s busy", eab->p.name); + ParPrintf(ead, eError, "ERROR: %s busy", eab->p.name); return 0; } ead->targetValue = fVal; @@ -593,6 +609,7 @@ static int EaseInit(SConnection *pCon, EaseBase *eab, int argc, char *argv[], eab->cmdtime = 0; eab->version[0] = '\0'; eab->maxflag = maxflag; + eab->sendCmd = NULL; eab->updateFlags = calloc(maxflag / EASE_FLAGBITS + 1, sizeof (*eab->updateFlags)); if (eab->updateFlags == NULL) { SCWrite(pCon, "out of memory", eError); @@ -764,12 +781,8 @@ int EaseSend(void *object, void *userarg, int argc, char *argv[]) { iret = EaseWaitRead(eab); if (iret >= 0) { - term = eab->ser->sendTerminator; - ParArg2Text(argc, argv, cmd, sizeof(cmd) - strlen(term)); - ParPrintf(eab, -2, "cmd: %s", cmd); - strcat(cmd, term); - iret = transactRS232(eab->ser, cmd, strlen(cmd), - ans, sizeof ans); + eab->sendCmd = ParArg2Text(argc, argv, NULL, 0); + ParPrintf(eab, -2, "ans: %s", ans); ParPrintf(eab, eValue, "%s", ans); } diff --git a/ease.h b/ease.h index e99c980..366a27b 100644 --- a/ease.h +++ b/ease.h @@ -48,6 +48,7 @@ typedef struct { time_t readPeriod; unsigned long *updateFlags; int startOk; + char *sendCmd; } EaseBase; typedef struct { diff --git a/ighdriv.c b/ighdriv.c index 4c34350..f8eae58 100644 --- a/ighdriv.c +++ b/ighdriv.c @@ -145,8 +145,8 @@ static void IghParDef(void *object) { ParName(motorValves[i]); ParTail("%"); if (i == V1K) ParList("all"); - ParFloat(&drv->mv[i], PAR_NAN); EaseUpdate(flag); flag++; + ParFloat(&drv->mv[i], PAR_NAN); } assert(flag == VALVE_FLAGS); l = 0; @@ -265,33 +265,33 @@ static long IghRead(long pc, void *object) { } EaseWrite(eab, "R0"); return __LINE__; case __LINE__: /**********************************/ - drv->sorbS = OxiGet(eab, 1, NULL); + drv->sorbS = OxiGet(eab, 1, NULL, drv->sorbS); skip0: if (EaseCheckDoit(eab)) goto quit; EaseWrite(eab, "R1"); return __LINE__; case __LINE__: /**********************************/ - drv->sorbT = OxiGet(eab, 1, NULL); + drv->sorbT = OxiGet(eab, 1, NULL, drv->sorbT); if (EaseCheckDoit(eab)) goto quit; EaseWrite(eab, "R2"); return __LINE__; case __LINE__: /**********************************/ - drv->onekT = OxiGet(eab, 3, NULL); + drv->onekT = OxiGet(eab, 3, NULL, drv->onekT); if (EaseCheckDoit(eab)) goto quit; EaseWrite(eab, "R3"); return __LINE__; case __LINE__: /**********************************/ - drv->mixT = OxiGet(eab, 3, NULL); + drv->mixT = OxiGet(eab, 3, NULL, drv->mixT); if (EaseCheckDoit(eab)) goto quit; if (EaseGetUpdate(drv, MIXP_FLAG)) goto skip4; EaseWrite(eab, "R4"); return __LINE__; case __LINE__: /**********************************/ - drv->mixP = OxiGet(eab, 5 - drv->e, NULL) * 10; + drv->mixP = OxiGet(eab, 5 - drv->e, NULL, drv->mixP/10) * 10; skip4: if (EaseCheckDoit(eab)) goto quit; @@ -299,7 +299,7 @@ static long IghRead(long pc, void *object) { if (EaseGetUpdate(drv, STILL_FLAG)) goto skip5; EaseWrite(eab, "R5"); return __LINE__; case __LINE__: /**********************************/ - drv->stillP = OxiGet(eab, 1, NULL); + drv->stillP = OxiGet(eab, 1, NULL, drv->stillP); skip5: if (EaseCheckDoit(eab)) goto quit; @@ -307,7 +307,7 @@ static long IghRead(long pc, void *object) { if (EaseGetUpdate(drv, SORBP_FLAG)) goto skip6; EaseWrite(eab, "R6"); return __LINE__; case __LINE__: /**********************************/ - drv->sorbP = OxiGet(eab, 3, NULL); + drv->sorbP = OxiGet(eab, 3, NULL, drv->sorbP); skip6: if (EaseCheckDoit(eab)) goto quit; @@ -315,7 +315,7 @@ static long IghRead(long pc, void *object) { if (EaseGetUpdate(drv, MOT_FLAGS+V6)) goto skip7; EaseWrite(eab, "R7"); return __LINE__; case __LINE__: /**********************************/ - drv->mv[V6] = OxiGet(eab, 1, NULL); + drv->mv[V6] = OxiGet(eab, 1, NULL, drv->mv[V6]); skip7: if (EaseCheckDoit(eab)) goto quit; @@ -323,7 +323,7 @@ static long IghRead(long pc, void *object) { if (EaseGetUpdate(drv, MOT_FLAGS+V12A)) goto skip8; EaseWrite(eab, "R8"); return __LINE__; case __LINE__: /**********************************/ - drv->mv[V12A] = OxiGet(eab, 1, NULL); + drv->mv[V12A] = OxiGet(eab, 1, NULL, drv->mv[V12A]); skip8: if (EaseCheckDoit(eab)) goto quit; @@ -331,38 +331,38 @@ static long IghRead(long pc, void *object) { if (EaseGetUpdate(drv, MOT_FLAGS+V1K)) goto skip9; EaseWrite(eab, "R9"); return __LINE__; case __LINE__: /**********************************/ - drv->mv[V1K] = OxiGet(eab, 1, NULL); + drv->mv[V1K] = OxiGet(eab, 1, NULL, drv->mv[V1K]); skip9: if (EaseCheckDoit(eab)) goto quit; EaseWrite(eab, "R14"); return __LINE__; case __LINE__: /**********************************/ - drv->press[G1] = OxiGet(eab, 1, NULL); + drv->press[G1] = OxiGet(eab, 1, NULL, drv->press[G1]); if (EaseCheckDoit(eab)) goto quit; EaseWrite(eab, "R15"); return __LINE__; case __LINE__: /**********************************/ - drv->press[G2] = OxiGet(eab, 1, NULL); + drv->press[G2] = OxiGet(eab, 1, NULL, drv->press[G2]); if (EaseCheckDoit(eab)) goto quit; EaseWrite(eab, "R16"); return __LINE__; case __LINE__: /**********************************/ - drv->press[G3] = OxiGet(eab, 1, NULL); + drv->press[G3] = OxiGet(eab, 1, NULL, drv->press[G3]); if (EaseCheckDoit(eab)) goto quit; EaseWrite(eab, "R20"); return __LINE__; case __LINE__: /**********************************/ - drv->press[P1] = OxiGet(eab, drv->pdig, &drv->pdig); + drv->press[P1] = OxiGet(eab, drv->pdig, &drv->pdig, drv->press[P1]); if (EaseCheckDoit(eab)) goto quit; EaseWrite(eab, "R21"); return __LINE__; case __LINE__: /**********************************/ - drv->press[P2] = OxiGet(eab, 1, NULL); + drv->press[P2] = OxiGet(eab, 1, NULL, drv->press[P2]); quit: ParLog(drv); @@ -382,6 +382,7 @@ static long IghStart(long pc, void *object) { EaseStop(eab); goto quit; } + eab->syntax = -8; /* special value for communication error correction */ ParPrintf(drv, eStatus, "connected to %s", eab->version); FsmCall(IghRead); return __LINE__; case __LINE__: /**********************************/ diff --git a/ilmdriv.c b/ilmdriv.c index 87f2a40..5725dc6 100644 --- a/ilmdriv.c +++ b/ilmdriv.c @@ -117,23 +117,31 @@ static long IlmRead(long pc, void *object) { IlmStatus(drv); /* check for errors */ EaseWrite(eab, "R1"); /* read sensor 1 */ return __LINE__; case __LINE__: /**********************************/ - if (drv->readState[0] != MEASURING) drv->lev[0] = OxiGet(eab, 1, NULL); - if (drv->readState[0] == NOTYETREAD) drv->readState[0] = NEW; + if (drv->readState[0] != MEASURING) { + drv->lev[0] = OxiGet(eab, 1, NULL, drv->lev[0]); + } + if (drv->readState[0] == NOTYETREAD) { + drv->readState[0] = NEW; + } if (drv->usage[1] == 0) goto skip2; EaseWrite(eab, "R2"); /* read sensor 2 */ return __LINE__; case __LINE__: /**********************************/ - drv->lev[1] = OxiGet(eab, 1, NULL); - if (drv->readState[1] == NOTYETREAD) drv->readState[1] = NEW; - + drv->lev[1] = OxiGet(eab, 1, NULL, drv->lev[1]); + if (drv->readState[1] == NOTYETREAD) { + drv->readState[1] = NEW; + } skip2: + if (drv->usage[2] == 0) goto skip3; EaseWrite(eab, "R3"); /* read sensor 3 */ return __LINE__; case __LINE__: /**********************************/ - drv->lev[2] = OxiGet(eab, 1, NULL); - if (drv->readState[2] == NOTYETREAD) drv->readState[2] = NEW; - + drv->lev[2] = OxiGet(eab, 1, NULL, drv->lev[2]); + if (drv->readState[2] == NOTYETREAD) { + drv->readState[2] = NEW; + } skip3: + if (ParLog(drv) >= 0) { /* logging was done */ for (i=0; i<3; i++) { if (drv->readState[i] == NEW) { diff --git a/ipsdriv.c b/ipsdriv.c index 95c10d3..7aa5e2b 100644 --- a/ipsdriv.c +++ b/ipsdriv.c @@ -208,6 +208,7 @@ static void IpsStatus(Ips *drv) { drv->heaterFault = 1; return; } + drv->heaterFault = 0; if (ans[8] == '1') { swi = 1; } else { @@ -242,14 +243,14 @@ static long IpsRead(long pc, void *object) { rd: EaseWrite(eab, "R7"); /* read current (in Tesla) */ return __LINE__; case __LINE__: /**********************************/ - drv->current = OxiGet(eab, 3, NULL); + drv->current = OxiGet(eab, 3, NULL, drv->current); if (drv->perswitch) { IpsSetField(drv, drv->current); goto quit; } EaseWrite(eab, "R18"); /* read persistant field (in Tesla) */ return __LINE__; case __LINE__: /**********************************/ - IpsSetField(drv, OxiGet(eab, 3, NULL)); + IpsSetField(drv, OxiGet(eab, 3, NULL, drv->persfield)); quit: ParLog(drv); @@ -334,7 +335,7 @@ static long IpsChangeField(long pc, void *object) { IpsStatus(drv); /* just check for errors */ EaseWrite(eab, "R7"); /* read current (in Tesla) */ return __LINE__; case __LINE__: /**********************************/ - drv->current = OxiGet(eab, 3, NULL); + drv->current = OxiGet(eab, 3, NULL, drv->current); ParLog(drv); if (fabs(drv->current - drv->lastfield) > 1e-5) goto stab1; @@ -375,7 +376,6 @@ static long IpsChangeField(long pc, void *object) { eab->errCode = EASE_FAULT; goto off_finish; } - drv->heaterFault = 0; } if (time(NULL) < drv->swtim + 30) goto start_ramp; /* wait */ OxiSet(eab, "T", drv->ramp, 3); @@ -391,13 +391,13 @@ static long IpsChangeField(long pc, void *object) { return __LINE__; case __LINE__: /**********************************/ EaseWrite(eab, "R7"); /* read "current" in Tesla */ return __LINE__; case __LINE__: /**********************************/ - IpsSetField(drv, OxiGet(eab, 3, NULL)); /* set drv->current and callback */ + IpsSetField(drv, OxiGet(eab, 3, NULL, drv->current)); /* set drv->current and callback */ EaseWrite(eab, "X"); return __LINE__; case __LINE__: /**********************************/ IpsStatus(drv); /* just check for errors */ EaseWrite(eab, "R9"); /* read back ramp rate (may be sweep limited) */ return __LINE__; case __LINE__: /**********************************/ - ramp=OxiGet(eab, 3, NULL); + ramp=OxiGet(eab, 3, NULL, drv->ramp); step=ramp/20; /* step = ramp * 3sec */ if (step < 0.001) step=0.001; if (drv->d.targetValue > drv->current + step) { @@ -442,7 +442,7 @@ static long IpsChangeField(long pc, void *object) { return __LINE__; case __LINE__: /**********************************/ EaseWrite(eab, "R18"); /* read persistent field in Tesla */ return __LINE__; case __LINE__: /**********************************/ - fld = OxiGet(eab, 3, NULL); + fld = OxiGet(eab, 3, NULL, drv->current); if (fld != drv->lastfield) { IpsSetField(drv, fld); /* set drv->current and callback */ drv->lastfield = fld; diff --git a/itcdriv.c b/itcdriv.c index d52350e..e018f9d 100644 --- a/itcdriv.c +++ b/itcdriv.c @@ -34,6 +34,10 @@ Markus Zolliker, May 2005 #define TESLATRON -1 #define ITC_SETHTR 1 #define ITC_SETGAS 2 +#define ITC_PIDMODE 3 +#define ITC_PROP 4 +#define ITC_INTEG 5 +#define ITC_DERIV 6 typedef struct { EaseDriv d; @@ -43,6 +47,8 @@ typedef struct { float gas; float autoGasLimit; float setGas; + float prop, integ, deriv; + int pidMode; int sampleChan; int controlChan; int gasMode; @@ -63,6 +69,7 @@ static void ItcParDef(void *object) { int i; static char *ti[4] = {"setp","t1","t2","t3"}; static char *modeList[]={"off", "manual", "auto", NULL }; + static char *pidList[]={"default", "manual", "auto", NULL }; ParName("sampleChan"); if (eab->syntax != TESLATRON) ParAccess(usUser); @@ -166,10 +173,28 @@ static void ItcParDef(void *object) { if (eab->syntax != TESLATRON) { ParName("autoGasLimit"); ParAccess(usUser); ParFmt("%.1f"); ParTail("K"); ParSave(1); - if (drv->gasMode != 2) { - ParList(""); - } + if (drv->gasMode != 2) ParList(""); ParFloat(&drv->autoGasLimit, 3.0); + + ParName("pidMode"); + ParEnum(pidList); + EaseUpdate(ITC_PIDMODE); ParSave(1); + ParInt(&drv->pidMode, 0); + + ParName("prop"); ParFmt("%.3f"); ParTail("K"); + if (drv->pidMode == 1) ParList(""); + EaseUpdate(ITC_PROP); + ParFloat(&drv->prop, PAR_NAN); + + ParName("int"); ParFmt("%.1f"); ParTail("min"); + if (drv->pidMode == 1) ParList(""); + EaseUpdate(ITC_INTEG); + ParFloat(&drv->integ, PAR_NAN); + + ParName("deriv"); ParFmt("%.2f"); ParTail("min"); + if (drv->pidMode == 1) ParList(""); + EaseUpdate(ITC_DERIV); + ParFloat(&drv->deriv, PAR_NAN); } if (drv->controlChan == 0) { @@ -210,6 +235,9 @@ void ItcStatus(Itc *drv) { drv->a = ans[3] - '0'; if (ans[9] == 'H') { drv->h = ans[10] - '0'; + if (ans[11] == 'L' && drv->pidMode != 0 && ! EaseGetUpdate(drv, ITC_PIDMODE)) { + drv->pidMode == ans[12] - '0' + 1; + } } else { drv->h = drv->controlChan; } @@ -236,19 +264,19 @@ static long ItcRead(long pc, void *object) { if (drv->dig[1] < 0) goto skip1; EaseWrite(eab, "R1"); /* read sensor 1 */ return __LINE__; case __LINE__: /**********************************/ - drv->t[1] = OxiGet(eab, drv->dig[1], &drv->dig[1]); + drv->t[1] = OxiGet(eab, drv->dig[1], &drv->dig[1], drv->t[1]); skip1: if (drv->dig[2] < 0) goto skip2; EaseWrite(eab, "R2"); /* read sensor 2 */ return __LINE__; case __LINE__: /**********************************/ - drv->t[2] = OxiGet(eab, drv->dig[2], &drv->dig[2]); + drv->t[2] = OxiGet(eab, drv->dig[2], &drv->dig[2], drv->t[2]); skip2: if (drv->dig[3] < 0) goto skip3; EaseWrite(eab, "R3"); /* read sensor 3 */ return __LINE__; case __LINE__: /**********************************/ - drv->t[3] = OxiGet(eab, drv->dig[3], &drv->dig[3]); + drv->t[3] = OxiGet(eab, drv->dig[3], &drv->dig[3], drv->t[3]); skip3: if (drv->controlChan == 0 || drv->a == 0) { @@ -257,7 +285,7 @@ static long ItcRead(long pc, void *object) { } EaseWrite(eab, "R0"); /* read control T */ return __LINE__; case __LINE__: /**********************************/ - drv->t[0] = OxiGet(eab, drv->dig[drv->controlChan], NULL); + drv->t[0] = OxiGet(eab, drv->dig[drv->controlChan], NULL, drv->t[0]); if (drv->gasMode == 2) { if (drv->t[drv->controlChan] > drv->autoGasLimit + 1.0) { if (drv->a < 2) { @@ -304,14 +332,35 @@ static long ItcRead(long pc, void *object) { EaseWrite(eab, "R5"); /* read heater */ return __LINE__; case __LINE__: /**********************************/ if (EaseGetUpdate(drv, ITC_SETHTR)) goto skiphtr; - drv->htr = OxiGet(eab, 1, NULL); + drv->htr = OxiGet(eab, 1, NULL, drv->htr); skiphtr: EaseWrite(eab, "R7"); /* read gas flow */ return __LINE__; case __LINE__: /**********************************/ - drv->gas = OxiGet(eab, 1, NULL); + drv->gas = OxiGet(eab, 1, NULL, drv->gas); skipgas: + if (EaseGetUpdate(drv, ITC_PROP)) goto skipprop; + EaseWrite(eab, "R9"); /* read prop */ + return __LINE__; case __LINE__: /**********************************/ + if (EaseGetUpdate(drv, ITC_PROP)) goto skipprop; + drv->prop = OxiGet(eab, 1, NULL, drv->prop); + skipprop: + + if (EaseGetUpdate(drv, ITC_INTEG)) goto skipint; + EaseWrite(eab, "R10"); /* read int */ + return __LINE__; case __LINE__: /**********************************/ + if (EaseGetUpdate(drv, ITC_INTEG)) goto skipint; + drv->integ = OxiGet(eab, 1, NULL, drv->integ); + skipint: + + if (EaseGetUpdate(drv, ITC_DERIV)) goto skipderiv; + EaseWrite(eab, "R11"); /* read deriv */ + return __LINE__; case __LINE__: /**********************************/ + if (EaseGetUpdate(drv, ITC_DERIV)) goto skipderiv; + drv->deriv = OxiGet(eab, 1, NULL, drv->deriv); + skipderiv: + ParLog(drv); fsm_quit: return 0; } /* FSM END *********************************/ } @@ -377,8 +426,12 @@ static long ItcSetTemp(long pc, void *object) { skiph: OxiSet(eab, "T", drv->d.targetValue, drv->dig[drv->controlChan]); /* set point */ return __LINE__; case __LINE__: /**********************************/ + + if (drv->pidMode != 0) goto skipPidMode; EaseWrite(eab, "L1"); /* 'auto' pid on */ return __LINE__; case __LINE__: /**********************************/ + skipPidMode: + a = 1; /* auto heater */ if (drv->a >= 2) a = 3; /* auto gas & heater */ if (drv->d.targetValue == 0.0) { @@ -428,7 +481,7 @@ static long ItcSetGas(long pc, void *object) { return __LINE__; case __LINE__: /**********************************/ EaseWrite(eab, "R7"); /* read gas flow */ return __LINE__; case __LINE__: /**********************************/ - drv->gas = OxiGet(eab, 1, NULL); + drv->gas = OxiGet(eab, 1, NULL, drv->gas); if (drv->a < 2) goto quit; snprintf(buf, sizeof buf, "A%d", drv->a); EaseWrite(eab, buf); @@ -471,6 +524,17 @@ static long ItcSet(long pc, void *object) { case EASE_RUN: FsmCall(ItcSetTemp); goto loop; case ITC_SETHTR: FsmCall(ItcSetHtr); goto loop; case ITC_SETGAS: FsmCall(ItcSetGas); goto loop; + case ITC_PIDMODE: + if (drv->pidMode == 1) { + EaseWrite(eab, "L0"); + } else { + EaseWrite(eab, "L1"); + drv->pidMode = 2; + } + goto loop; + case ITC_PROP: OxiSet(eab, "P", drv->prop, 1); goto loop; + case ITC_INTEG: OxiSet(eab, "I", drv->prop, 1); goto loop; + case ITC_DERIV: OxiSet(eab, "D", drv->prop, 1); goto loop; default: break; } EaseWrite(eab, "C0"); diff --git a/logger.c b/logger.c index 64d4463..dd8274d 100644 --- a/logger.c +++ b/logger.c @@ -13,17 +13,8 @@ Markus Zolliker, Sept 2004 #include #include #include -#include -#include "splitter.h" #include "logger.h" -#ifndef TECS_LOG -#include "sics.h" -#endif - -#define LOGGER_NAN -999999. -#define ONE_YEAR (366*24*3600) - struct Logger { char *name; char *old; @@ -137,6 +128,7 @@ int LoggerWrite0(Logger *log, time_t now, int period, char *value) { int l, ext, skip, changed; FILE *fil; long endPos, pos1, p; + char info[80]; LoggerGetDir(); if (dir == NULL) return 0; @@ -160,6 +152,7 @@ int LoggerWrite0(Logger *log, time_t now, int period, char *value) { fil = fopen(path, "w+"); if (fil == NULL) return 0; fprintf(fil, "%s isdst %d period %d exact %d\n", stim, tm->tm_isdst, period, log->exact); + log->period = period; endPos = ftell(fil); fseek(fil, -1, SEEK_CUR); } else { /* check if file is from today */ @@ -190,14 +183,15 @@ int LoggerWrite0(Logger *log, time_t now, int period, char *value) { } } changed = (0 != strcmp(value, log->old)); + info[0]='\0'; if (period != log->period) { log->period = period; - if (log->numeric) { - snprintf(buf, sizeof buf, "\t%d", period); - } else { - strcpy(buf, "\t0"); - } changed = 1; + if (log->numeric) { + snprintf(info, sizeof info, "period %d exact %d ", period, log->exact); + } else { + snprintf(info, sizeof info, "period 0 exact 1 "); + } } else { buf[0]='\0'; if (log->overwrite && !changed) { @@ -220,8 +214,9 @@ int LoggerWrite0(Logger *log, time_t now, int period, char *value) { fseek(fil, pos1, SEEK_SET); } } - if (tm->tm_isdst != isdst) { - fprintf(fil, "#isdst %d\n", tm->tm_isdst); + + if (tm->tm_isdst != isdst || info[0] != '\0') { + fprintf(fil, "#%sisdst %d\n", info, tm->tm_isdst); } pos1 = ftell(fil); strftime(stim, sizeof stim,"%H:%M:%S", tm); @@ -367,394 +362,9 @@ Logger *LoggerMake(char *name, int period, int exact) { return log; } /*--------------------------------------------------------------------------*/ -#ifndef TECS_LOG -typedef enum { NUMERIC, TEXT } CompType; - -typedef struct { - SConnection *pCon; - char *var; - int exact; - CompType type; - time_t step; - time_t tlim; - time_t tmin, tmax, tlast, told; - float ymin, ymax, ylast, yold; - char slast[256]; - char set[256]; - int np; -} Compressor; - -static char *dir2 = NULL; - -static void LoggerInitC(Compressor *c, SConnection *pCon, time_t step) { - c->pCon = pCon; - c->step = step; - c->tmin = -2; - c->tmax = 0; - c->tlast = 0; - c->tlim = 0; - c->told = 0; - c->slast[0]='\0'; - c->ylast = LOGGER_NAN; -} - -static void LoggerOutStr(Compressor *c, time_t t, char *str) { - char line[256]; - - /* printf("out %ld %g\n", t, y); */ - if (0 != strcmp(str, c->slast)) { - snprintf(line, sizeof line, "%ld %s\n", (long)(t - c->tlast), str); - c->tlast = t; - c->slast[0]='\0'; - strncat(c->slast, str, sizeof c->slast - 1); - SCWrite(c->pCon, line, eWarning); - c->np--; - } -} - -static void LoggerOut(Compressor *c, time_t t, float y) { - char line[80]; - - /* printf("out %ld %g\n", t, y); */ - if (y != c->ylast || !c->exact) { - c->ylast = y; - if (y == LOGGER_NAN) { - snprintf(line, sizeof line, "%ld\n", (long)(t - c->tlast)); - } else { - snprintf(line, sizeof line, "%ld %g\n", (long)(t - c->tlast), y); - } - /* printf("-%s\n", line); */ - c->tlast = t; - SCWrite(c->pCon, line, eWarning); - c->np--; - } -} - -static void LoggerPut(Compressor *c, time_t t, char *value) { - char *p; - double y; - - if (c->var) { - SCPrintf(c->pCon, eWarning, "*%s exact %d\n", c->var, c->exact); - c->var = NULL; - } - if (c->type == NUMERIC) { - if (t == 0) { /* finish */ - t = c->tlim + 3 * c->step; - y = 0; - } else { - y = strtod(value, &p); - if (p == value) { - y = LOGGER_NAN; - } else { - if (y == LOGGER_NAN) y *= 1.0000002; - } - } - /* printf("put %ld %g\n", t, y); */ - if (c->tlim == 0) goto first; - if (t >= c->tlim) { - c->tlim += c->step; - if (c->tmin > c->tmax) { - LoggerOut(c, c->tmax, c->ymax); - c->ymax = c->ymin; - c->tmax = c->tmin; - } else { - LoggerOut(c, c->tmin, c->ymin); - if (c->tmin == c->tmax) goto first; - c->ymin = c->ymax; - c->tmin = c->tmax; - } - if (t >= c->tlim) { - LoggerOut(c, c->tmin, c->ymin); - if (t >= c->tlim + c->step) { - LoggerOut(c, c->told, c->yold); - } - goto first; - } - } - if (y <= c->ymin) { - c->ymin = y; - c->tmin = t; - } else if (y > c->ymax) { - c->ymax = y; - c->tmax = t; - } - c->yold = y; - c->told = t; - return; - first: - c->tlim = t + 2 * c->step; - c->tmin = t; - c->tmax = t; - c->ymin = y; - c->ymax = y; - return; - } else if (c->type == TEXT) { - if (t != 0) LoggerOutStr(c, t, value); - } -} -/*--------------------------------------------------------------------------*/ -int LoggerGraph(SConnection *pCon, SicsInterp *pSics, void *pData, - int argc, char *argv[]) { - time_t from, to, step, xs, lastt, now; - long lxs; - char *p; - int i, iarg0, l, iret, loss, np; - int inRange; - int yday=0; - time_t t, startim; - struct tm tm; - char stim[32], path[256], line[256], lastval[256]; - char *lin, *val, *stp; - FILE *fil; - Compressor c; - float yy, lasty; - CompType type0; - DIR *dr; - char *opt; - int isdst; - int overflow; - - /* argtolower(argc, argv); */ - if (argc < 4) goto illarg; - now = time(NULL); - from = strtol(argv[1], &p, 0); /* unix time, not year 2038 safe */ - if (p == argv[1]) goto illarg; - to = strtol(argv[2], NULL, 0); - if (p == argv[2]) goto illarg; - if (from < ONE_YEAR) { - from += now; - } - if (to < ONE_YEAR) { - to += now; - } - iarg0 = 4; - if (strcasecmp(argv[3],"text") == 0) { /* non-numeric values */ - step = 1; - type0 = TEXT; - np = from - to + 2; - } else if (strcasecmp(argv[3],"np") == 0) { /* max. number of points */ - type0 = NUMERIC; - iarg0 = 5; - np = strtol(argv[4], NULL, 0); - if (to <= from) { - step = 1; - } else if (np <= 2) { - step = to - from; - } else { - step = (to - from) / (np - 2) + 1; - } - } else { - step = strtol(argv[3], NULL, 0); - if (step <= 0) step = 1; - type0 = NUMERIC; - np = (from - to) / step + 2; - } - if (p == argv[3]) goto illarg; - if (step <= 0) step = 1; - - snprintf(line, sizeof line, "%ld\n", (long)now); - SCWrite(pCon, line, eWarning); - - if (dir == NULL) { - dir = IFindOption(pSICSOptions, "LoggerDir"); - if (dir == NULL) { - SCWrite(pCon, "LoggerDir not found", eError); - return 0; - } - LoggerSetDir(dir); - } - if (dir2 == NULL) { - dir2 = IFindOption(pSICSOptions, "LoggerDir2"); - if (dir2 == NULL) dir2=""; - } - - loss = 0; - overflow = 0; - for (i=iarg0; inext; @@ -765,8 +375,3 @@ void LoggerFreeAll(void *data) { } list = NULL; } -/*--------------------------------------------------------------------------*/ -void LoggerInit(void) { - AddCommand(pServ->pSics,"Graph",LoggerGraph,LoggerFreeAll,NULL); -} -#endif /* TECS_LOG */ diff --git a/logger.h b/logger.h index 9fbe820..061a733 100644 --- a/logger.h +++ b/logger.h @@ -22,5 +22,7 @@ void LoggerWriteOld(Logger *log, time_t now); time_t LoggerLastTime(Logger *log); int LoggerGetStatus(Logger *log); void LoggerSetStatus(Logger *log, int status); +int LoggerVarPath(char *dir, char *path, int pathLen, char *name); +void LoggerFreeAll(void); #endif diff --git a/make_gen b/make_gen index d752ef3..131276f 100644 --- a/make_gen +++ b/make_gen @@ -19,7 +19,7 @@ OBJ=psi.o buffer.o ruli.o dmc.o nxsans.o nextrics.o sps.o pimotor.o \ $(MZOBJ) amordrive.o amorset.o \ dgrambroadcast.o sinq.o tabledrive.o -MZOBJ=fsm.o logger.o sugar.o pardef.o ease.o strobj.o oxinst.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 libpsi.a: $(OBJ) diff --git a/oxinst.c b/oxinst.c index 5e59bec..3b9839d 100644 --- a/oxinst.c +++ b/oxinst.c @@ -18,11 +18,44 @@ is not changed, i.e. an existing errCode is not overwritten. #include "sics.h" #include "oxinst.h" - +/*----------------------------------------------------------------------------*/ +char *OxiCorrect(char *str) { + /* there are sometimes communication errors with the IGH + as the errors always follow the same pattern, they can + be corrected, with the following code. The argument + is corrected in place, the result is NULL or a text + describing the conversion */ + int i; + unsigned char chr; + static char buf[32]; + char *result = NULL; + + for (i=0; i<=24; i++, str++) { + chr = *str; + if (chr == 0) return result; + if (chr > 0x60) { + if (chr > 0xC0) { + chr -= 0x80; + } else { + chr -= 0x40; + } + snprintf(buf, sizeof buf, "%2.2x->%2.2x (%c)", *str, chr, chr); + *str = chr; + result = buf; + } + } + if (result) { + strcat(buf, " overflow"); + return result; + } else { + return "overflow"; + } +} /*----------------------------------------------------------------------------*/ int OxiHandler(void *object) { int iret, l; EaseBase *eab = EaseBaseCast(object); + char *corr; if (eab->state < EASE_idle) goto quit; if (availableNetRS232(eab->ser) || availableRS232(eab->ser)) { @@ -36,6 +69,12 @@ int OxiHandler(void *object) { goto quit; } if (iret == 1) { + if (eab->syntax <= -8) { + corr = OxiCorrect(eab->ans); + if (corr) { + ParPrintf(eab, eWarning, "corrected bad response from IGH: %s", corr); + } + } ParPrintf(eab, -2, "ans: %s", eab->ans); if (strcmp(eab->ans, "??ck") == 0) { if (eab->state == EASE_lost) { @@ -84,13 +123,13 @@ quit: return EaseHandler(eab); } -double OxiGet(EaseBase *eab, int dig, int *pdig) { +double OxiGet(EaseBase *eab, int dig, int *pdig, double old) { char *endp, *p; double val; if (eab->state != EASE_read) { - /* eab->errCode = EASE_ILL_ANS; */ - return 0.0; + eab->errCode = EASE_ILL_ANS; + return old; } p = strchr(eab->ans, '.'); if (p) { @@ -100,13 +139,13 @@ double OxiGet(EaseBase *eab, int dig, int *pdig) { val=strtod(eab->ans+1, &endp); if (*endp != '\0') { eab->errCode = EASE_ILL_ANS; - return 0.0; + return old; } } else { val=strtol(eab->ans+1, &endp, 10); if (*endp != '\0') { eab->errCode = EASE_ILL_ANS; - return 0.0; + return old; } if (eab->syntax <= 0) { /* old style format */ for (; dig > 0; dig--) val=val*0.1; diff --git a/oxinst.h b/oxinst.h index 9e92428..7634ed7 100644 --- a/oxinst.h +++ b/oxinst.h @@ -12,8 +12,14 @@ Markus Zolliker, March 2005 #include "ease.h" int OxiHandler(void *eab); -double OxiGet(EaseBase *eab, int dig, int *pdig); +double OxiGet(EaseBase *eab, int dig, int *pdig, double old); void OxiSet(EaseBase *eab, char *cmd, double val, int dig); +/* usage of the syntax field of EaseBase: + syntax <= 0: old syntax, in general without decimal point + syntax > 0: new syntax, in general decimal point given + + syntax <= -8: error correction on input (ascii codes >= 96 are corrected) +*/ #endif diff --git a/pardef.h b/pardef.h index cdcfd36..a1910d9 100644 --- a/pardef.h +++ b/pardef.h @@ -133,7 +133,7 @@ typedef struct ParData { void ParTail(char *tail); /* comment to appear after list entry (e.g. units). If ParList is not called, ParTail will force to appear in standard list. */ - void ParLogAs(char *name); /* switch log on and give sugar name (NULL for default name) */ + void ParLogAs(char *name); /* switch log on and give sugar name (NULL for no logging) */ /* Parameter type definitions: diff --git a/psi.c b/psi.c index aacf971..1aab88f 100644 --- a/psi.c +++ b/psi.c @@ -62,7 +62,7 @@ void SiteInit(void) { /* insert here initialization routines ... */ - INIT(LoggerInit); + INIT(LogReaderInit); INIT(IlmStartup); INIT(IpsStartup); INIT(ItcStartup);