Dear colleagues,
I am struggling with a problem related to a
waveform StreamDevice record.
Specifically, the device I want to interface
with (Lecroy T3AFG200) has a remote interface
based on a text protocol. When I send the
string "C1:WaveBurst?", it replies with a
string such as:
C1:BTWV
STATE,ON,PRD,0.01S,STPS,0,TRSR,INT,TRMD,OFF,TIME,1,DLAY,1.38052e-06S
where the value of multiple parameters is
reported. I want to read these values - in the
above example, e.g., PRD is "0.01S", TRMD is
"OFF", DLAY is "1.38052e-06S".
What makes this task not trivial is that the
number of reported parameters, and their
order, depends on the status of the device.
Thus, the output string is not always the
same.
I tried to work as follows.
- I read the data in a waveform record,
where each element is a string, splitting
the string by comma (and ignoring the
initial C1:BTWV part)
- I process this data through an aSub
record. The associated sub-routine takes as
input the waveform record (INAA), and as
also another string record reporting the
field to be extracted (INBB). The two
outputs are a double value and a string
value containing, respectively, the double
representation (OUTA) and the string
representation (OUTB) of the element
following INBB, if any.
- For example, if the waveform record is
the one above, and the string identifier
record is "TRSR", the routine will return
"INT" in the string representation. If the
string identifier record is "DLAY", the
routine will return "1.38052e-06" in the
double representation (I trim out the last
"S" character)
I developed the following database records.
To read the data from the instrument and
parse it, I have four records. The order
of processing is dictated by the fact that,
for a StreamDevice record, I cannot use it
trivially as an input link with "Process
Passive", since this will result in the OLD
value to be reported before the protocol is
executed, so I must go "the other way around".
record(waveform, "$(P):C1:Burst")
{
field(DTYP, "stream")
field(FLNK, "$(P):C1:BurstCalc")
field(FTVL, "STRING")
field(INP, "@LecroyT3AFG.proto
ChannelBurst($(P),1) T3AFG")
field(NELM, "100")
field(SCAN, "Passive")
}
record(stringin, "$(P):C1:BurstWord")
{
field(FLNK, "$(P):C1:Burst")
field(SCAN, "Passive")
}
record(aSub, "$(P):C1:BurstCalc")
{
field(FTA, "STRING")
field(FTB, "STRING")
field(FTVA, "DOUBLE")
field(FTVB, "STRING")
field(INPA, "$(P):C1:Burst")
field(INPB, "$(P):C1:BurstWord")
field(LFLG, "IGNORE")
field(NOA, "100")
field(OUTA, "$(P):C1:BurstCalcDouble")
field(OUTB, "$(P):C1:BurstCalcString")
field(SNAM, "LecroyT3AFG_asub")
}
record(ai, "$(P):C1:BurstCalcDouble")
{
}
record(stringin, "$(P):C1:BurstCalcString")
{
field(VAL, "INITIAL_VALUE")
}
To read the status, I have two specific
records
record(scalcout, "$(P):C1:BurstStatus")
{
field(CALC, "BB")
field(INAA, "$(P):C1:BurstStatusS PP")
field(INBB, "$(P):C1:BurstCalcString")
field(SCAN, "Passive")
}
record(stringout, "$(P):C1:BurstStatusS")
{
field(FLNK, "$(P):C1:BurstWord")
field(OMSL, "closed_loop")
field(OUT, "$(P):C1:BurstWord")
field(VAL, "STATE")
}
My idea was the following: when I process
"$(P):C1:BurstStatus", the following sequence
should take place:
- INAA is processed: $(P):C1:BurstStatusS
-> $(P):C1:BurstWord -> $(P):C1:Burst
->$(P):C1:BurstCalc. The two records
"$(P):C1:BurstCalcDouble" and
"$(P):C1:BurstString" are populated.
- INBB is processed $(P):C1:BurstCalcString
I thus assumed that the full chain triggered
by INAA was processed before the INBB record
was read.
However, this is not the case. After
triggering the process of $(P):C1:BurstStatus,
I have $(P):C1:BurstStatus.SVAL equal to
"INITIAL_VALUE", as if INBB is processed
before (or during) INAA processing, and the
order is not respected. But the value of
$(P):C1:BurstCalcString is the correct one..
I am currently using epics version 7.0
Thanks,
Bests,
Andrea Celentano