From f6e5826e19074940d2832fc5642163f5cebcd2a8 Mon Sep 17 00:00:00 2001 From: zolliker Date: Thu, 19 Feb 2009 13:28:52 +0000 Subject: [PATCH] - various enhancements in drivers --- euro2kdriv.c | 152 +++++++++++++++++++++++++++++++++++++++++---------- haakedriv.c | 45 +++++++++++---- ighdriv.c | 2 +- lsc370driv.c | 24 +++++++- modbus.c | 16 +++++- pardef.c | 1 + 6 files changed, 193 insertions(+), 47 deletions(-) diff --git a/euro2kdriv.c b/euro2kdriv.c index e5d9b65..3f3741b 100644 --- a/euro2kdriv.c +++ b/euro2kdriv.c @@ -59,12 +59,10 @@ typedef struct { float range; float asymmetry; float setpoint; - float pbPow; - float pbMin; - float pbScl; - Euro2kPar *pars, *readPar; + Euro2kPar *pars, *readPar, *setPar; Statistics *stat; double lastRd; + char *model; } Euro2k; static ParClass euro2kClass = { "EURO2K", sizeof(Euro2k) }; @@ -169,6 +167,7 @@ void Euro2kParDef(void *object) Euro2kPar *par, *next; FILE *saveFile; char *w, *t, *u, *f; + float old; static char *modeList[] = { "auto", "manual", NULL }; @@ -177,9 +176,11 @@ void Euro2kParDef(void *object) ParFloat(&drv->value, PAR_NAN); ParName("unit"); - ParAccess(usUser); + if (drv->unit == NULL) { + ParAccess(usUser); + } ParLogAs(NULL); - ParStr(&drv->unit, "C"); + ParStr(&drv->unit, NULL); ParName("mode"); ParEnum(modeList); @@ -187,15 +188,26 @@ void Euro2kParDef(void *object) EaseUpdate(EURO2K_MODE); ParInt(&drv->mode, 1); + ParName("model"); + ParLogAs(NULL); + ParStr(&drv->model, NULL); + + /* + 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); + */ + + old = 0.0; ParName("pbPow"); - ParAccess(usUser); - ParFloat(&drv->pbPow, 0.0); + ParSave(0); + ParFloat(&old, 0.0); ParName("pbMin"); - ParAccess(usUser); - ParFloat(&drv->pbMin, 8.0); + ParSave(0); + ParFloat(&old, 0.0); ParName("pbScl"); - ParAccess(usUser); - ParFloat(&drv->pbScl, 3.0); + ParSave(0); + ParFloat(&old, 0.0); ParName("output"); ParTail("%"); @@ -256,7 +268,11 @@ void Euro2kParDef(void *object) } ParName(par->name); if (par->unit) { - ParTail(par->unit); + if (strcmp(par->unit, "@") == 0) { + ParTail(drv->unit); + } else { + ParTail(par->unit); + } } else { ParList(NULL); } @@ -265,10 +281,17 @@ void Euro2kParDef(void *object) } if (par->set >= settable) { if (EaseUpdate(EURO2K_PAR)) { - par->set = to_set; + old = par->par; + ParFloat(&par->par, PAR_NAN); + if (fabsf(par->par - old) > 1e-5 * (par->par + old)) { + par->set = to_set; + } + } else { + ParFloat(&par->par, PAR_NAN); } + } else { + ParFloat(&par->par, PAR_NAN); } - ParFloat(&par->par, PAR_NAN); } } @@ -313,6 +336,20 @@ double getTime(void) return tv.tv_sec + 1.0e-6 * tv.tv_usec; } +/*----------------------------------------------------------------------------*/ +float Euro2kGet(EaseBase * eab, Euro2kPar * par) +{ + /* a hack for converting different time formats on 2216 and 3216 models) */ + float value; + + value = ModBusGet(eab, par->adr, par->type); + if (par->type == modBusTime && value > 100000.0) { + par->type = modBusFloat; + value = ModBusGet(eab, par->adr, par->type); + } + return value; +} + /*----------------------------------------------------------------------------*/ static long Euro2kRead(long pc, void *object) { @@ -368,7 +405,7 @@ static long Euro2kRead(long pc, void *object) 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); + par->par = Euro2kGet(eab, par); } } now = getTime(); @@ -387,16 +424,15 @@ static long Euro2kRead(long pc, void *object) if (drv->position > 100) drv->position = 100; - if (drv->pbPow <= 0.0) - goto getPars; +/* + if (drv->pbPow <= 0.0) goto getPars; pb = drv->pbMin + pow(drv->value * drv->pbScl, drv->pbPow); - if (pb > 999.) - pb = 999.; + if (pb > 999.) pb=999.; ModBusPutValue(eab, 6, modBusFloat, pb); - - return __LINE__; - case __LINE__: /**********************************/ + + return __LINE__; case __LINE__: getPars: +*/ par = drv->readPar; par0 = par; do { @@ -414,7 +450,7 @@ static long Euro2kRead(long pc, void *object) case __LINE__: /**********************************/ par = drv->readPar; if (par->set != to_set) { - par->par = ModBusGetValue(eab, par->type); + par->par = Euro2kGet(eab, par); } skipPar: if (eab->p.verbose >= 3) { @@ -439,6 +475,7 @@ static long Euro2kSet(long pc, void *object) int l; int upd; char buf[4]; + float value; switch (pc) { default: /* FSM BEGIN ****************************** */ @@ -454,16 +491,22 @@ static long Euro2kSet(long pc, void *object) goto run; for (par = drv->pars; par != NULL; par = par->next) { if (par->set == to_set) { - ModBusPutValue(eab, par->adr, par->type, par->par); - par->set = settable; - goto setIt; + ModBusRequestValue(eab, par->adr, par->type); + goto readIt; } } goto fsm_quit; run: + ModBusRequestValue(eab, 2, modBusFloat); + return __LINE__; + case __LINE__: /**********************************/ + value = ModBusGetValue(eab, modBusFloat); + if (fabsf(value - drv->setpoint) <= 1e-5 * (value + drv->setpoint)) + goto skipset; ModBusPutFloats(eab, 2, 1, &drv->setpoint); return __LINE__; case __LINE__: /**********************************/ + skipset: if (drv->mode == 0) goto loop; drv->mode = 0; @@ -474,6 +517,18 @@ static long Euro2kSet(long pc, void *object) return __LINE__; case __LINE__: /**********************************/ ModBusPutValue(eab, 273, modBusInt, drv->mode); /* set manual to 0 */ + goto setIt; + readIt: + drv->setPar = par; + return __LINE__; + case __LINE__: /**********************************/ + par = drv->setPar; + value = Euro2kGet(eab, par); + par->set = settable; + if (fabsf(par->par - value) <= 0.00001 * fabsf(par->par + value)) { + goto loop; + } + ModBusPutValue(eab, par->adr, par->type, par->par); setIt: return __LINE__; case __LINE__: /**********************************/ @@ -488,17 +543,54 @@ static long Euro2kStart(long pc, void *object) { Euro2k *drv = ParCast(&euro2kClass, object); EaseBase *eab = object; + int number; + char hex[8]; switch (pc) { default: /* FSM BEGIN ****************************** */ - ModBusRequestValue(eab, 1, modBusFloat); + ModBusRequestValue(eab, 122, modBusInt); return __LINE__; case __LINE__: /**********************************/ - if (0 == ModBusGetValue(eab, modBusFloat)) { + if (eab->state != EASE_read) { ParPrintf(drv, eError, "bad or no response on ModBus"); goto quit; } - ParPrintf(drv, eLog, "connected to euro2k"); + number = ModBusGetValue(eab, modBusInt); + if (drv->model != NULL) { + free(drv->model); + } + snprintf(hex, sizeof hex, "%4.4X", number); + if (hex[0] == 'E') + hex[0] = '3'; + if (hex[2] == '3') { + hex[3] = '2'; + } else if (hex[2] == '6') { + hex[2] = '1'; + hex[3] = '6'; + } else { + hex[2] = '0'; + hex[3] = hex[2]; + } + drv->model = strdup(hex); + ModBusRequestValue(eab, 107, modBusInt); + return __LINE__; + case __LINE__: /**********************************/ + number = ModBusGetValue(eab, modBusInt); + snprintf(eab->version, sizeof(eab->version), "%s V%4.4X", drv->model, + number); + ParPrintf(drv, eLog, "connected to Eurotherm %s", eab->version); + if (drv->unit != NULL) + goto unitGiven; + ModBusRequestValue(eab, 516, modBusInt); + return __LINE__; + case __LINE__: /**********************************/ + number = ModBusGetValue(eab, modBusInt); + if (number == 0) { + drv->unit = strdup("C"); + } else if (number == 2) { + drv->unit = strdup("K"); + } + unitGiven: ModBusPutValue(eab, 111, modBusFloat, drv->d.upperLimit); return __LINE__; case __LINE__: /**********************************/ diff --git a/haakedriv.c b/haakedriv.c index 267dbc4..38bcbce 100644 --- a/haakedriv.c +++ b/haakedriv.c @@ -36,6 +36,8 @@ Markus Zolliker, Nov 2006 typedef struct { EaseDriv d; + char *unit; + float kelvin; float t; float t2; float set; @@ -147,19 +149,26 @@ static void HaakeParDef(void *object) ParName(""); ParFmt("%.2f"); - ParTail("K"); + ParTail(drv->unit); ParFloat(&drv->t, PAR_NAN); + ParName("unit"); + if (drv->unit == NULL) { + ParAccess(usUser); + } + ParLogAs(NULL); + ParStr(&drv->unit, NULL); + ParName("t2"); - if (drv->with2sensors) { + if (drv->with2sensors > 0) { ParFmt("%.2f"); - ParTail("K"); + ParTail(drv->unit); } ParFloat(&drv->t2, PAR_NAN); ParName("set"); ParFmt("%.2f"); - ParTail("K"); + ParTail(drv->unit); ParFloat(&drv->set, PAR_NAN); ParName("running"); @@ -200,7 +209,7 @@ static void HaakeParDef(void *object) EaseBasePar(drv); EaseSendPar(drv); - EaseDrivPar(drv, "%.2f", "K"); + EaseDrivPar(drv, "%.2f", drv->unit); ParStdDef(); EaseMsgPar(drv); } @@ -236,13 +245,13 @@ static long HaakeRead(long pc, void *object) EaseWrite(eab, "F1"); return __LINE__; case __LINE__: /**********************************/ - drv->t = atof(eab->ans) + 273.15; - if (!drv->with2sensors) + drv->t = atof(eab->ans) + drv->kelvin; + if (drv->with2sensors < 1) goto nof2; EaseWrite(eab, "F2"); return __LINE__; case __LINE__: /**********************************/ - drv->t2 = atof(eab->ans) + 273.15; + drv->t2 = atof(eab->ans) + drv->kelvin; if (drv->t2 < -222) { drv->t2 = PAR_NAN; } @@ -250,7 +259,7 @@ static long HaakeRead(long pc, void *object) EaseWrite(eab, "S"); return __LINE__; case __LINE__: /**********************************/ - drv->set = atof(eab->ans) + 273.15; + drv->set = atof(eab->ans) + drv->kelvin; skipGetSet: ParLog(drv); @@ -263,6 +272,7 @@ static long HaakeStart(long pc, void *object) { Haake *drv = ParCast(&haakeClass, object); EaseBase *eab = object; + char unitcmd[8] = "W TE K"; switch (pc) { default: /* FSM BEGIN ****************************** */ @@ -276,8 +286,18 @@ static long HaakeStart(long pc, void *object) EaseStop(eab); goto quit; } - ParPrintf(drv, eLog, "connected to haake thermostat %s", eab->version); - EaseWrite(eab, "W TE K"); + ParPrintf(drv, eLog, "connected to haake thermostat %s", + eab->version); + if (drv->unit == NULL) { + drv->unit = strdup("K"); + } + if (*drv->unit == 'C') { + EaseWrite(eab, "W TE C"); + drv->kelvin = 0; + } else { + EaseWrite(eab, "W TE K"); + drv->kelvin = 273.15; + } return __LINE__; case __LINE__: /**********************************/ FsmCall(HaakeRead); @@ -302,7 +322,8 @@ static long HaakeSet(long pc, void *object) upd = EaseNextUpdate(drv); switch (upd) { case EASE_RUN: - snprintf(cmd, sizeof cmd, "w sw %.5g", drv->d.targetValue - 273.17); + snprintf(cmd, sizeof cmd, "w sw %.5g", + drv->d.targetValue - drv->kelvin); break; case HAAKE_ON: snprintf(cmd, sizeof cmd, "w ts%d", drv->running); diff --git a/ighdriv.c b/ighdriv.c index 9b5fdf9..48e7d5c 100644 --- a/ighdriv.c +++ b/ighdriv.c @@ -311,8 +311,8 @@ void IghStatus(Igh * drv) } else { drv->v[i] = 0; } - p = p * 2; } + p *= 2; } drv->a = ans[3] - '0'; drv->s = ans[16] - '0'; diff --git a/lsc370driv.c b/lsc370driv.c index 1f5e9ff..9c943f0 100644 --- a/lsc370driv.c +++ b/lsc370driv.c @@ -54,6 +54,7 @@ typedef struct { int range; int autoRange; int index; + int controlChan; } Lsc370; static ParClass lsc370Class = { "LSC370", sizeof(Lsc370) }; @@ -126,7 +127,11 @@ static void Lsc370ParDef(void *object) ParName("set"); ParTail("K"); - ParFloat(&drv->set, PAR_NAN); + if (EaseUpdate(EASE_RUN)) { + ParFloat(&drv->d.targetValue, PAR_NAN); + } else { + ParFloat(&drv->set, PAR_NAN); + } ParName("htr"); ParTail("%"); @@ -174,6 +179,11 @@ static void Lsc370ParDef(void *object) ParAccess(usUser); ParInt(&drv->ighHeater, -1); + ParName("controlChan"); + ParList(NULL); + ParAccess(usUser); + ParInt(&drv->controlChan, 1); + ParName("currentEx"); EaseUpdate(RDGRNG_FLAG); ParEnum(currentList); @@ -276,6 +286,10 @@ static long Lsc370Read(long pc, void *object) default: /* FSM BEGIN ****************************** */ drv->index = 0; chanLoop: + if (drv->channel[drv->index] == 0) { + drv->temp[drv->index] == PAR_NAN; + goto noRead; + } snprintf(buf, sizeof buf, "RDGK?%d", drv->channel[drv->index]); EaseWrite(eab, buf); return __LINE__; @@ -284,6 +298,8 @@ static long Lsc370Read(long pc, void *object) if (1 == sscanf(eab->ans, "%f", &x)) { drv->temp[drv->index] = x; } + + noRead: drv->index++; if (drv->index < MAX_CHAN) goto chanLoop; @@ -332,6 +348,9 @@ static long Lsc370Read(long pc, void *object) goto skipHtrRng; if (1 == sscanf(eab->ans, "%d", &rng)) { drv->htrRange = rng; + if (rng == 0) { + drv->set = 0; + } } skipHtrRng: @@ -427,7 +446,8 @@ static long Lsc370Set(long pc, void *object) /* fall through */ htrrng: - snprintf(cmd, sizeof cmd, "CSET 1,1,1,1,1,8,%g;CSET?", drv->resist); + snprintf(cmd, sizeof cmd, "CSET %d,1,1,1,1,8,%g;CSET?", + drv->controlChan, drv->resist); EaseWrite(eab, cmd); return __LINE__; case __LINE__: /**********************************/ diff --git a/modbus.c b/modbus.c index 52d328b..36cd8de 100644 --- a/modbus.c +++ b/modbus.c @@ -296,6 +296,7 @@ int ModBusHandler(void *object) eab->cmd[3] = 0; eab->cmd[4] = 44; eab->cmd[5] = 55; + ParPrintf(eab, -2, "loopback"); ModBusWrite(eab, 6); eab->state = EASE_lost; } @@ -324,6 +325,11 @@ void ModBusPutFloats(EaseBase * eab, int adr, int npar, float val[]) double2ieee(val[n], eab->cmd + l); l += 4; } + if (npar == 1) { + ParPrintf(eab, -1, "write #%d %.5g", adr, val[0]); + } else { + ParPrintf(eab, -1, "write #%d %.5g %.5g ... (%d)", adr, val[0], val[1], npar); + } ModBusWrite(eab, l); } @@ -337,6 +343,7 @@ void ModBusRequestValues(EaseBase * eab, int adr, int npar) eab->cmd[1] = 3; /* read n words */ fadr2word(adr, eab->cmd + 2); uint2word(npar * 2, eab->cmd + 4); + ParPrintf(eab, -2, "read #%d (%d values)", adr, npar); ModBusWrite(eab, 6); } @@ -363,14 +370,16 @@ static double ModBus2double(char ieee[4]) float ModBusGet(EaseBase * eab, int adr, int type) { int startAdr; - int i; + int i, n; if (eab->state != EASE_read) { return 0.0; } + n = word2uint(eab->cmd + 4); + if (n <= 2) return ModBusGetValue(eab, type); startAdr = word2fadr(eab->cmd + 2); i = adr - startAdr; - if (i < 0 || i >= word2uint(eab->cmd + 4)) { + if (i < 0 || i >= n) { return 0.0; } if (type == modBusTime) { @@ -392,6 +401,7 @@ void ModBusRequestValue(EaseBase * eab, int adr, int type) fadr2word(adr, eab->cmd + 2); uint2word(2, eab->cmd + 4); } + ParPrintf(eab, -2, "read #%d", adr); ModBusWrite(eab, 6); } @@ -407,6 +417,7 @@ void ModBusPutValue(EaseBase * eab, int adr, int type, float val) uint2word(1, eab->cmd + 4); eab->cmd[6] = 2; uint2word((int) (val), eab->cmd + 7); + ParPrintf(eab, -1, "write #%d %.5g", adr, val); ModBusWrite(eab, 9); return; } @@ -422,6 +433,7 @@ void ModBusPutValue(EaseBase * eab, int adr, int type, float val) eab->cmd[9] = 0; eab->cmd[10] = 0; } + ParPrintf(eab, -1, "write #%d %.5g", adr, val); ModBusWrite(eab, 11); } diff --git a/pardef.c b/pardef.c index ce5accb..8a448fb 100644 --- a/pardef.c +++ b/pardef.c @@ -241,6 +241,7 @@ char *ParArg2Str(int argc, char *argv[], char *result, int maxsize) for (i = 0; i < argc; i++) { argsize += strlen(argv[i]) + 1; } + if (argsize == 0) argsize = 1; result = malloc(argsize); if (!result) return NULL;