new version of drivers (based on ease instead of eve)
This commit is contained in:
622
itcdriv.c
622
itcdriv.c
@ -2,8 +2,9 @@
|
||||
itcdriv.c
|
||||
|
||||
Driver for the Oxford Instruments ITC503/ITC4 temperature controller
|
||||
|
||||
Markus Zolliker, Sept 2004
|
||||
Version 2 (based on ease).
|
||||
|
||||
Markus Zolliker, May 2005
|
||||
----------------------------------------------------------------------------*/
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
@ -26,15 +27,22 @@ Markus Zolliker, Sept 2004
|
||||
#include <sicsvar.h>
|
||||
#include <evdriver.i>
|
||||
#include <rs232controller.h>
|
||||
#include "oicom.h"
|
||||
#include "oxinst.h"
|
||||
#include "fsm.h"
|
||||
#include "initializer.h"
|
||||
|
||||
#define TESLATRON -1
|
||||
#define ITC_SETHTR 1
|
||||
#define ITC_SETGAS 2
|
||||
|
||||
typedef struct {
|
||||
Eve eve;
|
||||
float t[4]; /* temperatures (0 unused) */
|
||||
EaseDriv d;
|
||||
float t[4]; /* temperatures (0 is set point) */
|
||||
int dig[4]; /* format for these */
|
||||
float htr;
|
||||
float gas;
|
||||
float autoGasLimit;
|
||||
float setGas;
|
||||
int sampleChan;
|
||||
int controlChan;
|
||||
int gasMode;
|
||||
@ -42,310 +50,470 @@ typedef struct {
|
||||
int remote;
|
||||
int h; /* actual heater channel */
|
||||
int a; /* actual auto mode */
|
||||
} ItcDriv;
|
||||
} Itc;
|
||||
|
||||
static ParClass itcClass = { "ITC", sizeof(Itc) };
|
||||
|
||||
static long ItcSetGas(long pc, void *obj);
|
||||
static long ItcSetHtr(long pc, void *obj);
|
||||
/*----------------------------------------------------------------------------*/
|
||||
#define A EVE_ACTPAR
|
||||
#define L EVE_LOGPAR
|
||||
#define S EVE_SAVEPAR
|
||||
static void ItcParDef(void *object) {
|
||||
Itc *drv = ParCast(&itcClass, object);
|
||||
EaseBase *eab = object;
|
||||
|
||||
void ItcPars(ItcDriv *me, EveParArg *arg) {
|
||||
char fmt[8]="";
|
||||
int i;
|
||||
int flag;
|
||||
char *ti[4] = {"setp","t1","t2","t3"};
|
||||
static char *ti[4] = {"setp","t1","t2","t3"};
|
||||
static char *modeList[]={"off", "manual", "auto", NULL };
|
||||
|
||||
EveStdPar(arg);
|
||||
|
||||
flag = me->controlChan != 0 && fabsf(me->eve.evc->fTarget - me->t[0]) > 9e-4;
|
||||
sprintf(fmt, "%%.%df\tK", me->dig[me->controlChan]);
|
||||
EveFloatPar(arg, ti[0], &me->t[0], fmt, usInternal, flag*A + L);
|
||||
|
||||
ParName("sampleChan");
|
||||
if (eab->syntax != TESLATRON) ParAccess(usUser);
|
||||
ParInt(&drv->sampleChan, 1);
|
||||
if (ParActionIs(PAR_SET) > 0) {
|
||||
if (drv->sampleChan < 1 || drv->sampleChan > 3) {
|
||||
drv->sampleChan = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (eab->syntax != TESLATRON) {
|
||||
ParName("controlChan");
|
||||
ParAccess(usUser);
|
||||
ParInt(&drv->controlChan, 0);
|
||||
if (ParActionIs(PAR_SET) > 0) {
|
||||
if (drv->controlChan < 0 || drv->controlChan > 3) {
|
||||
drv->controlChan = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ParName("");
|
||||
if (eab->syntax == TESLATRON) {
|
||||
ParTail("mbar");
|
||||
} else {
|
||||
ParTail("K");
|
||||
}
|
||||
ParFloat(&drv->t[drv->sampleChan], PAR_NAN);
|
||||
|
||||
ParName("dig1"); ParAccess(usUser); ParLogAs(NULL); ParInt(&drv->dig[1], -1);
|
||||
ParName("dig2"); ParAccess(usUser); ParLogAs(NULL); ParInt(&drv->dig[2], -1);
|
||||
ParName("dig3"); ParAccess(usUser); ParLogAs(NULL); ParInt(&drv->dig[3], -1);
|
||||
|
||||
if (eab->syntax != TESLATRON) {
|
||||
ParName(ti[0]);
|
||||
if (drv->controlChan != 0) {
|
||||
snprintf(fmt, sizeof fmt, "%%.%df", drv->dig[drv->controlChan]);
|
||||
ParFmt(fmt);
|
||||
if (fabsf(drv->d.targetValue - drv->t[0]) < 9e-4) {
|
||||
ParList("");
|
||||
}
|
||||
} else {
|
||||
ParList("");
|
||||
}
|
||||
ParTail("K");
|
||||
ParFloat(&drv->t[0], PAR_NAN);
|
||||
}
|
||||
|
||||
for (i=1; i<=3; i++) {
|
||||
flag = (me->dig[i] >= 0) && (me->sampleChan != i);
|
||||
sprintf(fmt, "%%.%df\tK", me->dig[i]);
|
||||
EveFloatPar(arg, ti[i], &me->t[i], fmt, usInternal, flag*A + L);
|
||||
|
||||
ParName(ti[i]);
|
||||
if (drv->dig[i] >= 0 && drv->sampleChan != i) {
|
||||
snprintf(fmt, sizeof fmt, "%%.%df", drv->dig[i]);
|
||||
ParFmt(fmt);
|
||||
ParTail("K");
|
||||
} else {
|
||||
ParList("");
|
||||
}
|
||||
ParFloat(&drv->t[i], PAR_NAN);
|
||||
|
||||
}
|
||||
|
||||
flag = me->controlChan != 0 || me->htr != 0;
|
||||
EveEnumPar(arg, "htrMode", &me->htrMode, modeList, usUser, A+S);
|
||||
EveFloatCmd(arg, "htr", &me->htr, "%.1f\t%%", ItcSetHtr, usUser, flag*A + L);
|
||||
EveEnumPar(arg, "gasMode", &me->gasMode, modeList, usUser, A+S);
|
||||
flag = me->gasMode > 0;
|
||||
EveFloatCmd(arg, "gas", &me->gas, "%.1f\t%%", ItcSetGas, usUser, flag*A + L);
|
||||
EveIntPar(arg, "dig1", &me->dig[1], usUser, S);
|
||||
EveIntPar(arg, "dig2", &me->dig[2], usUser, S);
|
||||
EveIntPar(arg, "dig3", &me->dig[3], usUser, S);
|
||||
EveIntPar(arg, "sampleChan", &me->sampleChan, usUser, A+S);
|
||||
EveIntPar(arg, "controlChan", &me->controlChan, usUser, A+S);
|
||||
sprintf(fmt, "%%.%df\tK", me->dig[me->sampleChan]);
|
||||
EveStdParEnd(arg, fmt, A+L);
|
||||
if (eab->syntax != TESLATRON) {
|
||||
ParName("htrMode");
|
||||
if (drv->controlChan == 0 && drv->htr == 0) {
|
||||
ParList("");
|
||||
}
|
||||
ParEnum(modeList); ParSave(1);
|
||||
ParInt(&drv->htrMode, 2);
|
||||
|
||||
ParName("htr");
|
||||
ParFmt("%.1f"); ParTail("%");
|
||||
ParSave(1);
|
||||
EaseUpdate(ITC_SETHTR);
|
||||
ParFloat(&drv->htr, PAR_NAN);
|
||||
}
|
||||
|
||||
ParName("gasMode");
|
||||
ParAccess(usUser); ParEnum(modeList);
|
||||
if (eab->syntax == TESLATRON) {
|
||||
ParInt(&drv->gasMode, 1);
|
||||
} else {
|
||||
ParList(""); ParInt(&drv->gasMode, 1);
|
||||
}
|
||||
|
||||
ParName("gas");
|
||||
ParFmt("%.1f"); ParTail("%");
|
||||
if (drv->gasMode < 1) {
|
||||
ParList("");
|
||||
}
|
||||
ParFloat(&drv->gas, PAR_NAN);
|
||||
|
||||
ParName("setGas");
|
||||
ParFmt("%.1f"); ParTail("%");
|
||||
if (drv->gasMode < 1) {
|
||||
ParList("");
|
||||
}
|
||||
EaseUpdate(ITC_SETGAS); ParSave(1);
|
||||
ParFloat(&drv->setGas, 20.0);
|
||||
|
||||
if (eab->syntax != TESLATRON) {
|
||||
ParName("autoGasLimit");
|
||||
ParAccess(usUser); ParFmt("%.1f"); ParTail("K"); ParSave(1);
|
||||
if (drv->gasMode != 2) {
|
||||
ParList("");
|
||||
}
|
||||
ParFloat(&drv->autoGasLimit, 3.0);
|
||||
}
|
||||
|
||||
if (drv->controlChan == 0) {
|
||||
i = drv->sampleChan;
|
||||
} else {
|
||||
i = drv->controlChan;
|
||||
}
|
||||
if (drv->dig[i] < 0) {
|
||||
snprintf(fmt, sizeof fmt, "%s", "%.3f");
|
||||
} else {
|
||||
snprintf(fmt, sizeof fmt, "%s.%df", "%", drv->dig[i]);
|
||||
}
|
||||
|
||||
EaseBasePar(drv);
|
||||
EaseSendPar(drv);
|
||||
if (eab->syntax != TESLATRON) {
|
||||
EaseDrivPar(drv, fmt, "K");
|
||||
}
|
||||
ParStdDef();
|
||||
EaseMsgPar(drv);
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void ItcStatus(ItcDriv *me) {
|
||||
void ItcStatus(Itc *drv) {
|
||||
char *ans;
|
||||
int *code;
|
||||
Eve *eve=&me->eve;
|
||||
|
||||
if (eve->state != readState) return;
|
||||
ans=eve->ans;
|
||||
code=&eve->errCode;
|
||||
if (drv->d.b.state != EASE_read) return;
|
||||
ans=drv->d.b.ans;
|
||||
code=&drv->d.b.errCode;
|
||||
if (ans[0] != 'X' ||
|
||||
ans[2] != 'A' ||
|
||||
ans[4] != 'C' ||
|
||||
ans[6] != 'S') {
|
||||
EvePrintf(eve, eError, "illegal status response");
|
||||
*code = EVE_FAULT;
|
||||
ParPrintf(drv, eError, "illegal status response");
|
||||
*code = EASE_FAULT;
|
||||
return;
|
||||
}
|
||||
me->a = ans[3] - '0';
|
||||
drv->a = ans[3] - '0';
|
||||
if (ans[9] == 'H') {
|
||||
me->h = ans[10] - '0';
|
||||
drv->h = ans[10] - '0';
|
||||
} else {
|
||||
me->h = me->controlChan;
|
||||
drv->h = drv->controlChan;
|
||||
}
|
||||
if (ans[6] != '3' && me->remote == 2) {
|
||||
EvePrintf(eve, eError, "ITC switched to local");
|
||||
*code = EVE_FAULT;
|
||||
me->remote = 1;
|
||||
if (ans[6] != '3' && drv->remote == 2) {
|
||||
ParPrintf(drv, eError, "ITC switched to local");
|
||||
*code = EASE_FAULT;
|
||||
drv->remote = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static long ItcRead(long pc, ItcDriv *me) {
|
||||
Eve *eve=&me->eve;
|
||||
static long ItcRead(long pc, void *object) {
|
||||
Itc *drv = ParCast(&itcClass, object);
|
||||
EaseBase *eab = object;
|
||||
char *p;
|
||||
int l;
|
||||
char buf[4];
|
||||
|
||||
FSM_BEGIN
|
||||
EveWrite(eve, "X");
|
||||
FSM_NEXT
|
||||
ItcStatus(me); /* check for errors */
|
||||
if (!me->remote) goto skiprmt;
|
||||
EveWrite(eve, "C0");
|
||||
me->remote = 0;
|
||||
FSM_NEXT
|
||||
|
||||
skiprmt:
|
||||
if (me->dig[1] < 0) goto skip1;
|
||||
EveWrite(eve, "R1"); /* read sensor 1 */
|
||||
FSM_NEXT
|
||||
me->t[1] = OiGetFlt(eve, me->dig[1], &me->dig[1]);
|
||||
switch (pc) { default: /* FSM BEGIN *******************************/
|
||||
EaseWrite(eab, "X");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
ItcStatus(drv); /* check for errors */
|
||||
|
||||
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]);
|
||||
|
||||
skip1:
|
||||
if (me->dig[2] < 0) goto skip2;
|
||||
EveWrite(eve, "R2"); /* read sensor 2 */
|
||||
FSM_NEXT
|
||||
me->t[2] = OiGetFlt(eve, me->dig[2], &me->dig[2]);
|
||||
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]);
|
||||
|
||||
skip2:
|
||||
if (me->dig[3] < 0) goto skip3;
|
||||
EveWrite(eve, "R3"); /* read sensor 3 */
|
||||
FSM_NEXT
|
||||
me->t[3] = OiGetFlt(eve, me->dig[3], &me->dig[3]);
|
||||
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]);
|
||||
|
||||
skip3:
|
||||
me->eve.value = me->t[me->sampleChan];
|
||||
if (me->controlChan == 0 || me->a) {
|
||||
me->t[0] = me->eve.evc->fTarget;
|
||||
if (drv->controlChan == 0 || drv->a == 0) {
|
||||
drv->t[0] = drv->d.targetValue;
|
||||
goto skip0;
|
||||
}
|
||||
EveWrite(eve, "R0"); /* read control T */
|
||||
FSM_NEXT
|
||||
me->t[0] = OiGetFlt(eve, me->dig[me->controlChan], NULL);
|
||||
|
||||
if (me->htrMode != 2 && me->a % 2 == 0) goto skiphtr;
|
||||
EaseWrite(eab, "R0"); /* read control T */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
drv->t[0] = OxiGet(eab, drv->dig[drv->controlChan], NULL);
|
||||
if (drv->gasMode == 2) {
|
||||
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");
|
||||
} else {
|
||||
goto skip0;
|
||||
}
|
||||
} else {
|
||||
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);
|
||||
} else {
|
||||
goto skip0;
|
||||
}
|
||||
}
|
||||
if (drv->setGas != drv->gas) {
|
||||
EaseSetUpdate(drv, ITC_SETGAS, 1);
|
||||
}
|
||||
}
|
||||
} else if (drv->a < 2) {
|
||||
goto skip0;
|
||||
} else {
|
||||
drv->a &= 1; /* switch gas to manual */
|
||||
}
|
||||
EaseWrite(eab, "C3");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
drv->remote = 2;
|
||||
|
||||
snprintf(buf, sizeof buf, "A%d", drv->a);
|
||||
EaseWrite(eab, buf);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
skip0:
|
||||
EveWrite(eve, "R5"); /* read heater */
|
||||
FSM_NEXT
|
||||
me->htr = OiGetFlt(eve, 1, NULL);
|
||||
skiphtr:
|
||||
if (me->gasMode != 2 && me->a < 2) goto skipgas;
|
||||
EveWrite(eve, "R7"); /* read gas flow */
|
||||
FSM_NEXT
|
||||
me->gas = OiGetFlt(eve, 1, NULL);
|
||||
|
||||
if (!drv->remote) goto skiprmt;
|
||||
EaseWrite(eab, "C0");
|
||||
drv->remote = 0;
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
skiprmt:
|
||||
|
||||
if (EaseGetUpdate(drv, ITC_SETHTR)) goto skiphtr;
|
||||
EaseWrite(eab, "R5"); /* read heater */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
if (EaseGetUpdate(drv, ITC_SETHTR)) goto skiphtr;
|
||||
drv->htr = OxiGet(eab, 1, NULL);
|
||||
skiphtr:
|
||||
|
||||
EaseWrite(eab, "R7"); /* read gas flow */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
drv->gas = OxiGet(eab, 1, NULL);
|
||||
skipgas:
|
||||
me->eve.value = me->t[me->sampleChan];
|
||||
EveLog(eve);
|
||||
FSM_END
|
||||
|
||||
ParLog(drv);
|
||||
fsm_quit: return 0; } /* FSM END *********************************/
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static long ItcStart(long pc, ItcDriv *me) {
|
||||
Eve *eve=&me->eve;
|
||||
static long ItcStart(long pc, void *object) {
|
||||
Itc *drv = ParCast(&itcClass, object);
|
||||
EaseBase *eab = object;
|
||||
|
||||
FSM_BEGIN
|
||||
EveWrite(eve, "V");
|
||||
FSM_NEXT
|
||||
if (0 == strncmp(eve->version, "ITC503", 6)) {
|
||||
me->eve.syntax = 3;
|
||||
} else if (0 == strncmp(eve->version, "ITC4", 4)) {
|
||||
me->eve.syntax = 0;
|
||||
switch (pc) { default: /* FSM BEGIN *******************************/
|
||||
EaseWrite(eab, "V");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
if (eab->syntax == TESLATRON) {
|
||||
if (0 != strncmp(eab->version, "TESLATRON", 9)) {
|
||||
snprintf(eab->msg, sizeof eab->msg, "unknown teslatron version: %s",
|
||||
eab->version);
|
||||
ParPrintf(drv, eError, "ERROR: %s", eab->msg);
|
||||
EaseStop(eab);
|
||||
goto quit;
|
||||
}
|
||||
} else {
|
||||
EvePrintf(eve, eError, "unknown temperature controller version: %s", eve->version);
|
||||
goto quit;
|
||||
if (0 == strncmp(eab->version, "ITC503", 6)) {
|
||||
eab->syntax = 3;
|
||||
} else if (0 == strncmp(eab->version, "ITC4", 4)) {
|
||||
eab->syntax = 0;
|
||||
} else {
|
||||
snprintf(eab->msg, sizeof eab->msg, "unknown temperature controller version: %s",
|
||||
eab->version);
|
||||
ParPrintf(drv, eError, "ERROR: %s", eab->msg);
|
||||
EaseStop(eab);
|
||||
goto quit;
|
||||
}
|
||||
}
|
||||
EvePrintf(eve, eStatus, "connected to %s", eve->version);
|
||||
if (me->controlChan == 0 && me->h >= 1 && me->h <= 3) {
|
||||
me->controlChan = me->h;
|
||||
ParPrintf(drv, eStatus, "connected to %s", eab->version);
|
||||
if (drv->controlChan == 0 && drv->h >= 1 && drv->h <= 3) {
|
||||
drv->controlChan = drv->h;
|
||||
}
|
||||
FSM_CALL(ItcRead);
|
||||
FsmCall(ItcRead);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
|
||||
quit:
|
||||
FSM_END
|
||||
return 0; } /* FSM END ********************************************/
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static long ItcSetTemp(long pc, ItcDriv *me) {
|
||||
Eve *eve=&me->eve;
|
||||
pEVControl evc=eve->evc;
|
||||
float fld;
|
||||
float step;
|
||||
float ramp;
|
||||
static long ItcSetTemp(long pc, void *object) {
|
||||
Itc *drv = ParCast(&itcClass, object);
|
||||
EaseBase *eab = object;
|
||||
char buf[4];
|
||||
SConnection *pCon;
|
||||
int a;
|
||||
|
||||
FSM_BEGIN
|
||||
if (me->controlChan == 0) {
|
||||
EvePrintf(eve, eError, "no control channel selected");
|
||||
switch (pc) { default: /* FSM BEGIN *******************************/
|
||||
if (drv->controlChan == 0) {
|
||||
ParPrintf(drv, eError, "no control channel selected");
|
||||
goto quit;
|
||||
}
|
||||
EveWrite(eve, "C3");
|
||||
FSM_NEXT
|
||||
if (me->h == me->controlChan) goto skiph;
|
||||
EveWrite(eve, "A0"); /* heater off */
|
||||
FSM_NEXT
|
||||
me->remote = 2;
|
||||
snprintf(buf, sizeof buf, "H%d", me->controlChan);
|
||||
EveWrite(eve, buf); /* set heater to channel */
|
||||
FSM_NEXT
|
||||
if (drv->h == drv->controlChan) goto skiph;
|
||||
EaseWrite(eab, "A0"); /* heater off */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
drv->remote = 2;
|
||||
snprintf(buf, sizeof buf, "H%d", drv->controlChan);
|
||||
EaseWrite(eab, buf); /* set heater to channel */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
|
||||
skiph:
|
||||
OiSet(eve, "T", evc->fTarget, me->dig[me->controlChan]); /* set point */
|
||||
FSM_NEXT
|
||||
a = 1;
|
||||
if (me->gasMode == 2) a = 3;
|
||||
if (me->h == me->controlChan && me->a == a) goto skipa;
|
||||
me->htrMode = 2; /* heater auto */
|
||||
if (me->gasMode == 2) {
|
||||
EveWrite(eve, "A3"); /* auto gas & heater */
|
||||
OxiSet(eab, "T", drv->d.targetValue, drv->dig[drv->controlChan]); /* set point */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "L1"); /* 'auto' pid on */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
a = 1; /* auto heater */
|
||||
if (drv->a >= 2) a = 3; /* auto gas & heater */
|
||||
if (drv->d.targetValue == 0.0) {
|
||||
drv->htrMode = 0;
|
||||
a = 0;
|
||||
if (drv->setGas != drv->gas) {
|
||||
EaseSetUpdate(drv, ITC_SETGAS, 1);
|
||||
}
|
||||
} else {
|
||||
EveWrite(eve, "A1"); /* auto heater */
|
||||
drv->htrMode = 2; /* heater auto */
|
||||
}
|
||||
FSM_NEXT
|
||||
|
||||
if (drv->h == drv->controlChan && drv->a == a) goto skipa;
|
||||
snprintf(buf, sizeof buf, "A%d", a);
|
||||
drv->a = a;
|
||||
EaseWrite(eab, buf);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
skipa:
|
||||
EveWrite(eve, "C0");
|
||||
FSM_NEXT
|
||||
me->remote = 0;
|
||||
wait:
|
||||
pCon = SCLoad(&evc->conn);
|
||||
eve->hwstate = eve->checkStatus(evc, pCon);
|
||||
if (eve->hwstate != HWBusy) goto quit;
|
||||
FSM_CALL(ItcRead);
|
||||
goto wait;
|
||||
|
||||
if (drv->a != 0) goto quit;
|
||||
EaseWrite(eab, "O0"); /* switch off heater */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
|
||||
quit:
|
||||
FSM_END
|
||||
return 0; } /* FSM END ********************************************/
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static long ItcSetGas(long pc, void *obj) {
|
||||
ItcDriv *me = obj;
|
||||
Eve *eve=&me->eve;
|
||||
pEVControl evc=eve->evc;
|
||||
float fld;
|
||||
float step;
|
||||
float ramp;
|
||||
static long ItcSetGas(long pc, void *object) {
|
||||
Itc *drv = ParCast(&itcClass, object);
|
||||
EaseBase *eab = object;
|
||||
char buf[4];
|
||||
SConnection *pCon;
|
||||
int a;
|
||||
|
||||
FSM_BEGIN
|
||||
EveWrite(eve, "C3");
|
||||
FSM_NEXT
|
||||
if (me->gasMode != 1) {
|
||||
EvePrintf(eve, eError, "gasMode must be set to manual");
|
||||
switch (pc) { default: /* FSM BEGIN *******************************/
|
||||
if (drv->gasMode != 1 && drv->gasMode != 2) {
|
||||
ParPrintf(drv, eError, "gasMode must be set to manual or auto");
|
||||
goto quit;
|
||||
}
|
||||
FSM_NEXT
|
||||
if (me->a == 2) {
|
||||
EveWrite(eve, "A0");
|
||||
} else if (me->a == 3) {
|
||||
EveWrite(eve, "A1");
|
||||
if (drv->a == 2) {
|
||||
EaseWrite(eab, "A0");
|
||||
} else if (drv->a == 3) {
|
||||
EaseWrite(eab, "A1");
|
||||
} else {
|
||||
goto skipmode;
|
||||
}
|
||||
FSM_NEXT
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
skipmode:
|
||||
OiSet(eve, "G", me->gas, 1); /* cold valve setting */
|
||||
FSM_NEXT
|
||||
EveWrite(eve, "C0");
|
||||
FSM_NEXT
|
||||
me->remote = 0;
|
||||
OxiSet(eab, "G", drv->setGas, 1); /* cold valve setting */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
EaseWrite(eab, "R7"); /* read gas flow */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
drv->gas = OxiGet(eab, 1, NULL);
|
||||
if (drv->a < 2) goto quit;
|
||||
snprintf(buf, sizeof buf, "A%d", drv->a);
|
||||
EaseWrite(eab, buf);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
quit:
|
||||
FSM_END
|
||||
return 0; } /* FSM END ********************************************/
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static long ItcSetHtr(long pc, void *obj) {
|
||||
ItcDriv *me = obj;
|
||||
Eve *eve=&me->eve;
|
||||
pEVControl evc=eve->evc;
|
||||
float fld;
|
||||
float step;
|
||||
float ramp;
|
||||
static long ItcSetHtr(long pc, void *object) {
|
||||
Itc *drv = ParCast(&itcClass, object);
|
||||
EaseBase *eab = object;
|
||||
char buf[4];
|
||||
SConnection *pCon;
|
||||
int a;
|
||||
|
||||
FSM_BEGIN
|
||||
EveWrite(eve, "C3");
|
||||
FSM_NEXT
|
||||
if (me->htrMode != 1) {
|
||||
EvePrintf(eve, eError, "htrMode must be set to manual");
|
||||
goto quit;
|
||||
}
|
||||
if (me->a == 0) goto skipmode;
|
||||
EveWrite(eve, "A0");
|
||||
FSM_NEXT
|
||||
switch (pc) { default: /* FSM BEGIN *******************************/
|
||||
if (drv->a == 0) goto skipmode;
|
||||
EaseWrite(eab, "A0");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
skipmode:
|
||||
OiSet(eve, "O", me->htr, 1); /* manual heater setting */
|
||||
FSM_NEXT
|
||||
EveWrite(eve, "C0");
|
||||
FSM_NEXT
|
||||
me->remote = 0;
|
||||
OxiSet(eab, "O", drv->htr, 1); /* manual heater setting */
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
if (drv->a == 0) goto quit;
|
||||
snprintf(buf, sizeof buf, "A%d", drv->a);
|
||||
EaseWrite(eab, buf);
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
quit:
|
||||
FSM_END
|
||||
return 0; } /* FSM END ********************************************/
|
||||
}
|
||||
/*------------------------------------------------------------------------*/
|
||||
pEVControl ItcMakeEVC(SConnection *pCon, int argc, char *argv[]) {
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static long ItcSet(long pc, void *object) {
|
||||
Itc *drv = ParCast(&itcClass, object);
|
||||
EaseBase *eab = object;
|
||||
int upd;
|
||||
|
||||
switch (pc) { default: /* FSM BEGIN *******************************/
|
||||
EaseWrite(eab, "C3");
|
||||
loop:
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
upd = EaseNextUpdate(drv);
|
||||
switch (upd) {
|
||||
case EASE_RUN: FsmCall(ItcSetTemp); goto loop;
|
||||
case ITC_SETHTR: FsmCall(ItcSetHtr); goto loop;
|
||||
case ITC_SETGAS: FsmCall(ItcSetGas); goto loop;
|
||||
default: break;
|
||||
}
|
||||
EaseWrite(eab, "C0");
|
||||
return __LINE__; case __LINE__: /**********************************/
|
||||
drv->remote = 0;
|
||||
quit:
|
||||
return 0; } /* FSM END ********************************************/
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int ItcInit(SConnection *con, int argc, char *argv[], int dynamic) {
|
||||
/* args:
|
||||
temperature itc <rs232>
|
||||
<host> <port>
|
||||
MakeObject objectname itc <rs232>
|
||||
MakeObject objectname itc <host> <port>
|
||||
*/
|
||||
Eve *eve;
|
||||
pEVControl evc;
|
||||
ItcDriv *me = NULL;
|
||||
Itc *drv;
|
||||
|
||||
evc = MakeEveEVC(argc, argv, calloc(1, sizeof *me), pCon);
|
||||
if (!evc) return NULL;
|
||||
|
||||
me = evc->pDriv->pPrivate;
|
||||
me->sampleChan = 1;
|
||||
me->gasMode = 1;
|
||||
me->htrMode = 1;
|
||||
eve=&me->eve;
|
||||
|
||||
eve->run = (FsmFunc)ItcSetTemp;
|
||||
eve->read = (FsmFunc)ItcRead;
|
||||
eve->pardef = (EveParDef)ItcPars;
|
||||
eve->todo = (FsmFunc)ItcStart;
|
||||
eve->task = FsmStartTask(me, (FsmHandler)OiHandler, (FsmFunc)EveIdle);
|
||||
|
||||
/* evc->pEnvir->IsInTolerance not changed */
|
||||
EVCSetPar(evc,"upperlimit",310.0,pCon);
|
||||
EVCSetPar(evc,"lowerlimit",1.0,pCon);
|
||||
|
||||
return evc;
|
||||
drv = EaseMakeDriv(con, &itcClass, argc, argv, dynamic, 7,
|
||||
ItcParDef, OxiHandler, ItcStart, NULL, ItcRead,
|
||||
ItcSet);
|
||||
if (drv == NULL) return 0;
|
||||
drv->d.b.syntax = 0;
|
||||
ParPrintf(drv, eValue, "OI Temperature Controller");
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
static int ItcInitLc(SConnection *con, int argc, char *argv[], int dynamic) {
|
||||
/* args:
|
||||
MakeObject objectname lc <rs232>
|
||||
MakeObject objectname lc <host> <port>
|
||||
*/
|
||||
Itc *drv;
|
||||
|
||||
drv = EaseMakeDriv(con, &itcClass, argc, argv, dynamic, 7,
|
||||
ItcParDef, OxiHandler, ItcStart, NULL, ItcRead,
|
||||
ItcSet);
|
||||
if (drv == NULL) return 0;
|
||||
drv->d.b.syntax = TESLATRON;
|
||||
ParPrintf(drv, eValue, "OI Lambda Controller");
|
||||
return 1;
|
||||
}
|
||||
/*----------------------------------------------------------------------------*/
|
||||
void ItcStartup(void) {
|
||||
ParMakeClass(&itcClass, EaseDrivClass());
|
||||
MakeDriver("ITC", ItcInit, 0);
|
||||
MakeDriver("LC", ItcInitLc, 0);
|
||||
}
|
||||
|
Reference in New Issue
Block a user