From d109dd026a3768a17b2c98bab53df6faa7fdc33c Mon Sep 17 00:00:00 2001 From: zolliker Date: Wed, 14 May 2008 14:23:43 +0000 Subject: [PATCH] - small improvements in drivers --- haakedriv.c | 20 +++++---- itcdriv.c | 122 ++++++++++++++++++++++++++++++++++++++++++++++----- lsc370driv.c | 31 +++++++++++-- oxinst.c | 15 ++++--- 4 files changed, 158 insertions(+), 30 deletions(-) diff --git a/haakedriv.c b/haakedriv.c index 0fbe1ee..547cf65 100644 --- a/haakedriv.c +++ b/haakedriv.c @@ -141,14 +141,14 @@ static void HaakeParDef(void *object) { EaseBase *eab = object; int reset = 0; - ParName(""); ParFmt("%.2f"); ParTail("C"); + ParName(""); ParFmt("%.2f"); ParTail("K"); ParFloat(&drv->t, PAR_NAN); ParName("t2"); - if (drv->with2sensors) { ParFmt("%.2f"); ParTail("C"); } + if (drv->with2sensors) { ParFmt("%.2f"); ParTail("K"); } ParFloat(&drv->t2, PAR_NAN); - ParName("set"); ParFmt("%.2f"); ParTail("C"); + ParName("set"); ParFmt("%.2f"); ParTail("K"); ParFloat(&drv->set, PAR_NAN); ParName("running"); EaseUpdate(HAAKE_ON); @@ -175,7 +175,7 @@ static void HaakeParDef(void *object) { EaseBasePar(drv); EaseSendPar(drv); - EaseDrivPar(drv, "%.2f", "C"); + EaseDrivPar(drv, "%.2f", "K"); ParStdDef(); EaseMsgPar(drv); } @@ -206,18 +206,18 @@ static long HaakeRead(long pc, void *object) { EaseWrite(eab, "F1"); return __LINE__; case __LINE__: /**********************************/ - drv->t = atof(eab->ans); + drv->t = atof(eab->ans) + 273.15; if (!drv->with2sensors) goto nof2; EaseWrite(eab, "F2"); return __LINE__; case __LINE__: /**********************************/ - drv->t2 = atof(eab->ans); + drv->t2 = atof(eab->ans) + 273.15; if (drv->t2 < -222) { drv->t2 = PAR_NAN; } nof2: EaseWrite(eab, "S"); return __LINE__; case __LINE__: /**********************************/ - drv->set = atof(eab->ans); + drv->set = atof(eab->ans) + 273.15; skipGetSet: ParLog(drv); @@ -227,7 +227,7 @@ static long HaakeRead(long pc, void *object) { static long HaakeStart(long pc, void *object) { Haake *drv = ParCast(&haakeClass, object); EaseBase *eab = object; - + switch (pc) { default: /* FSM BEGIN *******************************/ EaseWrite(eab, "V"); return __LINE__; case __LINE__: /**********************************/ @@ -239,6 +239,8 @@ static long HaakeStart(long pc, void *object) { goto quit; } ParPrintf(drv, eStatus, "connected to haake thermostat %s", eab->version); + EaseWrite(eab, "W TE K"); + return __LINE__; case __LINE__: /**********************************/ FsmCall(HaakeRead); return __LINE__; case __LINE__: /**********************************/ @@ -256,7 +258,7 @@ 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); + snprintf(cmd, sizeof cmd, "w sw %.5g", drv->d.targetValue-273.17); break; case HAAKE_ON: snprintf(cmd, sizeof cmd, "w ts%d", drv->running); diff --git a/itcdriv.c b/itcdriv.c index eefe9ad..bb788ed 100644 --- a/itcdriv.c +++ b/itcdriv.c @@ -38,6 +38,7 @@ Markus Zolliker, May 2005 #define ITC_PROP 4 #define ITC_INTEG 5 #define ITC_DERIV 6 +#define ITC_MAXVOLT 7 typedef struct { EaseDriv d; @@ -54,6 +55,13 @@ typedef struct { float deriv; /* deriv. time / int. for pressure [sec] */ float prop2; /* TESLATRON only: prop. for pressure [%/mbar] */ float lambdaTarget; /* TESLATRON only: lambda stage target temperature */ + float power; + float resist; + float htrVolt; + float maxVolt; + float maxPower; + int cntVolt; + int readMaxVolt; int pidMode; int sampleChan; int controlChan; @@ -167,6 +175,9 @@ static void ItcParDef(void *object) { ParList(NULL); ParInt(&drv->gasMode, 1); + ParName("heaterMode"); + ParInt(&drv->a, 0); + } else { ParName("progress"); ParAccess(usUser); ParEnum(progressList); @@ -187,6 +198,8 @@ static void ItcParDef(void *object) { ParList(""); } EaseUpdate(ITC_SETGAS); ParSave(1); + if (drv->setGas > 99.9) drv->setGas = 99.9; + if (drv->setGas < 0) drv->setGas = 0; ParFloat(&drv->setGas, 20.0); ParName("travelTime"); ParFmt("%.0f"); ParTail("sec"); @@ -219,7 +232,39 @@ static void ItcParDef(void *object) { if (drv->pidMode == 1) ParList(""); EaseUpdate(ITC_DERIV); ParFloat(&drv->deriv, PAR_NAN); + + ParName("maxPower"); + ParFmt("%.4g"); ParTail("W"); + EaseUpdate(ITC_MAXVOLT); + ParFloat(&drv->maxPower, PAR_NAN); + if (ParActionIs(PAR_SET) > 0) { + if (drv->maxPower < 0) { + drv->readMaxVolt = 1; + drv->maxPower = PAR_NAN; + drv->maxVolt = PAR_NAN; + } else { + drv->readMaxVolt = 0; + if (drv->resist < 0) { + drv->resist = 0; + } + drv->maxVolt = sqrt(drv->maxPower * drv->resist); + if (drv->maxVolt > 47.9) { + drv->maxVolt = 47.9; + } + } + } + + ParName("resist"); + ParFmt("%g"); ParAccess(usUser); + ParTail("Ohm"); ParList(""); + ParFloat(&drv->resist, 80.0); + + ParName("power"); + ParFmt("%g"); ParTail("W"); + ParFloat(&drv->power, PAR_NAN); + } else { + ParName("lambdaTarget"); ParFmt("%.2f"); ParTail("K"); if (drv->gasMode == 0) ParList(""); ParAccess(usUser); ParSave(1); @@ -348,7 +393,7 @@ static long ItcRead(long pc, void *object) { int l; time_t now, delta; char buf[4]; - float gas, band; + float gas, band, v1, v2, h; switch (pc) { default: /* FSM BEGIN *******************************/ EaseWrite(eab, "X"); @@ -384,7 +429,8 @@ static long ItcRead(long pc, void *object) { if (drv->t[drv->controlChan] > drv->autoGasLimit + 1.0) { if (drv->a < 2) { drv->a |= 2; /* switch gas to auto */ - ParPrintf(drv, eWarning, "switch to auto needle valve"); + ParPrintf(drv, eWarning, + "needle valve switched to ITC control (AutoGas)"); } else { goto skip0; } @@ -392,8 +438,8 @@ static long ItcRead(long pc, void *object) { if (drv->a >= 2) { if (drv->t[drv->controlChan] < drv->autoGasLimit) { drv->a &= 1; /* switch gas to manual */ - ParPrintf(drv, eWarning, "switch to manual needle valve (%f %%)", - drv->setGas); + ParPrintf(drv, eWarning, + "needle valve switched to software control"); } else { goto skip0; } @@ -494,13 +540,57 @@ static long ItcRead(long pc, void *object) { if (eab->syntax == TESLATRON) goto skipctrl; - if (EaseGetUpdate(drv, ITC_SETHTR)) goto skiphtr; - EaseWrite(eab, "R5"); /* read heater */ + if (EaseGetUpdate(drv, ITC_MAXVOLT)) goto skiphtr; + EaseWrite(eab, "R5"); /* read heater percent */ return __LINE__; case __LINE__: /**********************************/ - if (EaseGetUpdate(drv, ITC_SETHTR)) goto skiphtr; + if (EaseGetUpdate(drv, ITC_MAXVOLT)) goto skiphtr; drv->htr = OxiGet(eab, 1, NULL, drv->htr); - skiphtr: - + + if (drv->readMaxVolt == 0) { + drv->htrVolt = drv->htr * 0.01 * drv->maxVolt; + goto skiphtr; + } + EaseWrite(eab, "R6"); /* read heater voltage */ + return __LINE__; case __LINE__: /**********************************/ + drv->htrVolt = OxiGet(eab, 1, NULL, drv->htrVolt); + + if (drv->readMaxVolt) { + h = drv->htr; + if (h > 1.0) { + v1 = 0.1 * (int)(drv->htrVolt * 1000 / (h + 0.099) - 0.5); + v2 = 0.1 * (int)(drv->htrVolt * 1000 / (h - 0.05) + 0.99); + if (drv->maxVolt > v2) { + drv->cntVolt++; + if (drv->cntVolt > drv->readMaxVolt) { + drv->maxVolt = v2; + drv->cntVolt = 0; + drv->readMaxVolt++; + } + } else if (drv->maxVolt < v1) { + drv->cntVolt--; + if (drv->cntVolt < -drv->readMaxVolt) { + drv->maxVolt = v1; + drv->cntVolt = 0; + drv->readMaxVolt++; + } + } else { + drv->cntVolt = 0; + } + } + } + if (drv->maxVolt != PAR_NAN) { + drv->htrVolt = h * 0.01 * drv->maxVolt; + } + + skiphtr: + if (drv->resist <= 1) drv->resist = 80.0; + if (drv->maxVolt != PAR_NAN) { + drv->maxPower = drv->maxVolt * drv->maxVolt / drv->resist; + } + if (drv->htrVolt != PAR_NAN) { + drv->power = drv->htrVolt * drv->htrVolt / drv->resist; + } + if (EaseGetUpdate(drv, ITC_PROP)) goto skipprop; EaseWrite(eab, "R8"); /* read prop */ return __LINE__; case __LINE__: /**********************************/ @@ -556,11 +646,12 @@ static long ItcStart(long pc, void *object) { } } ParPrintf(drv, eStatus, "connected to %s", eab->version); + FsmCall(ItcRead); + return __LINE__; case __LINE__: /**********************************/ if (drv->controlChan == 0 && drv->h >= 1 && drv->h <= 3) { drv->controlChan = drv->h; } - FsmCall(ItcRead); - return __LINE__; case __LINE__: /**********************************/ + drv->d.targetValue = drv->t[0]; quit: return 0; } /* FSM END ********************************************/ @@ -642,7 +733,9 @@ static long ItcSetGas(long pc, void *object) { return __LINE__; case __LINE__: /**********************************/ EaseWrite(eab, "R7"); /* read gas flow */ return __LINE__; case __LINE__: /**********************************/ - drv->setGas = OxiGet(eab, 1, NULL, drv->setGas); + if (! EaseGetUpdate(drv, ITC_SETGAS)) { + drv->setGas = OxiGet(eab, 1, NULL, drv->setGas); + } if (drv->a < 2) goto quit; snprintf(buf, sizeof buf, "A%d", drv->a); EaseWrite(eab, buf); @@ -698,6 +791,7 @@ static long ItcSet(long pc, void *object) { case ITC_PROP: OxiSet(eab, "P", drv->prop, 1); goto loop; case ITC_INTEG: OxiSet(eab, "I", drv->integ, 1); goto loop; case ITC_DERIV: OxiSet(eab, "D", drv->deriv, 1); goto loop; + case ITC_MAXVOLT:OxiSet(eab, "M", drv->maxVolt, 1); goto loop; default: break; } } @@ -721,6 +815,10 @@ static int ItcInit(SConnection *con, int argc, char *argv[], int dynamic) { ItcSet); if (drv == NULL) return 0; drv->d.b.syntax = 0; + drv->cntVolt = 0; + drv->maxVolt = PAR_NAN; + drv->htrVolt = PAR_NAN; + drv->readMaxVolt = 1; return 1; } /*----------------------------------------------------------------------------*/ diff --git a/lsc370driv.c b/lsc370driv.c index a415bca..d0852e8 100644 --- a/lsc370driv.c +++ b/lsc370driv.c @@ -33,6 +33,7 @@ Markus Zolliker, July 2006 #define PID_FLAG 1 #define RDGRNG_FLAG 2 #define HTRRNG_FLAG 3 +#define MAX_CHAN 3 typedef struct { EaseDriv d; @@ -44,12 +45,15 @@ typedef struct { float integ; float deriv; float resist; /* Ohm */ + float temp[MAX_CHAN]; + int channel[MAX_CHAN]; int ighHeater; /* IGH heater range (-1 if output is direct) */ int htrRange; int currentEx; int voltageEx; int range; int autoRange; + int index; } Lsc370; static ParClass lsc370Class = { "LSC370", sizeof(Lsc370) }; @@ -85,6 +89,8 @@ static void Lsc370ParDef(void *object) { EaseBase *eab = object; float power, maxPower; int iRng; + int i; + static char *heaterList[]={"off", "30uA", "100uA", "300uA", "1mA", "3mA", "10mA", "30mA", "100mA", NULL }; @@ -104,8 +110,11 @@ static void Lsc370ParDef(void *object) { "2MegaOhm", "6MegaOhm", "20MegaOhm", "60MegaOhm", NULL }; static char *offOn[]={"off", "on", NULL}; + static char *tNames[]={"tsample", "tstill", "tmix"}; + static char *cNames[]={"csample", "cstill", "cmix"}; + ParName(""); ParTail("K"); - ParFloat(&drv->t, PAR_NAN); + ParFloat(&drv->temp[0], PAR_NAN); ParName("set"); ParTail("K"); ParFloat(&drv->set, PAR_NAN); @@ -113,6 +122,15 @@ static void Lsc370ParDef(void *object) { ParName("htr"); ParTail("%"); ParFloat(&drv->htr, PAR_NAN); + for (i = 0; i < MAX_CHAN; i++) { + if (drv->channel[i] > 0 && i > 0) { + ParName(tNames[i]); ParTail("K"); + ParFloat(&drv->temp[i], PAR_NAN); + } + ParName(cNames[i]); ParAccess(usUser); + ParInt(&drv->channel[i], 0); + } + ParName("res"); ParTail("Ohm"); ParFloat(&drv->res, PAR_NAN); @@ -217,14 +235,21 @@ static long Lsc370Read(long pc, void *object) { EaseBase *eab = object; int mode, exi, rng, autoR, eoff; float x, y, z; + char buf[16]; switch (pc) { default: /* FSM BEGIN *******************************/ - EaseWrite(eab, "RDGK?1"); + drv->index = 0; + chanLoop: + snprintf(buf, sizeof buf, "RDGK?%d", drv->channel[drv->index]); + EaseWrite(eab, buf); return __LINE__; case __LINE__: /**********************************/ if (1 == sscanf(eab->ans, "%f", &x)) { - drv->t = x; + drv->temp[drv->index] = x; } + drv->index++; + if (drv->index < MAX_CHAN) goto chanLoop; + EaseWrite(eab, "RDGR?1"); return __LINE__; case __LINE__: /**********************************/ if (1 == sscanf(eab->ans, "%f", &x)) { diff --git a/oxinst.c b/oxinst.c index 9481b37..10d2304 100644 --- a/oxinst.c +++ b/oxinst.c @@ -11,6 +11,7 @@ is not changed, i.e. an existing errCode is not overwritten. */ #include +#include #include #include #include @@ -160,13 +161,15 @@ double OxiGet(EaseBase *eab, int dig, int *pdig, double old) { void OxiSet(EaseBase *eab, char *cmd, double val, int dig) { char buf[64]; - int l; - - if (eab->syntax <= 0) { - snprintf(buf, sizeof(buf), "%s%.*f", cmd, dig, val); - } else { - snprintf(buf, sizeof(buf), "%s%f", cmd, val); + double f; + + if (eab->syntax > 0) { + f = fabs(val); + if (f < 1.0) f = 1.0; + dig = 5 - log10(f); + if (dig < 0) dig = 0; } + snprintf(buf, sizeof(buf), "%s%.*f", cmd, dig, val); EaseWrite(eab, buf); }