I would like to ask if there is an equivalent to LCRContinServo() that works with different minimal impulse lengths in the UP and DOWN directions?
Some of the actuators open for 40 seconds and close for 10 seconds because they have a safety feature (spring). When opening - the actuator overcomes the force of the spring, when closing - it doesn’t have to.
Unfortunately LCRContinServo() expects a constant speed in both directions, which is determined by the common input “t_impulse”.
I can use two such blocks, one for the UP direction and another for the DOWN direction, but I’d rather find some clean solution to this situation.
I do not have solution you are looking for. But Im testing now new model and AI algorithm for our conversational help. … just sharing result as an example. Feel free to comment it.
To address your requirement for different minimal impulse lengths in the UP and DOWN directions, you can use a custom solution that leverages the existing LCRContinServo() function block but with some additional logic to handle the different impulse times. Here’s a detailed approach:
Custom Solution Using LCRContinServo()
Define Two Separate Function Blocks:
Create two instances of LCRContinServo(), one for the UP direction and one for the DOWN direction.
Each instance will have its own t_impulse value to handle the different impulse times.
Control Logic:
Use a control logic to switch between the two function blocks based on the direction of movement.
This can be achieved using a state machine or conditional statements in your program.
Example Implementation in Structured Text (ST)
VAR
gateLCRContinServoUp: LCRContinServo_typ;
gateLCRContinServoDown: LCRContinServo_typ;
analogValue: REAL;
openGate, closeGate, reference: BOOL;
direction: BOOL; // TRUE for UP, FALSE for DOWN
END_VAR
// Initialization
INITIALIZATION
reference := FALSE;
gateLCRContinServoUp.enable := TRUE;
gateLCRContinServoUp.max_value := 100.0;
gateLCRContinServoUp.min_value := 0.0;
gateLCRContinServoUp.t_impulse := 0.5; // Adjust as needed
gateLCRContinServoUp.t_change_up := 40.0; // Time for opening
gateLCRContinServoUp.t_change_down := 0.0; // Not used for UP
gateLCRContinServoUp.ref := reference;
gateLCRContinServoDown.enable := TRUE;
gateLCRContinServoDown.max_value := 100.0;
gateLCRContinServoDown.min_value := 0.0;
gateLCRContinServoDown.t_impulse := 0.5; // Adjust as needed
gateLCRContinServoDown.t_change_up := 0.0; // Not used for DOWN
gateLCRContinServoDown.t_change_down := 10.0; // Time for closing
gateLCRContinServoDown.ref := reference;
END_INIT
// Cyclic Function
CYCLIC
IF direction THEN
// UP direction
gateLCRContinServoUp.x := analogValue;
gateLCRContinServoUp.ref := reference;
LCRContinServo(gateLCRContinServoUp);
openGate := gateLCRContinServoUp.up;
closeGate := gateLCRContinServoUp.down;
ELSE
// DOWN direction
gateLCRContinServoDown.x := analogValue;
gateLCRContinServoDown.ref := reference;
LCRContinServo(gateLCRContinServoDown);
openGate := gateLCRContinServoDown.up;
closeGate := gateLCRContinServoDown.down;
END_IF
END_CYCLIC
Explanation
Initialization:
Two instances of LCRContinServo() are created: gateLCRContinServoUp for the UP direction and gateLCRContinServoDown for the DOWN direction.
The t_change_up and t_change_down parameters are set to the appropriate values for each direction.
The t_impulse parameter is set to a common value, but you can adjust it as needed.
Cyclic Function:
The direction of movement is determined by the direction variable.
Depending on the direction, the appropriate LCRContinServo() instance is used to control the actuator.
The openGate and closeGate outputs are updated based on the selected instance.
This seems to be the solution to my problem. I will try to implement it.
In the meantime, I have revived the FUB SGSCHR from the B&R PG2000 environment. I was able to modify it over 20 years ago because the FUB source code was accessible. I was using it for servo drives on heat exchanger stations. Who would have expected back then that it would come in handy?
Thanks for the perfect support