diff --git a/euro2kdriv.c b/euro2kdriv.c index 8d715f5..2768d00 100644 --- a/euro2kdriv.c +++ b/euro2kdriv.c @@ -53,14 +53,18 @@ typedef struct { int mode; char *script; int warned; - float temperature; + float value; float output; float position; float range; float asymmetry; float setpoint; + float pbPow; + float pbMin; + float pbScl; Euro2kPar *pars, *readPar; Statistics *stat; + double lastRd; } Euro2k; static ParClass euro2kClass = { "EURO2K", sizeof(Euro2k) }; @@ -135,6 +139,7 @@ static int Euro2kMakePar(void *object, void *userarg, int argc, char *argv[]) if (par->fmt) par->fmt = strdup(par->fmt); ParInitPar(object, par->name); EaseParHasChanged(); + drv->readPar = NULL; return 1; Usage: ParPrintf(object, eError, "Usage: %s makepar [w] [int|time] adr [unit] [fmt]" @@ -152,7 +157,7 @@ void Euro2kParDef(void *object) { static char *modeList[]={"auto", "manual", NULL }; ParName(""); ParTail(drv->unit); - ParFloat(&drv->temperature, PAR_NAN); + ParFloat(&drv->value, PAR_NAN); ParName("unit"); ParAccess(usUser); ParLogAs(NULL); ParStr(&drv->unit, "C"); @@ -160,11 +165,15 @@ void Euro2kParDef(void *object) { ParName("mode"); ParEnum(modeList); ParList(0); EaseUpdate(EURO2K_MODE); ParInt(&drv->mode, 1); + ParName("pbPow"); ParAccess(usUser); ParFloat(&drv->pbPow, 0.0); + ParName("pbMin"); ParAccess(usUser); ParFloat(&drv->pbMin, 8.0); + ParName("pbScl"); ParAccess(usUser); ParFloat(&drv->pbScl, 3.0); + ParName("output"); ParTail("%"); ParFloat(&drv->output, PAR_NAN); ParName("position"); ParTail("%"); - ParFloat(&drv->position, PAR_NAN); + ParFloat(&drv->position, 50.0); ParName("asymmetry"); ParAccess(usUser); ParFloat(&drv->asymmetry, PAR_NAN); @@ -250,22 +259,31 @@ void Euro2kParDef(void *object) { free(par); } drv->pars = NULL; + drv->readPar = NULL; if (drv->stat) { StatisticsKill(drv->stat); } } } + +double getTime(void) { + struct timeval tv; + gettimeofday(&tv, NULL); + return tv.tv_sec + 1.0e-6 * tv.tv_usec; +} + /*----------------------------------------------------------------------------*/ static long Euro2kRead(long pc, void *object) { Euro2k *drv = ParCast(&euro2kClass, object); EaseBase *eab = object; - Euro2kPar *par; + Euro2kPar *par, *par0; Tcl_Interp *pTcl = NULL; char *p; int l, m, iRet; - float dif, a; + float dif, a, pb; char buf[4]; Statistics *old; + double now, delta; switch (pc) { default: /* FSM BEGIN *******************************/ if (drv->script && drv->script[0] != '\0' && 0 != strcmp(drv->script, "0")) { @@ -292,14 +310,23 @@ static long Euro2kRead(long pc, void *object) { } skipMode: - ModBusRequestFloats(eab, 1, 3); + ModBusRequestValues(eab, 1, 9); return __LINE__; case __LINE__: /**********************************/ - drv->temperature = ModBusGetFloat(eab, 1); + drv->value = ModBusGet(eab, 1, modBusFloat); if (!EaseGetUpdate(drv, EURO2K_SET)) { - drv->setpoint = ModBusGetFloat(eab, 2); + drv->setpoint = ModBusGet(eab, 2, modBusFloat); } - drv->output = ModBusGetFloat(eab, 3); - a = drv->output * eab->p.period / drv->range; + drv->output = ModBusGet(eab, 3, modBusFloat); + for (par = drv->pars; par != NULL; par = par->next) { + if (par->adr > 3 && par->adr <= 9 && par->set != to_set) { + par->par = ModBusGet(eab, par->adr, par->type); + } + } + now = getTime(); + delta = now - drv->lastRd; + drv->lastRd = now; + if (delta > 10) delta = 10; + a = drv->output * delta / drv->range; if ((drv->position > 50.) == (drv->output > 0)) { drv->position += a * (1 - drv->asymmetry * 0.01); } else { @@ -307,10 +334,24 @@ static long Euro2kRead(long pc, void *object) { } 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; + + if (drv->pbPow <= 0.0) goto getPars; + pb = drv->pbMin + pow(drv->value * drv->pbScl, drv->pbPow); + if (pb > 999.) pb=999.; + ModBusPutValue(eab, 6, modBusFloat, pb); + + return __LINE__; case __LINE__: /**********************************/ + getPars: + par = drv->readPar; + par0 = par; + do { + if (par == NULL) { + par = drv->pars; + } else { + par = par->next; + } + if (par == par0) goto skipPar; + } while (par == NULL || par->adr <= 9 || par->set == to_set); ModBusRequestValue(eab, par->adr, par->type); drv->readPar = par; return __LINE__; case __LINE__: /**********************************/ @@ -319,14 +360,12 @@ static long Euro2kRead(long pc, void *object) { par->par = ModBusGetValue(eab, par->type); } skipPar: - par = par->next; - goto loop; - - finish: if (eab->p.verbose >= 3) { eab->p.verbose--; if (eab->p.verbose < 3) eab->p.verbose=0; } + + finish: ParLog(drv); fsm_quit: return 0; } /* FSM END *********************************/ } @@ -410,8 +449,10 @@ static int Euro2kInit(SConnection *con, int argc, char *argv[], int dynamic) { Euro2kSet); if (drv == NULL) return 0; drv->pars = NULL; + drv->readPar = NULL; snprintf(sn, sizeof sn, "%s task", argv[1]); drv->stat = StatisticsNew(sn); + drv->lastRd = getTime(); setRS232ReplyTerminator(drv->d.b.ser,""); setRS232SendTerminator(drv->d.b.ser,""); return 1;