- new double control (former controlmode = 2)

- better sea client compatibility
This commit is contained in:
zolliker
2006-06-20 13:30:48 +00:00
parent c1bbdb935e
commit 735a0e6987
10 changed files with 556 additions and 94 deletions

View File

@@ -22,6 +22,7 @@
#define ARG_INT 2
#define ARG_FLT 3
#define ARG_ARR 4
#define ARG_OUT 5
/*-------------------------------------------------------------------------*/
@@ -290,14 +291,21 @@ int CocGetArray(CocConn *conn, const char *name, float *value, int value_size) {
/*-------------------------------------------------------------------------*/
int CocGetOut(CocConn *conn, const char *name, OutFunc *func) {
return(CocPushArg(conn, name, func, ARG_OUT, 0));
}
/*-------------------------------------------------------------------------*/
int CocDoIt(CocConn *conn, char *res, int res_len) {
StrBuf *buf;
int i, pending;
float *arr;
CocArg *a;
char *resp, *t, tag;
char *resp, *t, tag, *str;
int iret=0;
int siz;
OutFunc *f;
assert(conn!=NULL);
ERR_I(CocCmdWithRetry(conn));
@@ -354,6 +362,10 @@ int CocDoIt(CocConn *conn, char *res, int res_len) {
resp="<array>";
} else if (a->type==ARG_CHAR) {
ERR_P(StrNGet(buf, (char *)a->adr, a->size, COC_SEP));
} else if (a->type==ARG_OUT) {
ERR_P(str=StrNGet(buf, NULL, 0, COC_SEP));
f=(OutFunc *)a->adr;
f->func(str, f->arg);
} else {
ERR_MSG("unknown type");
}

View File

@@ -4,6 +4,11 @@
#include "myc_buf.h"
#include "coc_util.h"
typedef struct {
void (* func) (char *, void *);
void *arg;
} OutFunc;
typedef struct {
void *adr;
int type, size;
@@ -43,6 +48,7 @@ int CocGetStr(CocConn *conn, const char *name, char *value, int value_len);
int CocGetFloat(CocConn *conn, const char *name, float *value);
int CocGetInt(CocConn *conn, const char *name, int *value);
int CocGetArray(CocConn *conn, const char *name, float *value, int value_size);
int CocGetOut(CocConn *conn, const char *name, OutFunc *f);
int CocDoIt(CocConn *conn, char *error, int error_len);
int CocCheck(CocConn *conn);

View File

@@ -22,7 +22,7 @@
typedef enum { NORMAL, SPY, CLIENT, NMODE } Mode;
#define MAXMSG 256
#define MAXMSG 8192
static char *clcname="six", *servername="sics";
static int clclen=3;
@@ -580,7 +580,7 @@ int main (int argc, char *argv[]) {
int i, j, gotolevel, sicslogin;
int home;
int savehist = 0;
char buf[128], lbuf[16];
char buf[512], lbuf[16];
char stdPrompt[128]="", prompt[256]="";
char *p;
char *bar;
@@ -754,16 +754,17 @@ int main (int argc, char *argv[]) {
ERR_I(sendCmd(sock[0], "status"));
ERR_P(readWrite(12000,0,NULL));
term_read_hist(clcname, instr);
} else {
sprintf(stdPrompt, "%s[%s] ", clcname, host);
status[0]='E'; status[1]='\0';
term_read_hist(clcname, host);
}
iret=1;
buf[0]='\0';
pos=0;
term_read_hist(clcname);
savehist = 1;
while (1) {

View File

@@ -115,11 +115,13 @@ static float
maxCurrent, /* maxCurrent (not really reached for resist > 25 Ohm */
powFact=1, /* power factor (for external power supplies) */
resist=10, /* heater resistance */
tShift=0, /* setpoint shift */
empty, full, /* empty/full value for helium level */
prop, integ, deriv, /* pid */
maxShift=2, /* maximal shift in when controlMode=2 */
maxOver=0, /* maximal overshoot in when controlMode=2 */
int2=1200.0, /* integration time (sec) for doublecontrol */
tShift=0, /* setpoint shift */
maxShift=10, /* maximal shift for doublecontrol */
propUp=0.5, /* upper limit coefficient (doublecontrol) */
propDown=0.8, /* lower limit coefficient (doublecontrol) */
tm=DATA_UNDEF, /* main temperature */
ts=DATA_UNDEF, /* sample temperature */
tx=DATA_UNDEF, /* controlled temperature */
@@ -128,6 +130,7 @@ static float
tk=DATA_UNDEF, /* test temperature 2 */
he=DATA_UNDEF, /* helium level value */
aux=DATA_UNDEF, /* auxiliary value */
scanChan=DATA_UNDEF, /* scan channel */
ramp=0,
slope=0,
smooth=0,
@@ -135,8 +138,9 @@ static float
r1, r2, /* temporary values */
still=0,
linearPower=0, /* normally 0. Maximum power when loop=2 and the power linear to the output */
mout,
tInt=0; /* integral time (sec.) for setpoint shift */
shiftUp, shiftLow, /* upper and lower limit of tShift correction */
state,
mout;
static int
logPeriod=5, /* data logging period (sec.) */
@@ -146,10 +150,11 @@ static int
saveTime, /* time for a CRVSAV command */
noResp=1, /* no response */
quit, /* quit server */
controlMode=2, /* 0: control on heater, 1: control on sample, 3: 2nd loop for difference heater-sample */
controlMode=0, /* obsolete (now controlSensor/doubleControl) 0: control on heater, 1: control on sample, 2: 2nd loop for difference heater-sample */
doubleControl=0,
manual=0,
int2=30, /* inegration time for controlMode 2 */
remoteMode, /* 1: local, 2: remote */
local, /* 0: remote, 1: local */
maxfld, /* last used display field */
busy, /* busy after CRVSAV */
relay, relay0, /* relay status */
@@ -196,6 +201,7 @@ static char
alarmChannels[N_SENSORS],
alarmHistory[N_SENSORS],
swap[4],
controlSensor[4], /* '0': main two, '1': sample two, or any of "slmntkabcd" */
dev[80],
devHelp[10000],
update[32], /* update script option */
@@ -215,6 +221,8 @@ static float gradata[COC_RES_LEN/4-100];
static char grapar[128];
static int* grasize;
static char ttp[64]; /* temperature, target and power */
typedef struct {
char cmd[COC_CMD_LEN];
int logstart;
@@ -605,6 +613,8 @@ again:
slope=0;
ramp=0;
controlMode=0;
doubleControl=0;
controlSensor[0]='0';
linearPower=0;
powFact=1;
config[0]='\0';
@@ -678,10 +688,10 @@ again:
tLimit=310;
tMaxLimit=350;
} else {
tLimit=tMaxLimit;
tLimit=tMaxLimit-10;
}
} else if (tMaxLimit==0.0) {
tMaxLimit=tLimit;
tMaxLimit=tLimit+10;
} else if (tLimit>tMaxLimit) {
tLimit=tMaxLimit;
}
@@ -699,7 +709,7 @@ again:
s->band=10;
if (s->scale==0.0) s->scale=1.0;
if ((s->alarm==0.0 && typ=='m') || typ=='s') {
s->alarm=tLimit;
s->alarm=tMaxLimit;
s->customAlarm=0;
} else {
s->customAlarm=1;
@@ -904,8 +914,27 @@ void LogMinMax(int new) {
}
}
SensorT *findSensor(char txt) {
int i;
SensorT *s;
s = NULL;
txt = tolower(txt);
if (strchr("01slmntkabcde", txt) != 0) {
for (i=0; i<4; i++) {
if (txt == tolower(sensors[i]->ch[0])
|| txt == sensors[i]->typ) {
s = sensors[i];
}
}
}
return s;
}
void SetCtlSens(void) {
if (controlMode==1) {
SensorT *s;
if (controlSensor[0] == '1') {
tShift=0;
if (ctlSens==NULL) {
ctlSens=samp.sensor1;
@@ -920,8 +949,13 @@ void SetCtlSens(void) {
} else {
ctlSens=samp.sensor1;
}
} else {
if (controlMode!=2) tShift=0;
if (controlMode != 2) {
controlMode = 1;
}
} else if (controlSensor[0] == '0') {
if (!doubleControl) {
tShift=0;
}
if (ctlSens==NULL) {
ctlSens=cryo.sensor1;
} else if (ctlSens==cryo.sensor1) {
@@ -935,6 +969,26 @@ void SetCtlSens(void) {
} else {
ctlSens=cryo.sensor1;
}
if (controlMode != 2) {
controlMode = 0;
}
} else {
s = findSensor(controlSensor[0]);
if (s) {
ctlSens = s;
if (controlMode != 2) {
if (s->typ == 's' || s->typ == 'l') {
controlMode = 1;
} else {
controlMode = 0;
}
}
} else {
ctlSens = cryo.sensor1; /* should always be defined */
if (controlMode != 2) {
controlMode = 0;
}
}
}
}
@@ -1104,10 +1158,10 @@ int ReadTemp(void) {
tm=(rdTim % 3600) * 1.0e-4;
ts=(rdTim % 60) * 60.0e-4+0.5;
}
if (controlMode==0) {
tx=tm;
} else {
if (doubleControl) {
tx=ts;
} else if (ctlSens) {
tx=TrueScale(ctlSens, ctlSens->t);
}
if (auxSens != NULL) {
aux=TrueScale(auxSens, auxSens->t);
@@ -1185,8 +1239,9 @@ int ReadHeater(int full) {
int SetTemp(int switchOn) {
int showSet;
float diff, tc;
float tc;
float tLim;
if (set<0 || set>tLimit) {
set=0;
logfileOut(LOG_MAIN, "set point not within (0 ... %g), reset to 0\n", tLimit);
@@ -1199,27 +1254,17 @@ int SetTemp(int switchOn) {
if (ctlSens==NULL) return 0;
str_copy(chan, ctlSens->ch);
if (tShift>maxShift) {
tShift=maxShift;
} else if (tShift<-maxShift) {
tShift=-maxShift;
if (!doubleControl) {
tShift=0.0;
}
if (controlMode==2) {
diff=set-samp.temp;
if (diff>maxOver) { /* do overshoot */
diff=maxOver;
tShift=0;
tInt=0;
} else if (diff<-maxOver) { /* do undershoot */
diff=-maxOver;
tShift=0;
tInt=0;
}
} else {
diff=0.0;
tLim = (tLimit+tMaxLimit)*0.5;
if (set+tShift <= 0) { /* set + tShift must not be negative */
tShift = -0.999 * set;
} else if (set + tShift > tLim) { /* prevent overshoot */
tShift = tLim - set;
}
setH=FakeScale(ctlSens, set+tShift+diff);
if (setH > FakeScale(ctlSens, tLimit)) setH=FakeScale(ctlSens, tLimit);
setH=FakeScale(ctlSens, set+tShift);
if (setH > FakeScale(ctlSens, tLim)) setH=FakeScale(ctlSens, tLim);
if (switchOn) {
/* switch off other loop */
if (loop==1) {
@@ -1276,7 +1321,7 @@ int SetTemp(int switchOn) {
ERR_P(LscCmd(ser, "SETP?[loop]>fbuf"));
if (fabsf(setH-fbuf) >= (fbuf+setH)*1.0e-5) {
ERR_P(LscCmd(ser, "SETP [loop]:[setH]"));
if (controlMode!=2 && !showSet) {
if (!doubleControl && !showSet) {
logfileOut(LOG_MAIN, "set %g (on %s) (was changed %g -> %g)\n", set, ctlSens->ch, fbuf, setH);
}
} else {
@@ -1523,7 +1568,7 @@ int SetMaxPower(void) {
if (slope<0) slope=-slope;
if (slope!=0 && slope<0.1) slope=0.1;
SetCtlSens();
fbuf=FakeScale(ctlSens, tLimit);
fbuf=FakeScale(ctlSens, (tLimit + tMaxLimit)*0.5);
if (loop==1) {
PidSumHdl(COC_RD, NULL, 0);
if (!initMaxPower && lastCurrent != maxCurrent && lastCurrent != 0) {
@@ -1665,6 +1710,7 @@ int Settings(void) {
if (remoteMode!=2) {
remoteMode=2; /* set to remote mode */
local=0;
ERR_I(LoadFromLsc());
ERR_P(LscCmd(ser, "MODE:[remoteMode]"));
} else {
@@ -1846,13 +1892,260 @@ int ConfigByName(int plugNr) {
return -1;
}
#define HISTSIZE 65
typedef struct {
int init;
float vals[HISTSIZE];
float fore;
float weight;
float err;
} Hist;
/*
static Hist fore, mFore;
*/
float forecast(Hist *h, float value, int tim, int nmax) {
int i, n, stp, ne;
float d1, d2, d, vmean, vsig, val, val1, fact, fact1;
float emean, esig, errLin, valLin;
if (h->init == 0) { /* put a start value */
h->init = 1;
for (i=0; i<HISTSIZE; i++) {
h->vals[i] = value;
}
h->err = value;
return value;
}
for (i=HISTSIZE-1; i>0; i--) {
h->vals[i] = h->vals[i-1];
}
h->vals[0] = value;
h->err = value;
h->fore = 0;
errLin = value;
valLin = value;
for (stp = 1; stp*4 < HISTSIZE; stp *= 2) {
vmean = 0;
vsig = 0;
n = 0;
val1 = 0;
emean = 0;
esig = 0;
ne = 0;
for (i = 0; i < stp*nmax && i + 2 * stp < HISTSIZE; i += stp) {
d1 = h->vals[i+stp] - h->vals[i];
d2 = h->vals[i+2*stp] - h->vals[i+stp];
if (fabs(d2) > fabsf(d1) && d1 * d2 >= 0 && n >= 0) {
/* exponential extrapolation */
fact = d1 / d2;
val = h->vals[i] - d1 * fact / (1 - fact);
if (n == 0) {
fact1 = fact;
val1 = val;
}
n++;
d = val - vmean;
vmean += d / n;
vsig += d * (val - vmean);
} else {
n = -1; /* exponential interpolation not possible */
}
/* linear extrapolation */
val = h->vals[i] - 2 * d1 * tim / stp;
ne++;
d = val - emean;
emean += d / ne;
esig += d * (val - emean);
val = h->vals[i];
ne++;
d = val - emean;
emean += d / ne;
esig += d * (val - emean);
}
if (n > 1) {
vsig = sqrt(vsig / (n - 1));
if (vsig < h->err) {
h->err = vsig;
h->fore = val1;
if (fact1 > 0.9) {
h->weight = (1 - fact1) / stp;
} else {
h->weight = 1 - pow(fact1, 1.0/stp);
}
}
}
esig = sqrt(esig / (ne - 1));
if (esig < errLin) {
errLin = esig;
valLin = emean;
}
}
h->init = 1;
if (h->fore == 0) {
h->fore = valLin;
h->err = errLin;
h->init = -1;
h->weight = 1.0 / tim;
}
return h->fore;
}
#define MAXTIMES 16
typedef struct {
int init;
int ntimes;
float period;
float mn[MAXTIMES];
float mx[MAXTIMES];
float upper;
float lower;
} Stat;
static Stat mStat, sStat;
void statInit(Stat *s, float mn, float mx) {
int i;
assert(mx >= mn);
for (i=1; i < MAXTIMES; i++) {
s->mn[i] = mn;
s->mx[i] = mx;
}
}
void statCrop(Stat *s, float mn, float mx) {
int i;
float d;
if (mn > s->upper) {
d = mn - s->upper;
for (i=1; i < MAXTIMES; i++) {
s->mx[i] += d;
}
}
if (mx < s->lower) {
d = mx - s->lower;
for (i=1; i < MAXTIMES; i++) {
s->mn[i] += d;
}
}
}
void statBegin(Stat *s, float period, float value) {
s->ntimes = 0;
s->period = period;
s->mn[0] = value;
s->mx[0] = value;
if (s->init == 0) { /* put a start value */
s->init = 1;
statInit(s, value*0.9, value*1.1);
}
s->lower = 0;
s->upper = 0;
}
int statTime(Stat *s, float tim1, float tim2) {
float w1, w2, dif, mn, mx;
int i;
i = s->ntimes;
assert(tim1 <= tim2);
assert(i < MAXTIMES-1);
mn = s->mn[s->ntimes];
mx = s->mx[s->ntimes];
s->ntimes++;
i = s->ntimes;
s->upper = s->mx[i];
s->lower = s->mn[i];
if (tim1 <= 0) {
w1 = 1;
} else {
w1 = 1 - exp(-s->period / tim1);
}
if (tim2 <= 0) {
w2 = 1;
} else {
w2 = 1 - exp(-s->period / tim2);
}
dif = mx - s->mx[i];
if (dif > 0) {
s->mx[i] += w1 * dif;
} else {
s->mx[i] += w2 * dif;
}
dif = mn - s->mn[i];
if (dif < 0) {
s->mn[i] += w1 * dif;
} else {
s->mn[i] += w2 * dif;
}
return i;
}
void statEnd(Stat *s) {
int i;
i = s->ntimes;
if (s->upper < s->mx[i]) {
s->upper = s->mx[i];
}
if (s->lower > s->mn[i]) {
s->lower = s->mn[i];
}
}
typedef struct {
float slope;
float last;
float mx;
int wasmax;
time_t lastTim;
} Slope;
void maxSlope(Slope *s, float value) {
float d;
if (rdTim <= s->lastTim + per*0.0015) {
return;
}
s->wasmax = 0;
if (s->slope < 0) {
s->last = value;
s->lastTim = rdTim;
s->slope = 0;
} else {
d = (value - s->last) / (rdTim - s->lastTim);
s->slope = d;
if (fabsf(d) > s->mx) {
s->mx = fabsf(d);
s->wasmax = 1;
}
}
s->last = value;
s->lastTim = rdTim;
}
static Slope slopeS, slopeU, slopeL;
int PeriodicTask(void) {
static int lastIntTim;
char buf[256], lbuf[16];
char *next, *alms;
int i, k, cnt;
float p, d, w, t, dif, htr0, mstep, fdif;
float t, htr0, mstep, fdif, d, dif2, ml;
static time_t finTime;
static int lastIntTim;
static float dif=0;
static float oldSet=0;
static float oldShift=0;
/*
static float shiftTarget=0;
*/
if (nScan==0) {
ERR_P(LscCmd(ser, "DIOST?>cod1,out1;DOUT 3,29;BUSY?>busy"));
} else {
@@ -1997,6 +2290,8 @@ int PeriodicTask(void) {
ERR_I(ReadTemp());
snprintf(ttp, sizeof(ttp), "%.6g %.6g %.6g", tm, tr, power);
if (htrst!=htrst0) {
LogMinMax(0);
if (htrst==0) {
@@ -2075,24 +2370,85 @@ int PeriodicTask(void) {
lastIntTim=0;
}
}
if (cryo.sensor1!=samp.sensor1 && controlMode==2) {
d=fdif/t; /* relative difference */
w=exp(-d*d*230); /* gaussian */
/* if (w<0.1) tInt=0; reset when far from setpoint (more than 10 %) */
if (int2<1) int2=1;
if (tInt<int2) tInt+=w*per/1000; /* increase integral time until int2 sec. */
if (tInt>w) {
p=w/tInt;
} else {
p=1.0;
ml = set/100;
if (ml == 0) ml = 1;
statBegin(&mStat, per*0.001, TrueScale(ctlSens, ctlSens->t));
statTime(&mStat, 10, 20);
statTime(&mStat, int2/16, int2/2);
statTime(&mStat, int2/1.5, int2+10);
statEnd(&mStat);
statBegin(&sStat, per*0.001, samp.temp);
statTime(&sStat, 10, 20);
statEnd(&sStat);
maxSlope(&slopeS, samp.temp);
maxSlope(&slopeU, mStat.upper);
maxSlope(&slopeL, mStat.lower);
/* statBegin(&sStat, maxShift*0.01, per*0.001, samp.temp); */
d = set - samp.temp;
shiftLow = mStat.lower - sStat.upper;
shiftUp = mStat.upper - sStat.lower;
if (cryo.sensor1!=samp.sensor1 && doubleControl) {
dif2 = d - dif;
if (oldSet == 0) oldSet = samp.temp;
if (oldSet != set || fabsf(d) > 50*ml) {
if (oldSet != set) {
if (set < oldSet) {
tShift *= set/oldSet;
}
state = 1;
} else {
state = 0;
}
finTime = rdTim + int2 + 30;
slopeS.mx = -1;
slopeU.mx = -1;
slopeL.mx = -1;
}
dif=cryo.temp-samp.temp;
tShift=tShift*(1.0-p)+p*(cryo.temp-samp.temp);
if (rdTim < finTime) {
if (slopeS.wasmax) {
finTime = rdTim + int2 + 30;
}
if (fabs(slopeS.slope) > slopeS.mx * 0.2
&& finTime < rdTim + per * 0.0035) {
finTime = rdTim + per * 0.0035;
}
if (d > 0) {
tShift = oldShift + propUp * d;
} else {
tShift = oldShift + propDown * d;
}
} else {
if (state != 2) {
tShift = oldShift;
state = 2;
statCrop(&mStat, sStat.lower+tShift, sStat.upper+tShift);
}
if (shiftLow > tShift) {
tShift = shiftLow;
} else if (shiftUp < tShift) {
tShift = shiftUp;
}
oldShift = tShift;
}
if (tShift > ml * maxShift) {
tShift = ml * maxShift;
} else if (tShift < -ml * maxShift) {
tShift = - ml * maxShift;
}
dif = d;
ERR_I(SetTemp(0));
} else {
ERR_I(SetTemp(0));
}
} else {
oldShift = 0;
}
oldSet = set;
if (nScan==0) {
ERR_P(LscCmd(ser, "KEYST?>key;DIOST?>cod2,out2;DOUT 3,30"));
@@ -2114,6 +2470,13 @@ int PeriodicTask(void) {
if (out1==30 && out2==29) {
/* code conversion */
plug0.code1=3*decod[cod2 % 8] ^ 2*decod[cod1 % 8]; /* ^ is exclusive OR */
if ((plug0.code1 & 0x2a) == 0x20) {
/* for external switch (MA09) */
scanChan = cod1 & 0x03;
plug0.code1 = plug0.code1 & 0x30;
} else {
scanChan = DATA_UNDEF;
}
plug1.code1=-(3*decod[cod2 / 8] ^ 2*decod[cod1 / 8]);
for (i=0; i<2; i++) {
plug=plugs[i];
@@ -2145,6 +2508,7 @@ int PeriodicTask(void) {
if (key!=0) {
ERR_P(LscCmd(ser, "MODE?>remoteMode"));
local = (remoteMode == 1);
if (!touched) {
touched=1;
logfileOut(LOG_MAIN ,"user touched keys\n");
@@ -2153,7 +2517,7 @@ int PeriodicTask(void) {
logfileOut(LOG_MAIN ,"user switched to remote\n");
touched=0;
ERR_I(LoadFromLsc());
if (controlMode==2) {
if (doubleControl) {
ERR_P(LscCmd(ser, "RANGE?>iRange"));
if (iRange==0) set=0;
} else {
@@ -2261,32 +2625,25 @@ int TLimitHdl(int mode, void *base, int fd) {
}
int SwapHdl(int mode, void *base, int fd) {
int i,j;
static int idx[2];
static char swp;
static SensorT *s1, *s2;
if (mode==COC_WR) {
if (strlen(swap) != 2) ERR_MSG("must be 2 letters");
str_lowcase(swap, swap);
for (j=0; j<2; j++) {
idx[j]=-1;
for (i=0; i<4; i++) {
if (swap[j] == tolower(sensors[i]->ch[0])) {
swap[j]=sensors[i]->typ;
}
if (sensors[i]->typ == swap[j]) idx[j]=i;
}
if (strchr("msnltk", swap[j]) == 0) ERR_MSG("only letters m,s,n,l,e,k are allowed");
s1 = findSensor(swap[0]);
s2 = findSensor(swap[1]);
if (s1 == NULL || s2 == NULL) {
ERR_MSG("no such sensor(s)");
}
if (idx[0]==idx[1]) {
if (idx[0]<0) ERR_MSG("no such sensors");
if (s1 == s2) {
return 0;
}
return COC_DWR;
} else if (mode==COC_DWR) {
for (j=0; j<2; j++) {
if (idx[j]>=0) {
sensors[idx[j]]->typ=swap[1-j];
}
}
swp = s1->typ;
s2->typ = s1->typ;
s1->typ = swp;
AssignTypes();
}
return 0;
@@ -2381,7 +2738,6 @@ int SetHdl(int mode, void *base, int fd) {
ERR_P(LscCmd(ser, "CMODE [loop],1;MOUT [loop],0"));
}
if (cryo.sensor1!=NULL && remoteMode==2) {
tInt=0; /* reset integral time */
ERR_I(SetTemp(1));
}
}
@@ -2389,6 +2745,26 @@ int SetHdl(int mode, void *base, int fd) {
OnError: return -1;
}
int ControlModeHdl(int mode, void *base, int fd) {
if (mode==COC_WR) {
if (controlMode == 1) {
controlSensor[0]='1';
} else {
controlSensor[0]='0';
}
if (controlMode >= 2) {
doubleControl = 1;
controlMode = 2;
} else {
doubleControl = 0;
if (controlMode < 0) {
controlMode = 0;
}
}
}
return SetHdl(mode, base, fd);
}
int MaxPowerHdl(int mode, void *base, int fd) {
static float setpower;
if (mode==COC_WR) {
@@ -2764,6 +3140,17 @@ int RemoteHdl(int mode, void *base, int fd) {
OnError: return -1;
}
int LocalHdl(int mode, void *base, int fd) {
if (mode==COC_RD) {
local = (remoteMode == 1);
return 0;
} else if (mode==COC_WR) {
remoteMode = 1 + (local == 0);
return RemoteHdl(mode, base, fd);
}
return 0;
}
int RelayHdl(int mode, void *base, int fd) {
if (mode==COC_WR) {
if (alarmChannels[0]!='\0') ERR_MSG("alarm is still active");
@@ -2845,7 +3232,6 @@ int MainBody(void) {
per=1000; /* 1 sec */
cryo.temp=0;
samp.temp=0;
/* remoteMode=1; */
noResp=3;
} else if (noResp < 2) {
logfileShowErr("no response");
@@ -2922,8 +3308,10 @@ int main(int argc, char *argv[]) {
CocDefFlt(setH, RD);
CocDefFlt(full, RW);
CocDefFlt(empty, RW);
CocDefFlt(int2, RW);
CocDefFlt(propUp, RW);
CocDefFlt(propDown, RW);
CocDefFlt(maxShift, RW);
CocDefFlt(maxOver, RW);
CocDefFlt(tm, RD);
CocDefFlt(ts, RD);
CocDefFlt(tr, RD);
@@ -2936,8 +3324,12 @@ int main(int argc, char *argv[]) {
CocDefFlt(r1, RD);
CocDefFlt(r2, RD);
CocDefFlt(tShift, RW);
CocDefFlt(tInt, RW);
CocDefFlt(linearPower, RW);
CocDefFlt(scanChan, RW);
CocDefFlt(shiftUp, RW);
CocDefFlt(shiftLow, RW);
CocDefFlt(state, RW);
CocDefPtr(clData, ClientData);
CocStrFld(ClientData, cmd, RW); CocHdl(SendHdl);
@@ -2966,6 +3358,7 @@ int main(int argc, char *argv[]) {
CocDefStr(devHelp, RD); CocHdl(DevHelpHdl);
CocDefStr(update, RW); CocHdl(UpdateHdl);
CocDefStr(lscfg, RD);
CocDefStr(ttp, RD);
CocDefInt(cod1, RD);
CocDefInt(cod2, RD);
@@ -2978,6 +3371,7 @@ int main(int argc, char *argv[]) {
CocDefInt(iRange, RD);
CocDefInt(jRange, RD);
CocDefInt(remoteMode, RW); CocHdl(RemoteHdl);
CocDefInt(local, RW); CocHdl(LocalHdl);
CocDefInt(relay, RW); CocHdl(RelayHdl);
CocDefInt(manual, RW); CocHdl(ManualHdl);
CocDefInt(htrst, RD);
@@ -2989,14 +3383,16 @@ int main(int argc, char *argv[]) {
CocDefInt(logMask, RW);
CocDefInt(logPeriod, RW);
CocDefInt(readTemp, RW);
CocDefInt(controlMode, RW); CocHdl(SetHdl);
CocDefInt(int2, RW);
CocDefInt(controlMode, RW); CocHdl(ControlModeHdl);
CocDefInt(busy, RD);
CocDefInt(serialNo, RD);
CocDefInt(quit, RW);
CocDefInt(nScan, RD);
CocDefInt(keepT, RW);
CocDefInt(swRangeOn, RW);
CocDefInt(doubleControl, RW);
CocDefStr(controlSensor, RW); CocHdl(SetHdl);
CocDefStr(grapar, RA);
CocDefArr(gradata, RD); CocHdl(GraHdl); grasize=CocSizePtr();
@@ -3136,8 +3532,17 @@ int main(int argc, char *argv[]) {
ERR_P(DataCreateSet(NULL, "T4", &sensA4.t, logPeriod, LOGLIFETIME, tim));
ERR_P(DataCreateSet(NULL, "Aux", &aux, logPeriod, LOGLIFETIME, tim));
ERR_P(DataCreateSet(NULL, "P", &power, logPeriod, LOGLIFETIME, tim));
ERR_P(DataCreateSet(NULL, "ScanChan", &scanChan, logPeriod, LOGLIFETIME, tim));
DataUndef(0);
ERR_P(DataCreateSet(NULL, "Set", &set, logPeriod, LOGLIFETIME, tim));
ERR_P(DataCreateSet(NULL, "shiftUp", &shiftUp, logPeriod, LOGLIFETIME, tim));
ERR_P(DataCreateSet(NULL, "shiftLow", &shiftLow, logPeriod, LOGLIFETIME, tim));
ERR_P(DataCreateSet(NULL, "state", &state, logPeriod, LOGLIFETIME, tim));
DataUndef(DATA_UNDEF);
ERR_P(DataCreateSet(NULL, "tShift", &tShift, logPeriod, LOGLIFETIME, tim));
remoteMode=2;
local = 0;
prop=50;
integ=20;
deriv=0;

View File

@@ -91,6 +91,22 @@ int TeccGetX(pTecsClient conn, float *tC, float *tP, float *tDif) {
OnError: return(-1);
}
int TeccGetMult(pTecsClient conn, int argc, char *argv[], void (* outfunc)(char *, void *), void *arg) {
OutFunc f;
int iret, i;
f.func = outfunc;
f.arg = arg;
CocReset(conn);
for (i=0; i<argc; i++) {
ERR_I(CocGetOut(conn, argv[i], &f));
}
ERR_I(iret=CocDoIt(conn, response, sizeof(response)));
if (iret) ERR_MSG(response);
return 0;
OnError: return -1;
}
int TeccSet(pTecsClient conn, float temp) {
int iret;

View File

@@ -23,6 +23,9 @@ int TeccGetX(pTecsClient conn, float *tC, float *tP, float *tDif);
int TeccGet3(pTecsClient conn, float *tSet, float *tExch, float *tSamp);
/* get temperatures */
int TeccGetMult(pTecsClient conn, int argc, char *argv[], void (* outfunc)(char *, void *), void *arg);
/* get multiple values */
int TeccSet(pTecsClient conn, float temp);
/* set temperature */

View File

@@ -33,6 +33,7 @@ typedef struct Set {
int step, lifetime;
int start, end;
float *var;
float undef;
Run *runs;
Summary sum;
Logger *log;
@@ -50,6 +51,12 @@ typedef struct {
static Base database;
static float undef_value = DATA_UNDEF; /* additonal undef value */
void DataUndef(float undef) {
undef_value = undef;
}
void InsSum(Summary *sum, int t, float d) {
if (sum->tmin == 0) {
sum->tmin = t;
@@ -127,6 +134,7 @@ Set *CreateSet(Base *base, char *name, float *var, int step, int lifetime, int s
s->start = start;
s->step = step;
s->var = var;
s->undef = undef_value;
s->log = NULL;
ResetSum(&s->sum);
return s;
@@ -273,6 +281,7 @@ int DataPutAll(DataBase *base, int mytime) {
char value[32];
char tname[32];
static time_t lastOpen = 0;
float val;
if (base == NULL) {
s=database.head;
@@ -281,8 +290,12 @@ int DataPutAll(DataBase *base, int mytime) {
}
while (s!=NULL) {
if (s->var!=NULL) {
ERR_I(Put(s, mytime, *s->var));
if (s->log == NULL && *s->var != DATA_UNDEF && time(NULL) > lastOpen + 300) {
val = *s->var;
if (val == s->undef) {
val = DATA_UNDEF;
}
ERR_I(Put(s, mytime, val));
if (s->log == NULL && val != DATA_UNDEF && time(NULL) > lastOpen + 300) {
/* try to make logger if not yet tried in the last 5 min. */
snprintf(tname, sizeof tname, "tt.%s", s->set.name);
s->log = LoggerMake(tname, s->step, 0);
@@ -291,10 +304,10 @@ int DataPutAll(DataBase *base, int mytime) {
}
}
if (s->log != NULL) {
if (*s->var == DATA_UNDEF) {
if (val == DATA_UNDEF) {
value[0]='\0';
} else {
snprintf(value, sizeof value, "%.5g", *s->var);
snprintf(value, sizeof value, "%.5g", val);
}
LoggerWrite(s->log, mycUnixTime(mytime), s->step, value);
}

View File

@@ -40,6 +40,8 @@ int DataGetMult(char *names, int startTime, int endTime, int step, int stdStep,
get multiple datasets
*/
void DataUndef(float undef);
/*
define DATA_UNDEF as a binary and decimal well defined, hopefully rarely used number
*/

View File

@@ -191,7 +191,8 @@ FILE *term_open_pref(int temp, char *head, char *mode) {
char *usr, *home, *p;
int l;
FILE *fil;
mode_t oldmask;
usr = getenv("USER");
if (temp && usr==NULL) return NULL;
if (usr != NULL && *usr != '\0' && strstr(usr, "lnsg") != 0) {
@@ -226,7 +227,9 @@ FILE *term_open_pref(int temp, char *head, char *mode) {
str_append(old, usr);
/* new file name */
str_copy(buf, "/tmp/six/");
mkdir(buf, S_IRWXU+S_IRGRP+S_IXGRP+S_IROTH+S_IXOTH);
oldmask = umask(0);
mkdir(buf, S_IRWXU+S_IRWXG+S_IRWXO);
umask(oldmask);
str_append(buf, head);
str_append(buf, ".");
str_append(buf, usr); /* usr is the username, or lnsg_<subdirectory> */
@@ -296,13 +299,14 @@ void term_save_hist(int trimlast) {
fclose(fil);
}
void term_read_hist(char *id) {
void term_read_hist(char *id, char *instr) {
FILE *fil;
int i;
char buf[1024], *lin;
str_copy(filehead, id);
str_append(filehead, "_hist");
str_append(filehead, "_hist_");
str_append(filehead, instr);
fil=term_open_pref(1, filehead, "r");
if (fil==NULL) return;
hist_end=0;
@@ -340,8 +344,8 @@ int term_get_line(char *buf, int size, int *pos, char *prompt, fd_set *mask) {
char *lin;
int key;
int i,l,iret,buflen;
char tmp[512];
static char back[128]="";
char tmp[1024];
static char back[512]="";
if (back[0] == '\0') {
memset(back, '\b', sizeof back);

View File

@@ -30,7 +30,7 @@ FILE *term_open_pref(int temp, char *head, char *mode);
char *term_fgets(char *buf, int size, FILE *fil);
/* fgets without newline */
void term_read_hist(char *id);
void term_read_hist(char *id, char *instr);
/* read history from temporary file with id */
void term_save_hist(int trimlast);