EPICS Controls Argonne National Laboratory

Experimental Physics and
Industrial Control System

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  <20192020  2021  2022  2023  2024  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  <20192020  2021  2022  2023  2024 
<== Date ==> <== Thread ==>

Subject: RE: Stream device - parsing array of pairs of floats
From: Joao Afonso via Tech-talk <[email protected]>
To: Andrew Johnson <[email protected]>, "[email protected]" <[email protected]>, "[email protected]" <[email protected]>
Cc: Stephen Page <[email protected]>
Date: Tue, 19 Feb 2019 12:38:07 +0000
Hello all,

Thank you very much for your suggestions using StreamDevice and/or aSub.

I was able to get a solution that works, using the following records:

1) Two streamdevice waveform records, to send/receive the char array to/from the device. They don't split yet the data, just handle the communication protocol.
record(waveform, "REF:TABLE:G")
{
field(DTYP, "stream")
field(FTVL, "CHAR")
field(NELM, "65536")
field(SCAN, "Passive")
field(INP, "@fgc.proto get_string($(FGC), REF.TABLE.FUNCTION) $(PORT)")
# field(FLNK, "REF:TABLE:READ PP")
}

record(waveform, "REF:TABLE:S")
{
field(DTYP, "stream")
field(FTVL, "CHAR")
field(NELM, "65536")
field(SCAN, "Passive")
field(INP, "@fgc.proto set_string($(FGC), REF.TABLE.FUNCTION) $(PORT)")
}
2) Two aSub records. One to parse and split the data from REF:TABLE:G into REF:TABLE:TIME and REF:TABLE:REF.
The other does the opposite: merge the data from REF:TABLE:TIME and REF:TABLE:REF into REF:TABLE:S.
record(aSub, "REF:TABLE:READ")
{
field(SNAM, "time_val_read")
field(SCAN, "Passive")
field(FTA, "CHAR")
field(FTVA, "DOUBLE")
field(FTVB, "DOUBLE")
field(NOA, "65536")
field(NOVA, "1024")
field(NOVB, "1024")
field(INPA, "REF:TABLE:G PP")
field(OUTA, "REF:TABLE:TIME")
field(OUTB, "REF:TABLE:REF")
}

record(aSub, "REF:TABLE:WRITE")
{
field(SNAM, "time_val_write")
field(SCAN, "Passive")
field(FTA, "DOUBLE")
field(FTB, "DOUBLE")
field(FTVA, "CHAR")
field(NOA, "1024")
field(NOB, "1024")
field(NOVA, "65536")
field(INPA, "REF:TABLE:TIME")
field(INPB, "REF:TABLE:REF")
field(OUTA, "REF:TABLE:S PP")
}
3) Two double waveform records to contain the two parsed arrays.
record(waveform, "REF:TABLE:REF")
{
field(FTVL, "DOUBLE")
field(NELM, "1024")
}

record(waveform, "REF:TABLE:TIME")
{
field(FTVL, "DOUBLE")
field(NELM, "1024")
}

Overall this works as intended, but I have a few more questions:

a) According to StreamDevice documentation:
"Note that input links with PP flag pointing to a StreamDevice record will read the old value first and start the protocol afterward. This is a problem all asynchronous EPICS device supports have."

I noticed this at first while testing this records. If I process the read aSub record:
> caput TEST:REF:TABLE:READ.PROC 1
It will use the old value from streamdevice, not the new one.

Of course, this is fixable by using a FLNK in the REF:TABLE:G records (as commented in the code above).
But it means that for reading I would be triggering a streamdevice record, while for writing I would be triggering a aSub record.

Is it possible to do this in a symmetric way?
I.e. be able to read/write by triggering only the streamdevice or the aSub records?

b) For these cases, is it possible to propagate the errors from the streamdevice to aSub records? Or does it only work for INP links?

c) When read a double type waveform using caget:
> caget REF:TABLE:REF,
it prints all the allocated array elements and the size NELM (in this case the 1024 elements). It seems to ignore the NORD field, which contains the actual number of valid elements on the array and may be much smaller.
Is this the normal behavior for EPICS records, when I get an array value without knowing the size?

Thank you in advance,
Joao Afonso

________________________________________
From: Johnson, Andrew N. [[email protected]]
Sent: 15 February 2019 17:36
To: Joao Afonso; [email protected]
Subject: Re: Stream device - parsing array of pairs of floats

Hi Joao,

On 2/14/19 11:35 AM, Joao Afonso via Tech-talk wrote:
> I have a string returned by a device, representing an array where each
> element is a pair <time, value>:
>
> - each pair is separated by "|": <timestamp>|<value>
> - each element of the array separated by ","
> - all values are floats
> - the timestamp increment may not be linear (that is why it needs to
> be recorded)
>
> Example
> 0.1000|0.1230000E+00,0.2000|0.4560000E+00,0.3000|0.7890000E+00, [...]
>
> Is it possible to parse this using stream device (into two waveform
> records)?
> Or do I have to use something more powerful such as asynDriver?
> I have seen several examples, but only with using simple type
> elements, not like this.
>
> As a followup, is it possible to do the inverse, merging two waveform
> records into a string?
Dirk has discussed parsing this directly using StreamDevice, but there
is another option which might be easier: Parse all of the elements into
a single waveform record, then use an aSub record to split that waveform
into two separate arrays. The aSub is a version of the subroutine record
type that has multiple input and output fields and links for which you
provide your own C function to perform any data processing that you need
to do.

You can pull in the array from the streamDevice waveform record with one
input link, split up the data inside your code and place it into a
couple of the output fields configured as double arrays. You could even
take the input as a string (char array) instead of having StreamDevice
parse it into doubles for you if performance is important.

This approach can also be used for your inverse requirement, merging
multiple input arrays into one output array, and in this case it might
be easier to generate a string (char array) directly.

HTH,

- Andrew

--
Arguing for surveillance because you have nothing to hide is no
different than making the claim, "I don't care about freedom of
speech because I have nothing to say." -- Edward Snowdon


Replies:
Re: Stream device - parsing array of pairs of floats Johnson, Andrew N. via Tech-talk
References:
Stream device - parsing array of pairs of floats Joao Afonso via Tech-talk
Re: Stream device - parsing array of pairs of floats Johnson, Andrew N. via Tech-talk

Navigate by Date:
Prev: Two EVR in one VME Di Wang via Tech-talk
Next: Re: Problems with StreamDevice Dirk Zimoch via Tech-talk
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  <20192020  2021  2022  2023  2024 
Navigate by Thread:
Prev: Re: Stream device - parsing array of pairs of floats Johnson, Andrew N. via Tech-talk
Next: Re: Stream device - parsing array of pairs of floats Johnson, Andrew N. via Tech-talk
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  <20192020  2021  2022  2023  2024 
ANJ, 19 Feb 2019 Valid HTML 4.01! · Home · News · About · Base · Modules · Extensions · Distributions · Download ·
· Search · EPICS V4 · IRMIS · Talk · Bugs · Documents · Links · Licensing ·