/*-------------------------------------------------------------------------- D I L U T I L A few utility functions for dealing with a Dillution emperature controller CC0-510/AVSI within the SINQ setup: host -- TCP/IP -- MAC --- RS-232. Mark Koennecke, October 1997 Copyright: see copyrigh.h ---------------------------------------------------------------------------- */ #include #include #include #include #include "serialsinq.h" #include "dillutil.h" #include "../fortify.h" /* #define debug 1 */ /*-------------------------------------------------------------------------*/ int DILLU_Open(pDILLU *pData, char *pHost, int iPort, int iChannel, int iMode, char *pTransFile) { int iRet; char pCommand[80]; char pReply[132]; pDILLU self = NULL; pSTable pTable = NULL; FILE *fd = NULL; /* check translation file first */ fd = fopen(pTransFile,"r"); if(!fd) { return DILLU__FILENOTFOUND; } fgets(pReply, 131,fd); if(strstr(pReply,"DILLUTION") == NULL) { fclose(fd); return DILLU__NODILLFILE; } pTable = CreateTable(fd); fclose(fd); if(!pTable) { return DILLU__ERRORTABLE; } /* allocate a new data structure */ self = (pDILLU)malloc(sizeof(DILLU)); if(self == NULL) { return DILLU__BADMALLOC; } *pData = self; self->pTranstable = pTable; iRet = SerialOpen(&self->pData, pHost, iPort, iChannel); if(iRet != 1) { return iRet; } /* set an lengthy timeout for the configuration in order to prevent problems. */ iRet = SerialConfig(&self->pData, 100); if(iRet != 1) { return iRet; } self->iReadOnly = iMode; if(!self->iReadOnly) { /* switch to remote operation */ /* iRet = SerialWriteRead(&self->pData,"C1\r\n",pReply,131); if(iRet != 1) { return iRet; } */ } return 1; } /* --------------------------------------------------------------------------*/ void DILLU_Close(pDILLU *pData) { char pReply[132]; int iRet; pDILLU self; self = *pData; if(!self) return; /* switch to local operation */ iRet = SerialWriteRead(&self->pData,"C0\r\n",pReply,131); /* ignore errors on this one, the thing may be down */ /* close connection */ SerialClose(&self->pData); /* free memory */ free(self); *pData = NULL; } /* --------------------------------------------------------------------------*/ int DILLU_Config(pDILLU *pData, int iTmo) { int iRet; char pReply[132]; char pCommand[10]; pDILLU self; self = *pData; /* first timeout */ if(iTmo > 0) { iRet = SerialConfig(&self->pData, iTmo); if(iRet < 0) { return iRet; } } return 1; } /* --------------------------------------------------------------------------*/ int DILLU_Send(pDILLU *pData, char *pCommand, char *pReply, int iLen) { pDILLU self; self = *pData; /* make sure, that there is a \r at the end of the command */ if(strchr(pCommand,(int)'\r') == NULL) { strcat(pCommand,"\r\n"); } return SerialWriteRead(&self->pData,pCommand,pReply,iLen); } /* --------------------------------------------------------------------------*/ int DILLU_Read(pDILLU *pData, float *fVal) { char pCommand[10], pReply[132]; int iRet; float fRead = -9999.; float fOhm; pDILLU self; self = *pData; /* send D command */ sprintf(pCommand,"D\r\n"); iRet = SerialWriteRead(&self->pData,pCommand,pReply,131); if(iRet != 1) { return iRet; } /* read ohms */ iRet = sscanf(pReply,"%f",&fOhm); if(iRet != 1) { return DILLU__BADREAD; } if(fOhm > 9999890.) { return DILLU__SILLYANSWER; } /* convert to K */ iRet = InterpolateVal2(self->pTranstable,fOhm,&fRead); *fVal = fRead; return 1; } /*-------------------------------------------------------------------------*/ int DILLU_Set(pDILLU *pData, float fVal) { char pCommand[50], pReply[132]; int iRet, i,iRange, iExec; const float fPrecision = 0.0001; float fSet, fRead, fOhms, tmax, fTemp; pDILLU self; self = *pData; if(self->iReadOnly) { return DILLU__READONLY; } /* send D command to read current value*/ sprintf(pCommand,"D\r\n"); iRet = SerialWriteRead(&self->pData,pCommand,pReply,131); if(iRet != 1) { return iRet; } /* read ohms */ iRet = sscanf(pReply,"%f",&fRead); if(iRet != 1) { return DILLU__BADREAD; } if(fRead > 9999890.) { return DILLU__SILLYANSWER; } /* convert new set value to ohms */ iRet = InterpolateVal1(self->pTranstable,fVal,&fOhms); if(!iRet) { return DILLU__OUTOFRANGE; } /* set to remote operation */ #ifdef debug printf("C1\n"); #endif iRet = SerialWriteRead(&self->pData,"C1\r\n",pReply,131); if(iRet != 1) { return iRet; } /* set heater power */ strcpy(pCommand,"G3\r"); if(fOhms > 1125) { strcpy(pCommand,"G2\r"); } if(fOhms > 4000) strcpy(pCommand,"G1\r"); #ifdef debug printf("A9\n"); #endif iRet = SerialWriteRead(&self->pData,"A9\r",pReply,131); if(iRet != 1) { return iRet; } #ifdef debug printf("%s\n",pCommand); #endif iRet = SerialWriteRead(&self->pData,pCommand,pReply,131); if(iRet != 1) { return iRet; } /* Integrator time constant */ strcpy(pCommand,"G2\r"); if(fOhms > 200) strcpy(pCommand,"G1\r"); if(fOhms > 2000) strcpy(pCommand,"G0\r"); strcpy(pCommand,"G7\r"); if(fOhms > 400.) { strcpy(pCommand,"G6\r"); } #ifdef debug printf("A4\n"); #endif iRet = SerialWriteRead(&self->pData,"A4\r",pReply,131); if(iRet != 1) { return iRet; } #ifdef debug printf("%s\n",pCommand); #endif iRet = SerialWriteRead(&self->pData,pCommand,pReply,131); if(iRet != 1) { return iRet; } /* derivator time constant */ if(fOhms > 1000.) { strcpy(pCommand,"G1\r"); } else { strcpy(pCommand,"G2\r"); } #ifdef debug printf("A5\n"); #endif iRet = SerialWriteRead(&self->pData,"A5\r",pReply,131); if(iRet != 1) { return iRet; } #ifdef debug printf("%s\n",pCommand); iRet = 1; #endif iRet = SerialWriteRead(&self->pData,pCommand,pReply,131); if(iRet != 1) { return iRet; } /* proportional gain */ if(fOhms > 500.) { strcpy(pCommand,"G3\r"); } if(fOhms > 1000) { strcpy(pCommand,"G2\r"); } if(fOhms > 2000) { strcpy(pCommand,"G1\r"); } #ifdef debug printf("A6\n"); #endif iRet = SerialWriteRead(&self->pData,"A6\r",pReply,131); if(iRet != 1) { return iRet; } #ifdef debug printf("%s\n",pCommand); #endif iRet = SerialWriteRead(&self->pData,pCommand,pReply,131); if(iRet != 1) { return iRet; } /* range calculation a la Elsenhans */ iRange = 1; fTemp = fOhms*10000.; if( (fRead > 1.9) || (fOhms > 1.9) ) { iRange = 2; fTemp = fOhms*1000.; } if( (fRead > 19) || (fOhms > 19) ) { iRange = 3; fTemp = fOhms*100.; } if( (fRead > 190) || (fOhms > 190) ) { iRange = 4; fTemp = fOhms*10.; } if( (fRead > 750) || (fOhms > 750) ) { iRange = 5; fTemp = fOhms; } if( (fRead > 19000) || (fOhms > 19000) ) { iRange = 6; fTemp = fOhms/10.; } if( (fRead > 190000) || (fOhms > 190000) ) { iRange = 7; fTemp = fOhms/100.; } sprintf(pCommand,"R%1.1d\r",iRange); #ifdef debug printf("%s\n",pCommand); #endif iRet = SerialWriteRead(&self->pData,pCommand,pReply,131); if(iRet != 1) { return iRet; } /* finally set temperature */ #ifdef debug printf("Set Val befor hex: %d\n",(int)fTemp); #endif sprintf(pCommand,"G%4.4X\r",(int)fTemp); #ifdef debug printf("A3\n"); #endif iRet = SerialWriteRead(&self->pData,"A3\r",pReply,131); if(iRet != 1) { return iRet; } #ifdef debug printf("%s\n",pCommand); #endif iRet = SerialWriteRead(&self->pData,pCommand,pReply,131); if(iRet != 1) { return iRet; } /* unset remote operation, so that users may mess everything up from the panel */ #ifdef debug printf("C1\n"); #endif iRet = SerialWriteRead(&self->pData,"C0\r\n",pReply,131); if(iRet != 1) { return iRet; } return 1; } /*-------------------------------------------------------------------------*/ void DILLU_Error2Text(pDILLU *pData,int iCode, char *pError, int iLen) { char pBueffel[512]; pDILLU self; self = *pData; switch(iCode) { case DILLU__FILENOTFOUND: strncpy(pError,"Translation Table file not found",iLen); return; break; case DILLU__NODILLFILE: strncpy(pError,"Translation Table file is not DILLU",iLen); return; break; case DILLU__ERRORTABLE: strncpy(pError,"Translation Table could not be created",iLen); return; break; case DILLU__BADREAD: strncpy(pError,"Message corrupted",iLen); return; break; case DILLU__SILLYANSWER: strncpy(pError,"Message corrupted",iLen); return; break; case DILLU__BADMALLOC: strncpy(pError,"Out of memory in Open_DILLU",iLen); return; break; case DILLU__READONLY: strncpy(pError,"DILLU is read-only",iLen); return; break; case DILLU__OUTOFRANGE: strncpy(pError,"Requested value is out of range",iLen); return; break; default: SerialError(iCode,pError,iLen); break; } }