|
|
Experimental Physics and
| ||||||||||||||
|
|
Hi folks,
For certain experiments on our beamline we like to continuously oscillate the sample in the beam to spread out the x-ray dose and reduce radiation damage (we call this process “toasting”). For the past many years we’ve done this using control code specific
to a (Parker) motor controller dedicated to these experiments. This controller is reaching end of life, and I’m hoping to get a more general solution to this that only depends on logic in an IOC, so that whenever we have to update controllers in the future
we don’t have to rewrite this oscillation code.
I took a quick look through the archives of this list and some of the SynApps modules and didn’t see anything that would already do this for me, so I set out to make my own. My first attempt is to just use a combination of a calcout record and a seq record.
The seq record uses a selection mask to either send the positive or negative endpoint to the motor record to start a move. The calcout record checks whether the motor is at the positive or negative endpoint and then sets the mask value for the seq and tells
the seq to process. Then I set the motor FLNK to point to the calcout record PROC.
The problem that I’m running into is that the calcout seems to sometimes process a bit before the move is finished, or at least before the motor RBV has updated to the final position. You can start this process and it will run for a bit (5-10 cycles), and then
it will stop. When it stops, if you check the calcout .A record, which gets its value from the motor RBV, it will say something like -4.9784, while the motor RBV at the end of the move is something like -5.00380 for a move to -5 (note: I haven’t yet thought
about how to deal with deadband or step resolution in terms of determining which end the motor is at).
I’m wondering if there’s either another way to tell the calcout to process or if there’s a better way to do this that will create the desired effect. I should note that I don’t want to introduce any hardcoded delays anywhere because the point of this is a smooth
turnaround so that the beam doesn’t linger and preferentially damage spots of the sample at the end of the scans (also, unreliable).
Here are my test seq and calcout records (with fixed values for positions for this test, but in the future could point to aouts that the user sets for each limit, for example):
record(seq, "$(P)Toast:$(D)Move") {
field(DESC, "Toast motor")
field(SCAN, "Passive")
field(DOL0, "5")
field(LNK0, "$(MOTOR).VAL PP")
field(DOL1, "-5")
field(LNK1, "$(MOTOR).VAL PP")
field(SELM, "2")
field(SHFT, "0")
#field(SELN, "1")
field(SELL, "$(P)Toast:$(D)Check.OVAL")
}
record(calcout, "$(P)Toast:$(D)Check") {
field(DESC, "Check if toast motor moves")
field(INPA, "$(MOTOR).RBV")
#field(INPA, "0")
field(INPB, "5")
field(INPC, "-5")
field(CALC, "((A >= B) || (A <= C)) ? 1: 0")
field("OOPT", 3)
field("DOPT", 1)
field("OCAL", "(A >= B) ? 2 : 1")
field("OUT", "$(P)Toast:$(D)Move PP")
}
If this issue is just a fundamental limitation of the motor record processing I was thinking the next thing to do would be to write a sequence record, but I haven’t messed with SNL before and it seemed a lot easier to try these standard EPICS records first.
Any advice would be appreciated.
All the best.
---- Sector 18, Advanced Photon Source Research Associate Professor, Illinois Tech
| ||||||||||||||
| ANJ, 19 Mar 2026 |
·
Home
·
News
·
About
·
Talk
·
Base
·
Modules
·
Extensions
·
· Distributions · Download · Documents · Links · Licensing · |