Argonne National Laboratory

Experimental Physics and
Industrial Control System

1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017  Index 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017 
<== Date ==> <== Thread ==>

Subject: bug in break-point table conversion
From: Rolf Keitel <rolf@triumf.ca>
To: tech_talk <tech-talk@aps.anl.gov>
Date: Fri, 12 May 2006 09:15:58 -0700
There is a problem with break-point table conversion from engineering to raw values ( function cvtEngToRawBpt in file cvtBpt.c).
The function returns incorrect results, if the breakpoint table has negative slopes, i.e. if engineering values decrease with increasing raw values.
The faulty routine and one possible fix are attached below.
Here is the printout from a test program, which converts raw values to engineering values and back to raw values:


Breakpoint Table:
0 -- 186 475 slope -0.203488
1 -- 358 440 slope -0.196078
2 -- 562 400 slope -0.199601
3 -- 1063 300 slope -0.207612
4 -- 1641 180 slope -0.22409
5 -- 1998 100 slope -0.257732
6 -- 2192 50 slope -0.266667
7 -- 2267 30 slope -0.101695
8 -- 2326 24 slope -0.0261438
9 -- 2632 16 slope -0.0217391
10 -- 2908 10 slope -0.0139373
11 -- 3195 6 slope -0.0152672

    raw     eng         raw
bit:  500 ==> 412.157 ==> 494.829 (index 1 0)
bit:  800 ==> 352.495 ==> 788.025 (index 2 0)
bit: 1100 ==> 292.318 ==> 1083.75 (index 3 0)
bit: 1400 ==> 230.035 ==> 1389.83 (index 3 0)
bit: 1700 ==> 166.779 ==> 1700.69 (index 4 0)
bit: 2000 ==> 99.4845 ==> 2031.39 (index 5 0)
bit: 2300 ==> 26.6441 ==> 2389.35 (index 7 0)
bit: 2600 ==> 16.8366 ==> 2437.55 (index 8 0)
bit: 2900 ==> 10.1739 ==> 2470.29 (index 9 0)


>>>>>>>>>>>>>> faulty function


long cvtEngToRawBpt(double *pval,short linr,short init,
void **ppbrk,short *plbrk)
{ double val=*pval;
long status=0;
brkTable *pbrkTable;
brkInt *pInt; brkInt *pnxtInt;
short lbrk;
int number;



if(linr < 2) return(-1); if(init==TRUE || *ppbrk == NULL) { /*must find breakpoint table*/ pbrkTable = findBrkTable(linr); if(!pbrkTable) return(S_dbLib_badField); *ppbrk = (void *)pbrkTable; /* Just start at the beginning */ *plbrk=0; } pbrkTable = (struct brkTable *)*ppbrk; number = pbrkTable->number; lbrk = *plbrk; /*make sure we dont go off end of table*/ if( (lbrk+1) >= number ) lbrk--; pInt = pbrkTable->papBrkInt[lbrk]; pnxtInt = pbrkTable->papBrkInt[lbrk+1]; /* find entry for increased value */ while( (pnxtInt->eng) <= val ) { lbrk++; pInt = pbrkTable->papBrkInt[lbrk]; if( lbrk >= number-1) { status=1; break; } pnxtInt = pbrkTable->papBrkInt[lbrk+1]; } while( (pInt->eng) > val) { if(lbrk==0) { status=1; break; } lbrk--; pInt = pbrkTable->papBrkInt[lbrk]; } if(pInt->slope!=0){ *plbrk = lbrk; *pval = pInt->raw + (val - pInt->eng) / pInt->slope; } else { return(status); } return(0); }

*>>>>>>>>>>>>>> possible fix*

long cvtEngToRawBpt(double *pval,short linr,short init,
void **ppbrk,short *plbrk)
{ double val=*pval;
long status=0;
brkTable *pbrkTable;
brkInt *pInt; brkInt *pnxtInt;
short lbrk;
int number;



if(linr < 2) return(-1);
if(init==TRUE || *ppbrk == NULL) { /*must find breakpoint table*/
pbrkTable = findBrkTable(linr);
if(!pbrkTable) return(S_dbLib_badField);
*ppbrk = (void *)pbrkTable;
/* Just start at the beginning */
*plbrk=0;
}
pbrkTable = (struct brkTable *)*ppbrk;
number = pbrkTable->number;
lbrk = *plbrk;
/*make sure we dont go off end of table*/
if( (lbrk+1) >= number ) lbrk--;
pInt = pbrkTable->papBrkInt[lbrk];
pnxtInt = pbrkTable->papBrkInt[lbrk+1];
if (pInt->slope > 0) { /* positive slopes */
/* find entry for increased value */
while( (pnxtInt->eng) <= val ) {
lbrk++;
pInt = pbrkTable->papBrkInt[lbrk];
if( lbrk >= number-1) {
status=1;
break;
}
pnxtInt = pbrkTable->papBrkInt[lbrk+1];
}
while( (pInt->eng) > val) {
if(lbrk==0) {
status=1;
break;
}
lbrk--;
pInt = pbrkTable->papBrkInt[lbrk];
}
} else { /* negative slopes */
/* find entry for decreased value */
while( (pnxtInt->eng) >= val ) {
lbrk++;
pInt = pbrkTable->papBrkInt[lbrk];
if( lbrk >= number-1) {
status=1;
break;
}
pnxtInt = pbrkTable->papBrkInt[lbrk];
}
while( (pInt->eng) < val) {
if(lbrk==0) {
status=1;
break;
}
lbrk--;
pInt = pbrkTable->papBrkInt[lbrk];
}
}
if(pInt->slope!=0){
*plbrk = lbrk;
*pval = pInt->raw + (val - pInt->eng) / pInt->slope;
}
else {
return(status);
}
return(0);
}
--
+-------------------------------------------------+
| Rolf Keitel, TRIUMF Tel: (604) 222-7453 |
| Group Leader ISAC Controls Fax: (604) 222-7307 |
| and Electronics Development |
| Vancouver, B.C., Canada |
+-------------------------------------------------+



Replies:
Re: bug in break-point table conversion D. Peter Siddons

Navigate by Date:
Prev: RE: Naming Conventions and Control Logix Dalesio, Leo `Bob`
Next: Re: EDM Command Options Question Devin Bougie
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017 
Navigate by Thread:
Prev: RE: Naming Conventions and Control Logix Dalesio, Leo `Bob`
Next: Re: bug in break-point table conversion D. Peter Siddons
Index: 1994  1995  1996  1997  1998  1999  2000  2001  2002  2003  2004  2005  <20062007  2008  2009  2010  2011  2012  2013  2014  2015  2016  2017 
ANJ, 02 Sep 2010 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·