- various enhancements in drivers

This commit is contained in:
zolliker
2009-02-19 13:28:52 +00:00
parent a0e7c9782b
commit f6e5826e19
6 changed files with 193 additions and 47 deletions

View File

@ -59,12 +59,10 @@ typedef struct {
float range; float range;
float asymmetry; float asymmetry;
float setpoint; float setpoint;
float pbPow; Euro2kPar *pars, *readPar, *setPar;
float pbMin;
float pbScl;
Euro2kPar *pars, *readPar;
Statistics *stat; Statistics *stat;
double lastRd; double lastRd;
char *model;
} Euro2k; } Euro2k;
static ParClass euro2kClass = { "EURO2K", sizeof(Euro2k) }; static ParClass euro2kClass = { "EURO2K", sizeof(Euro2k) };
@ -169,6 +167,7 @@ void Euro2kParDef(void *object)
Euro2kPar *par, *next; Euro2kPar *par, *next;
FILE *saveFile; FILE *saveFile;
char *w, *t, *u, *f; char *w, *t, *u, *f;
float old;
static char *modeList[] = { "auto", "manual", NULL }; static char *modeList[] = { "auto", "manual", NULL };
@ -177,9 +176,11 @@ void Euro2kParDef(void *object)
ParFloat(&drv->value, PAR_NAN); ParFloat(&drv->value, PAR_NAN);
ParName("unit"); ParName("unit");
ParAccess(usUser); if (drv->unit == NULL) {
ParAccess(usUser);
}
ParLogAs(NULL); ParLogAs(NULL);
ParStr(&drv->unit, "C"); ParStr(&drv->unit, NULL);
ParName("mode"); ParName("mode");
ParEnum(modeList); ParEnum(modeList);
@ -187,15 +188,26 @@ void Euro2kParDef(void *object)
EaseUpdate(EURO2K_MODE); EaseUpdate(EURO2K_MODE);
ParInt(&drv->mode, 1); 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"); ParName("pbPow");
ParAccess(usUser); ParSave(0);
ParFloat(&drv->pbPow, 0.0); ParFloat(&old, 0.0);
ParName("pbMin"); ParName("pbMin");
ParAccess(usUser); ParSave(0);
ParFloat(&drv->pbMin, 8.0); ParFloat(&old, 0.0);
ParName("pbScl"); ParName("pbScl");
ParAccess(usUser); ParSave(0);
ParFloat(&drv->pbScl, 3.0); ParFloat(&old, 0.0);
ParName("output"); ParName("output");
ParTail("%"); ParTail("%");
@ -256,7 +268,11 @@ void Euro2kParDef(void *object)
} }
ParName(par->name); ParName(par->name);
if (par->unit) { if (par->unit) {
ParTail(par->unit); if (strcmp(par->unit, "@") == 0) {
ParTail(drv->unit);
} else {
ParTail(par->unit);
}
} else { } else {
ParList(NULL); ParList(NULL);
} }
@ -265,10 +281,17 @@ void Euro2kParDef(void *object)
} }
if (par->set >= settable) { if (par->set >= settable) {
if (EaseUpdate(EURO2K_PAR)) { 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; 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) static long Euro2kRead(long pc, void *object)
{ {
@ -368,7 +405,7 @@ static long Euro2kRead(long pc, void *object)
drv->output = ModBusGet(eab, 3, modBusFloat); drv->output = ModBusGet(eab, 3, modBusFloat);
for (par = drv->pars; par != NULL; par = par->next) { for (par = drv->pars; par != NULL; par = par->next) {
if (par->adr > 3 && par->adr <= 9 && par->set != to_set) { 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(); now = getTime();
@ -387,16 +424,15 @@ static long Euro2kRead(long pc, void *object)
if (drv->position > 100) if (drv->position > 100)
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); pb = drv->pbMin + pow(drv->value * drv->pbScl, drv->pbPow);
if (pb > 999.) if (pb > 999.) pb=999.;
pb = 999.;
ModBusPutValue(eab, 6, modBusFloat, pb); ModBusPutValue(eab, 6, modBusFloat, pb);
return __LINE__; return __LINE__; case __LINE__:
case __LINE__: /**********************************/
getPars: getPars:
*/
par = drv->readPar; par = drv->readPar;
par0 = par; par0 = par;
do { do {
@ -414,7 +450,7 @@ static long Euro2kRead(long pc, void *object)
case __LINE__: /**********************************/ case __LINE__: /**********************************/
par = drv->readPar; par = drv->readPar;
if (par->set != to_set) { if (par->set != to_set) {
par->par = ModBusGetValue(eab, par->type); par->par = Euro2kGet(eab, par);
} }
skipPar: skipPar:
if (eab->p.verbose >= 3) { if (eab->p.verbose >= 3) {
@ -439,6 +475,7 @@ static long Euro2kSet(long pc, void *object)
int l; int l;
int upd; int upd;
char buf[4]; char buf[4];
float value;
switch (pc) { switch (pc) {
default: /* FSM BEGIN ****************************** */ default: /* FSM BEGIN ****************************** */
@ -454,16 +491,22 @@ static long Euro2kSet(long pc, void *object)
goto run; goto run;
for (par = drv->pars; par != NULL; par = par->next) { for (par = drv->pars; par != NULL; par = par->next) {
if (par->set == to_set) { if (par->set == to_set) {
ModBusPutValue(eab, par->adr, par->type, par->par); ModBusRequestValue(eab, par->adr, par->type);
par->set = settable; goto readIt;
goto setIt;
} }
} }
goto fsm_quit; goto fsm_quit;
run: 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); ModBusPutFloats(eab, 2, 1, &drv->setpoint);
return __LINE__; return __LINE__;
case __LINE__: /**********************************/ case __LINE__: /**********************************/
skipset:
if (drv->mode == 0) if (drv->mode == 0)
goto loop; goto loop;
drv->mode = 0; drv->mode = 0;
@ -474,6 +517,18 @@ static long Euro2kSet(long pc, void *object)
return __LINE__; return __LINE__;
case __LINE__: /**********************************/ case __LINE__: /**********************************/
ModBusPutValue(eab, 273, modBusInt, drv->mode); /* set manual to 0 */ 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: setIt:
return __LINE__; return __LINE__;
case __LINE__: /**********************************/ case __LINE__: /**********************************/
@ -488,17 +543,54 @@ static long Euro2kStart(long pc, void *object)
{ {
Euro2k *drv = ParCast(&euro2kClass, object); Euro2k *drv = ParCast(&euro2kClass, object);
EaseBase *eab = object; EaseBase *eab = object;
int number;
char hex[8];
switch (pc) { switch (pc) {
default: /* FSM BEGIN ****************************** */ default: /* FSM BEGIN ****************************** */
ModBusRequestValue(eab, 1, modBusFloat); ModBusRequestValue(eab, 122, modBusInt);
return __LINE__; return __LINE__;
case __LINE__: /**********************************/ case __LINE__: /**********************************/
if (0 == ModBusGetValue(eab, modBusFloat)) { if (eab->state != EASE_read) {
ParPrintf(drv, eError, "bad or no response on ModBus"); ParPrintf(drv, eError, "bad or no response on ModBus");
goto quit; 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); ModBusPutValue(eab, 111, modBusFloat, drv->d.upperLimit);
return __LINE__; return __LINE__;
case __LINE__: /**********************************/ case __LINE__: /**********************************/

View File

@ -36,6 +36,8 @@ Markus Zolliker, Nov 2006
typedef struct { typedef struct {
EaseDriv d; EaseDriv d;
char *unit;
float kelvin;
float t; float t;
float t2; float t2;
float set; float set;
@ -147,19 +149,26 @@ static void HaakeParDef(void *object)
ParName(""); ParName("");
ParFmt("%.2f"); ParFmt("%.2f");
ParTail("K"); ParTail(drv->unit);
ParFloat(&drv->t, PAR_NAN); ParFloat(&drv->t, PAR_NAN);
ParName("unit");
if (drv->unit == NULL) {
ParAccess(usUser);
}
ParLogAs(NULL);
ParStr(&drv->unit, NULL);
ParName("t2"); ParName("t2");
if (drv->with2sensors) { if (drv->with2sensors > 0) {
ParFmt("%.2f"); ParFmt("%.2f");
ParTail("K"); ParTail(drv->unit);
} }
ParFloat(&drv->t2, PAR_NAN); ParFloat(&drv->t2, PAR_NAN);
ParName("set"); ParName("set");
ParFmt("%.2f"); ParFmt("%.2f");
ParTail("K"); ParTail(drv->unit);
ParFloat(&drv->set, PAR_NAN); ParFloat(&drv->set, PAR_NAN);
ParName("running"); ParName("running");
@ -200,7 +209,7 @@ static void HaakeParDef(void *object)
EaseBasePar(drv); EaseBasePar(drv);
EaseSendPar(drv); EaseSendPar(drv);
EaseDrivPar(drv, "%.2f", "K"); EaseDrivPar(drv, "%.2f", drv->unit);
ParStdDef(); ParStdDef();
EaseMsgPar(drv); EaseMsgPar(drv);
} }
@ -236,13 +245,13 @@ static long HaakeRead(long pc, void *object)
EaseWrite(eab, "F1"); EaseWrite(eab, "F1");
return __LINE__; return __LINE__;
case __LINE__: /**********************************/ case __LINE__: /**********************************/
drv->t = atof(eab->ans) + 273.15; drv->t = atof(eab->ans) + drv->kelvin;
if (!drv->with2sensors) if (drv->with2sensors < 1)
goto nof2; goto nof2;
EaseWrite(eab, "F2"); EaseWrite(eab, "F2");
return __LINE__; return __LINE__;
case __LINE__: /**********************************/ case __LINE__: /**********************************/
drv->t2 = atof(eab->ans) + 273.15; drv->t2 = atof(eab->ans) + drv->kelvin;
if (drv->t2 < -222) { if (drv->t2 < -222) {
drv->t2 = PAR_NAN; drv->t2 = PAR_NAN;
} }
@ -250,7 +259,7 @@ static long HaakeRead(long pc, void *object)
EaseWrite(eab, "S"); EaseWrite(eab, "S");
return __LINE__; return __LINE__;
case __LINE__: /**********************************/ case __LINE__: /**********************************/
drv->set = atof(eab->ans) + 273.15; drv->set = atof(eab->ans) + drv->kelvin;
skipGetSet: skipGetSet:
ParLog(drv); ParLog(drv);
@ -263,6 +272,7 @@ static long HaakeStart(long pc, void *object)
{ {
Haake *drv = ParCast(&haakeClass, object); Haake *drv = ParCast(&haakeClass, object);
EaseBase *eab = object; EaseBase *eab = object;
char unitcmd[8] = "W TE K";
switch (pc) { switch (pc) {
default: /* FSM BEGIN ****************************** */ default: /* FSM BEGIN ****************************** */
@ -276,8 +286,18 @@ static long HaakeStart(long pc, void *object)
EaseStop(eab); EaseStop(eab);
goto quit; goto quit;
} }
ParPrintf(drv, eLog, "connected to haake thermostat %s", eab->version); ParPrintf(drv, eLog, "connected to haake thermostat %s",
EaseWrite(eab, "W TE K"); 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__; return __LINE__;
case __LINE__: /**********************************/ case __LINE__: /**********************************/
FsmCall(HaakeRead); FsmCall(HaakeRead);
@ -302,7 +322,8 @@ static long HaakeSet(long pc, void *object)
upd = EaseNextUpdate(drv); upd = EaseNextUpdate(drv);
switch (upd) { switch (upd) {
case EASE_RUN: 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; break;
case HAAKE_ON: case HAAKE_ON:
snprintf(cmd, sizeof cmd, "w ts%d", drv->running); snprintf(cmd, sizeof cmd, "w ts%d", drv->running);

View File

@ -311,8 +311,8 @@ void IghStatus(Igh * drv)
} else { } else {
drv->v[i] = 0; drv->v[i] = 0;
} }
p = p * 2;
} }
p *= 2;
} }
drv->a = ans[3] - '0'; drv->a = ans[3] - '0';
drv->s = ans[16] - '0'; drv->s = ans[16] - '0';

View File

@ -54,6 +54,7 @@ typedef struct {
int range; int range;
int autoRange; int autoRange;
int index; int index;
int controlChan;
} Lsc370; } Lsc370;
static ParClass lsc370Class = { "LSC370", sizeof(Lsc370) }; static ParClass lsc370Class = { "LSC370", sizeof(Lsc370) };
@ -126,7 +127,11 @@ static void Lsc370ParDef(void *object)
ParName("set"); ParName("set");
ParTail("K"); 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"); ParName("htr");
ParTail("%"); ParTail("%");
@ -174,6 +179,11 @@ static void Lsc370ParDef(void *object)
ParAccess(usUser); ParAccess(usUser);
ParInt(&drv->ighHeater, -1); ParInt(&drv->ighHeater, -1);
ParName("controlChan");
ParList(NULL);
ParAccess(usUser);
ParInt(&drv->controlChan, 1);
ParName("currentEx"); ParName("currentEx");
EaseUpdate(RDGRNG_FLAG); EaseUpdate(RDGRNG_FLAG);
ParEnum(currentList); ParEnum(currentList);
@ -276,6 +286,10 @@ static long Lsc370Read(long pc, void *object)
default: /* FSM BEGIN ****************************** */ default: /* FSM BEGIN ****************************** */
drv->index = 0; drv->index = 0;
chanLoop: 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]); snprintf(buf, sizeof buf, "RDGK?%d", drv->channel[drv->index]);
EaseWrite(eab, buf); EaseWrite(eab, buf);
return __LINE__; return __LINE__;
@ -284,6 +298,8 @@ static long Lsc370Read(long pc, void *object)
if (1 == sscanf(eab->ans, "%f", &x)) { if (1 == sscanf(eab->ans, "%f", &x)) {
drv->temp[drv->index] = x; drv->temp[drv->index] = x;
} }
noRead:
drv->index++; drv->index++;
if (drv->index < MAX_CHAN) if (drv->index < MAX_CHAN)
goto chanLoop; goto chanLoop;
@ -332,6 +348,9 @@ static long Lsc370Read(long pc, void *object)
goto skipHtrRng; goto skipHtrRng;
if (1 == sscanf(eab->ans, "%d", &rng)) { if (1 == sscanf(eab->ans, "%d", &rng)) {
drv->htrRange = rng; drv->htrRange = rng;
if (rng == 0) {
drv->set = 0;
}
} }
skipHtrRng: skipHtrRng:
@ -427,7 +446,8 @@ static long Lsc370Set(long pc, void *object)
/* fall through */ /* fall through */
htrrng: 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); EaseWrite(eab, cmd);
return __LINE__; return __LINE__;
case __LINE__: /**********************************/ case __LINE__: /**********************************/

View File

@ -296,6 +296,7 @@ int ModBusHandler(void *object)
eab->cmd[3] = 0; eab->cmd[3] = 0;
eab->cmd[4] = 44; eab->cmd[4] = 44;
eab->cmd[5] = 55; eab->cmd[5] = 55;
ParPrintf(eab, -2, "loopback");
ModBusWrite(eab, 6); ModBusWrite(eab, 6);
eab->state = EASE_lost; eab->state = EASE_lost;
} }
@ -324,6 +325,11 @@ void ModBusPutFloats(EaseBase * eab, int adr, int npar, float val[])
double2ieee(val[n], eab->cmd + l); double2ieee(val[n], eab->cmd + l);
l += 4; 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); ModBusWrite(eab, l);
} }
@ -337,6 +343,7 @@ void ModBusRequestValues(EaseBase * eab, int adr, int npar)
eab->cmd[1] = 3; /* read n words */ eab->cmd[1] = 3; /* read n words */
fadr2word(adr, eab->cmd + 2); fadr2word(adr, eab->cmd + 2);
uint2word(npar * 2, eab->cmd + 4); uint2word(npar * 2, eab->cmd + 4);
ParPrintf(eab, -2, "read #%d (%d values)", adr, npar);
ModBusWrite(eab, 6); ModBusWrite(eab, 6);
} }
@ -363,14 +370,16 @@ static double ModBus2double(char ieee[4])
float ModBusGet(EaseBase * eab, int adr, int type) float ModBusGet(EaseBase * eab, int adr, int type)
{ {
int startAdr; int startAdr;
int i; int i, n;
if (eab->state != EASE_read) { if (eab->state != EASE_read) {
return 0.0; return 0.0;
} }
n = word2uint(eab->cmd + 4);
if (n <= 2) return ModBusGetValue(eab, type);
startAdr = word2fadr(eab->cmd + 2); startAdr = word2fadr(eab->cmd + 2);
i = adr - startAdr; i = adr - startAdr;
if (i < 0 || i >= word2uint(eab->cmd + 4)) { if (i < 0 || i >= n) {
return 0.0; return 0.0;
} }
if (type == modBusTime) { if (type == modBusTime) {
@ -392,6 +401,7 @@ void ModBusRequestValue(EaseBase * eab, int adr, int type)
fadr2word(adr, eab->cmd + 2); fadr2word(adr, eab->cmd + 2);
uint2word(2, eab->cmd + 4); uint2word(2, eab->cmd + 4);
} }
ParPrintf(eab, -2, "read #%d", adr);
ModBusWrite(eab, 6); ModBusWrite(eab, 6);
} }
@ -407,6 +417,7 @@ void ModBusPutValue(EaseBase * eab, int adr, int type, float val)
uint2word(1, eab->cmd + 4); uint2word(1, eab->cmd + 4);
eab->cmd[6] = 2; eab->cmd[6] = 2;
uint2word((int) (val), eab->cmd + 7); uint2word((int) (val), eab->cmd + 7);
ParPrintf(eab, -1, "write #%d %.5g", adr, val);
ModBusWrite(eab, 9); ModBusWrite(eab, 9);
return; return;
} }
@ -422,6 +433,7 @@ void ModBusPutValue(EaseBase * eab, int adr, int type, float val)
eab->cmd[9] = 0; eab->cmd[9] = 0;
eab->cmd[10] = 0; eab->cmd[10] = 0;
} }
ParPrintf(eab, -1, "write #%d %.5g", adr, val);
ModBusWrite(eab, 11); ModBusWrite(eab, 11);
} }

View File

@ -241,6 +241,7 @@ char *ParArg2Str(int argc, char *argv[], char *result, int maxsize)
for (i = 0; i < argc; i++) { for (i = 0; i < argc; i++) {
argsize += strlen(argv[i]) + 1; argsize += strlen(argv[i]) + 1;
} }
if (argsize == 0) argsize = 1;
result = malloc(argsize); result = malloc(argsize);
if (!result) if (!result)
return NULL; return NULL;