Hi Bruno,
Your device support should have a function specialLinconv() or similar,
which is function number 6 in the device support structure:
struct {
long number;
DEVSUPFUN report;
DEVSUPFUN init;
DEVSUPFUN init_record;
DEVSUPFUN get_ioint_info;
DEVSUPFUN read;
DEVSUPFUN special_linconv;
} myAi =
{
6,
NULL,
NULL,
initRecordAi,
getInIntInfoAi,
readAi,
specialLinconv
};
That function may look like this:
STATIC long specialLinconv(aiRecord *record, int after)
{
epicsUInt32 hwSpan;
myPrivate_t *priv = (myPrivate_t *)record->dpvt;
if (after) {
hwSpan = (priv->type == LCN12BMP || priv->type == LCN12BBP) ?
4095 : 65535;
record->eslo = (record->eguf - record->egul) / hwSpan;
record->eoff = record->egul;
}
return 0;
}
Call specialLinconv() from initRecordAi(). Additionally, the record will
call it automatically when anyone changes EGUL or EGUF.
In initRecordAi(), malloc a private data structure (I called it
myPrivate_t) with a field "type" (and anything else you need to store
and use later, for example in readAi). Set type and then store the
pointer to the structure in record->dpvt before calling specialLinconv().
In the record database, set EGUF to the user value that corresponds to
the maximum ADC value (4095 or 65535 depending on your ADC type) and
EGUL to the value that corresponds to the minimum ACC value (0). For
example 10 and -10 (Volts). You may change that later on the fly and
specialLinconv will adjust ESLO and EOFF.
Dirk
Bruno Seiva Martins wrote:
Hi Ralph,
Thanks for your advice! I'm still learning EPICS, so I'm using those
A/D's just for experimenting. When it comes to the real deal, I'll keep
in mind what you said.
Best regards,
Bruno Seiva Martins
On Tue, Aug 28, 2012 at 11:05 AM, Ralph Lange <[email protected]
<mailto:[email protected]>> wrote:
On Tue Aug 28 2012 15:28:34 GMT+0200 (CEST), Bruno Seiva Martins
<[email protected]> <mailto:[email protected]> wrote:
Rectifying:
epicsFloat64 div;
pao->eguf = 10.0;
pao->egul = (type == LCN12BMP || type == LCN16BMP) ? 0.0 : -10.0;
div = (type == LCN12BMP || type == LCN12BBP) ? 4095.0 : 65535.0;
pao->hopr = pao->eguf;
pao->lopr = pao->egul;
pao->eslo = ((pao->eguf) - (pao->egul)) / div;
Bruno Seiva Martins
Another comment:
The linear conversion mechanism is intended to convert the digitized
value into the final engineering units.
You might want to use your A/D converter for signals that correspond
to positions [mm], pressures [mbar], or temperatures [C].
In those cases, the database designer will set EGU, EGUL and EGUF to
e.g. "mm", -5 and 25, meaning that -10V are equivalent to -5mm, and
+10V are equivalent to +25mm. To limit the range that is shown in
the GUI, the designer might also want to set e.g. LOPR to -2 and
HOPR to +2, so that graphs and meters show the "interesting" range,
-2mm to +2mm.
To have this work correctly, setting EGUF, EGUL, HOPR and LOPR in
your device support may actually not be a good idea.
Normally, I would just set ESLO and EOFF.
Cheers,
~Ralph
- Replies:
- Re: aiRecord conversion Eric Norum
- References:
- aiRecord conversion Bruno Seiva Martins
- Re: aiRecord conversion Dirk Zimoch
- Re: aiRecord conversion Bruno Seiva Martins
- Re: aiRecord conversion Bruno Seiva Martins
- Re: aiRecord conversion Ralph Lange
- Re: aiRecord conversion Bruno Seiva Martins
- Navigate by Date:
- Prev:
Re: aiRecord conversion Eric Norum
- Next:
Re: aiRecord conversion Eric Norum
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
<2012>
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
- Navigate by Thread:
- Prev:
Re: aiRecord conversion Bruno Seiva Martins
- Next:
Re: aiRecord conversion Eric Norum
- Index:
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
<2012>
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
|