/*--------------------------------------------------------------------------- euro2kdriv.c Driver for the EuroTherm 2000 controllers (ModBus protocoll) Markus Zolliker, August 2005 ----------------------------------------------------------------------------*/ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "modbus.h" #include "fsm.h" #include "initializer.h" typedef struct { EaseDriv d; float temperature; float output; float setpoint; int adr; float par; } Euro2k; static ParClass euro2kClass = { "EURO2K", sizeof(Euro2k) }; /*----------------------------------------------------------------------------*/ void Euro2kParDef(void *object) { Euro2k *drv = ParCast(&euro2kClass, object); ParName(""); ParTail("C"); ParFloat(&drv->temperature, PAR_NAN); ParName("output"); ParTail("%"); ParFloat(&drv->output, PAR_NAN); ParName("setpoint"); ParTail("C"); ParFloat(&drv->setpoint, PAR_NAN); ParName("adr"); ParAccess(usUser); ParList(NULL); ParInt(&drv->adr, 0); if (drv->adr > 0) { ParName("par"); ParList(NULL); ParFloat(&drv->par, PAR_NAN); } EaseBasePar(drv); EaseDrivPar(drv, "%#.5g", "C"); ParStdDef(); EaseMsgPar(drv); } /*----------------------------------------------------------------------------*/ static long Euro2kRead(long pc, void *object) { Euro2k *drv = ParCast(&euro2kClass, object); EaseBase *eab = object; char *p; int l; char buf[4]; switch (pc) { default: /* FSM BEGIN *******************************/ ModBusRequestFloats(eab, 1, 3); return __LINE__; case __LINE__: /**********************************/ drv->temperature = ModBusGetFloat(eab, 1); drv->setpoint = ModBusGetFloat(eab, 2); drv->output = ModBusGetFloat(eab, 3); if (drv->adr == 0) goto noPar; ModBusRequestFloats(eab, drv->adr, 3); return __LINE__; case __LINE__: /**********************************/ drv->par = ModBusGetFloat(eab, drv->adr); noPar: ParLog(drv); fsm_quit: return 0; } /* FSM END *********************************/ } /*----------------------------------------------------------------------------*/ static long Euro2kSet(long pc, void *object) { Euro2k *drv = ParCast(&euro2kClass, object); EaseBase *eab = object; char *p; int l; char buf[4]; switch (pc) { default: /* FSM BEGIN *******************************/ ModBusPutFloats(eab, 2, 1, &drv->d.targetValue); return __LINE__; case __LINE__: /**********************************/ fsm_quit: return 0; } /* FSM END *********************************/ } /*----------------------------------------------------------------------------*/ static long Euro2kStart(long pc, void *object) { Euro2k *drv = ParCast(&euro2kClass, object); EaseBase *eab = object; switch (pc) { default: /* FSM BEGIN *******************************/ ModBusRequestFloats(eab, 1, 1); return __LINE__; case __LINE__: /**********************************/ if (0 == ModBusGetFloat(eab, 1)) { ParPrintf(drv, eError, "bad or no response on ModBus"); goto quit; } ParPrintf(drv, eStatus, "connected to euro2k"); FsmCall(Euro2kRead); return __LINE__; case __LINE__: /**********************************/ quit: return 0; } /* FSM END ********************************************/ } /*----------------------------------------------------------------------------*/ static int Euro2kInit(SConnection *con, int argc, char *argv[], int dynamic) { /* args: MakeObject objectname euro2k */ Euro2k *drv; drv = EaseMakeDriv(con, &euro2kClass, argc, argv, dynamic, 7, Euro2kParDef, ModBusHandler, Euro2kStart, NULL, Euro2kRead, Euro2kSet); if (drv == NULL) return 0; setRS232ReplyTerminator(drv->d.b.ser,""); setRS232SendTerminator(drv->d.b.ser,""); return 1; } /*----------------------------------------------------------------------------*/ void Euro2kStartup(void) { ParMakeClass(&euro2kClass, EaseDrivClass()); MakeDriver("EURO2K", Euro2kInit, 0); }