• Not Answered

How to put PID into RCAS at a given output?

In several places in our process, we have a flow control module connected to a flowmeter and valve. When starting flow, often we want to "jump" to a specific valve position then begin automatic control from there. This worked well on our previous control system. We recently upgraded to DeltaV, where the same technique doesn't seem to work.

In DeltaV, there is an AI block (the flowmeter) as input to a PID, whose output goes to an AO block (the valve). The AO block's BKCAL_OUT is then fed back to the PID block's BKCAL_IN.

In our previous control system, we would do its equivalent of this:

'//#WFI_FLOW_CTL#/PID1/MODE.TARGET' := ROUT;
'//#WFI_FLOW_CTL#/PID1/ROUT_IN.CV' := 50;

'//#WFI_FLOW_CTL#/PID1/MODE.TARGET' := RCAS;
'//#WFI_FLOW_CTL#/PID1/RCAS_IN.CV' := 120 ;

In that system, it would open the valve to 50% (causing an immediate and considerable flow), then begin automatic controlling with a setpoint of 120. In DeltaV, even with the first two statements in one action and the second two in another (delaying off of the previous statement's completion, whose confirm is OUT.CV = 50), the actual valve doesn't open to 50%. It acts almost like the first two statements don't exist; the valve starts fully closed (the condition before any of these statements) , then slowly opens until the setpoint is reached. This causes the flow to begin at zero, then slowly ramp to the desired flowrate, rather than starting near the setpoint and tweaking from there.

How do we put a PID into RCAS, but have it start at a given output and adjust the output from there?

7 Replies

  • Your code above should work. Does MODE.ACTUAL make it to ROUT or does it get stuck in another mode such as IMAN? You could also try TRK_IN_D and TRK_VAL to force the output to 50.
  • This is fairly standard practice within emerson as well to construct code like this. There are a few minor differences that we usually do, but I don't think they necessarily are an issue with what your are seeing.

    First, I would suggest confirming mode.target and rout_in.awst in the confirm for your first action. As a general practice, confirming OUT.CV = 50 in a sequence is not the best idea. If the device becomes interlocked and/or you need to change the value later, it's better to confirm on .AWST instead of what the value is. Also, confirming mode.target will ensure that parameter write has also occured.

    You mention you are delaying the next action on the previous action. Are you delaying off the previous action status = complete or some other method to determine it's complete? Like I mentioned, fairly standard practice for us as well.

    If you want to post a couple of screenshots of two actions, I can take a look and see if anything sticks out.
  • In reply to Matt Forbis:

    One other thing to Matt's comments is that with writing the SP and MODE in the same action, the PID block won't see the SP change in that mode (unless potentially cross controller write and they are split and written at different times and block runs in between...probably rare case but possible) and execute the Gain calc to bump the output which is probably what you want here but if not then you can split up the mode and SP writes and then see the bump in output because of SP change would be done in that RCAS mode.

    You can confirm MODE.ACTUAL like also suggested but you should either have some other method of confirmation in case of IMAN/LO modes in the confirm expression or the confirm timeout expression/time. We typically use the confirm expression and save the current step time to a param and then check if the step time is > save time + value/parameter where the value/parameter is a value you're comfortable using as a timeout (we use parameter for these and rarely hard code values so they can be tuned without requiring a download). So Example would be:
    (('//#WFI_FLOW_CTL#/PID1/MODE.ACTUAL' = ROUT) AND
    ('//#WFI_FLOW_CTL#/PID1/ROUT_IN.AWST' = 0)) OR
    ('STEP_NAME/TIME.CV' >= ('^/TIME_SAVE.CV' + '^/CFM_TIMEOUT.CV'))
  • Assuming that actions are implemented in an SFC Step, I would recommend using 4 actions to do this.
    Setting mode and RCAS_IN/ROUT_IN value in the same action may fail due to the internal logic of PID and AO blocks.

    A1:
    Delay Expression => 0 (or whatever condition is needed in a larger context)
    Action Expression => '//#WFI_FLOW_CTL#/PID1/MODE.TARGET' := ROUT;
    Confirm Expression => '//#WFI_FLOW_CTL#/PID1/MODE.ACTUAL' := ROUT;
    A2:
    Delay Expression => A1 completed
    Action Expression => '//#WFI_FLOW_CTL#/PID1/ROUT_IN.CV' := 50;
    Confirm Expression => '//#WFI_FLOW_CTL#/PID1/ROUT_IN.AWST' := 0; (this is the confirmation of 50 value written in the ROUT_IN parameter. Using OUT = 50 may fail due to connected AO block current state. For example OUT_LO_LIM = 55 will clamp OUT to 55)

    A3:
    Delay Expression => A2 completed
    Action Expression => '//#WFI_FLOW_CTL#/PID1/MODE.TARGET' := RCAS;
    Confirm Expression => '//#WFI_FLOW_CTL#/PID1/MODE.ACTUAL' := RCAS;

    A4:
    Delay Expression => A3 completed
    Action Expression => '//#WFI_FLOW_CTL#/PID1/RCAS_IN.CV' := 120;
    Confirm Expression => '//#WFI_FLOW_CTL#/PID1/RCAS_IN.AWST' := 0; (this is the confirmation of 120 value written in the RCAS_IN parameter. Using SP = 120 may fail due to connected AO block current state. For example SP_LO_LIM = 105 will clamp SP to 105)

    NOTE: Even if RCAS_IN value is far from current PV after A4 is completed, the OUT value will change in an smooth way and a "Kick" in the OUT value will not happen. If that "kick" is desired, for faster response, then RCAS_IN must be set to current PV before action A4 is executed.
  • In reply to gamella:

    Here's a screenshot of the actual actions for one area of our process. (It's slightly different, particularly the confirms, but is essentially the same method.)

    Screenshots of actions

    (Notes: R_WFI_OPEN = 20, P_WFI_RATE = 70, MODE = PID1/MODE, ROUT = PID1/ROUT_IN, RSP = PID1/RCAS_IN)

    So A4 sets the module to ROUT with an output of 20, and confirms that the target mode is ROUT and the target output . A5 waits for A4 to complete, then sets the module to RCAS with a setpoint of 70 (P_WFI_RATE = 70). That SHOULD have had the output start at 20%, then had the PID start controlling. But what really happened was that the PID1/OUT started at zero and slowly ramped up until the flow setpoint was reached. I've watched it happen twice in real time; the output really does start at zero and control up from there. Both the unit (that the phase is running on) and the module are on the same controller.

    If Matt Stoner is correct, it's possible that the ROUT_IN isn't getting fully set due to being in the same action as the MODE change to ROUT; if so, gamella's solution of splitting them into 4 actions would seem to work. Could we do the ROUT_IN first, then MODE:=ROUT and RCAS_IN in an action, then MODE:=RCAS? Or does it really need to be 4 separate actions?

  • In reply to Andy Hairston:

    Why not just use an AT block connected to the PID? Keep the PID target mode wherever you like.
  • In reply to Mark Bendele:

    The AT connects to the PID Track inputs and would typically be used for interlocking the PID output, which sets the PID in LO. Managing the PID in normal control scenarios with CAS, RCAS and ROUT allows the logic to be developed without compromising the Interlock logic, that is, whatever you end up doing in this control application, the interlock stays ready to act as designed. It can get complicated trying to do both interlock logic on the output and manage control variations all in the AT block. It's possible, but it can lead to an overly complicated interlock solution rather than keep these things separate.

    The example above seems to be using module level parameters for the ROUT and RCAS values, which may be wired or internally referenced to the PID block parameters. That can change how the values are processed. The point Matt makes is writing to MODE.TARGET requires the block to execute before MODE.ACTUAL is attained. The write to the ROUT_IN or RCAS_IN needs to follow the MODE.TARGET attaining the desired mode. separating the mode manipulation from the parameter setting allows the block to accept the value as it has actually changed to the correct mode. If the target parameter is wired into the Block, the value will be sitting in the parameter waiting for the Mode.ACTUAL to change, and the value is then read. subtle timing issue that is avoided by sequencing the Mode change and then the parameter write once the mode is attained.

    DeltaV PID execution is designed to avoid SP induced bumps. Some blocks have balance times that kick in to also avoid abrupt changes. Normal cascade loops track the CAS IN value for bumpless transfer to CAS mode and once in CAS, the source PID block is released to now drive the SP of the second loop. A similar approach would be prudent moving to RCAS or ROUT that ensures the mode change is bumpless, and once enabled the RCAS or ROUT controls start to move the value as needed. SP rate or OUTPUT Rate limits may be in place to prevent sudden bumps on the working SP or OUT value. These will prevent a straight bump change if enabled.

    I totally agree with Matt that your MODE changes should be confirmed before you do your control parameter write. This way it matters not if the module has a wired parameter or internal reference or if you write directly to the block parameter. Always confirm the mode Actual is correct before writing. This can all be done in one Step.

    Andre Dicaire