Ok dann halt via Code:
Aber erstmal nur der Actuatorteil ohne das drumherum
FUNCTION_BLOCK ACTUATOR_3PN
VAR_INPUT
EN : BOOL; (* enable actuator *)
IN : BYTE; (* Signal Byte *)
END_CLOSE : BOOL; (* Terminating Close *)
END_OPEN : BOOL; (* Terminating Open *)
END_VAR
VAR_OUTPUT
OPEN : BOOL; (* Signal for open-Valve *)
CLOSE : BOOL; (* Signal for Closing-Valve *)
POS : BYTE; (* Virtual Position *)
STATUS : BYTE; (* STEPS: 100 is good *)
END_VAR
VAR
ramp : _RMP_NEXT; (* lookup for direction *)
Counter : CTU; (* Counter for Movements *)
moves : INT; (* var for Counts *)
next_zero : INT := 250; (* max of Movements *)
tonValve : TON ; (* Timer Valve *)
tonRelay : TON; (* Timer RelayPausing *)
tonCalib : TON; (* Timer Calibration *)
ERROR : BYTE; (* 0 = OK, 10 = NoClose, 20 = NoOpen, 30=NoBoth *)
END_VAR
VAR CONSTANT
T_RUN : TIME := t#70s; (* maximimum runtime of Valve, longer then time for endswitch *)
T_CAL : TIME := t#24h; (* permanently make Calibration *)
t_LockOut : TIME := t#20s; (* Lock for changing Direction too fast *)
T_RELAY : TIME := t#1500ms; (* Locktime for smooth change of relay-Direction *)
END_VAR
(* Original:
version 2.0 28. jan 2010
programmer hugo
tested by oscat
actuator_3P is an interface for a 3 point actuator.
a 3P actuator is a motor with 2 directions that drives a valve or flap.
the position of the valve or flap is controlled by runtime of the motor foreward or backward.
the available inputs are:
IN specifies the position of the actuator, 0 = 0% and 255 = 100%.
30.07.2015 Shrimps:
Special Version for heating-Mixers with 2 external Position-Switches
renew most steps
Implemented security: When disable, run close first !
If no switch, all will be based on Timers like the original code
03.12.2015 Shrimps:
All Time() Funktions replaced with TON in behavior of Time() Overflow-Problems
*)
(* @END_DECLARATION := '0' *)
(* Starting all Timer *)
tonValve(PT := T_RUN);
tonRelay(PT := T_RELAY);
tonCalib(PT := T_CAL);
(* all steps will be done with these sequence *)
CASE status OF
0: (* Init, will start at Runup or called by Calibration *)
OPEN := FALSE; (* Power off *)
CLOSE := FALSE; (* Power off *)
ramp.TR := T_RUN; (* Fill ramp with default time rising *)
ramp.TF := T_RUN; (* Fill ramp with default time falling *)
(* Counter.RESET := TRUE; (* Reset Moves *) *)
error := 0;
status := 5; (* do next step *)
5: (* Wait some time, better for Relay, perhaps comming from other direction *)
tonRelay.IN := TRUE; (* Starting Wait *)
IF tonRelay.Q THEN
tonRelay.IN := FALSE; (* Reset Timer *)
status := 10; (* do next step *)
END_IF
10: (* Closing the valve until Timeout or Position reached *)
CLOSE := TRUE; (* give valve power *)
tonValve.IN := TRUE; (* Starting Timer *)
IF tonValve.Q OR END_CLOSE THEN (* Timeout or final Switch reached ? *)
tonValve.IN := FALSE; (* Reset Timer *)
CLOSE := FALSE; (* Stop down *)
error := error + (10 * BOOL_TO_BYTE(NOT END_CLOSE));
status := 20; (* do the next step *)
END_IF
20: (* Wait some seconds to avoid damage of Motor or Relays *)
tonRelay.IN := TRUE; (* Starting Wait *)
IF tonRelay.Q THEN
tonRelay.IN := FALSE; (* Reset Timer *)
status := 30; (* do next step *)
END_IF
30: (* opening Valve *)
OPEN := TRUE;
tonValve.IN := TRUE; (* Starting Timer *)
IF tonValve.Q OR END_OPEN THEN (* Timeout or Position reached ? *)
OPEN := FALSE; (* Off all Power *)
ramp.TR := tonValve.ET; (* Uptime *)
tonValve.IN := FALSE; (* Reset Timer *)
ramp.IN := 255; (* set ramp pos to max value, we reached Openposition *)
error := error + (20 * BOOL_TO_BYTE(NOT END_OPEN));
STATUS := 40; (* do the next step *)
END_IF
40: (* pause for some s its better for the relays instead to change direction immediately *)
tonRelay.IN := TRUE; (* Starting Wait *)
IF tonRelay.Q THEN
tonRelay.IN := FALSE; (* Reset Timer *)
status := 50; (* do next step *)
END_IF
50: (* now closing the valve *)
CLOSE := TRUE; (* Close valve *)
tonValve.IN := TRUE; (* Starting Timer *)
IF tonValve.Q OR END_CLOSE THEN (* Timeout or Position reached ? *)
CLOSE := FALSE; (* Stop power *)
ramp.TF := tonValve.ET; (* TF to be filled! *)
tonValve.IN := FALSE; (* Reset Timer *)
ramp.IN := 0; (* Ramp position set to zero *)
pos := 0;
STATUS := 60; (* do next step *)
END_IF
60: (* pause for some s its better for the relays instead to change direction immediately *)
tonRelay.IN := TRUE; (* Starting Wait *)
IF tonRelay.Q THEN
tonRelay.IN := FALSE; (* Reset Timer *)
status := 100; (* do next step *)
END_IF
100: (* normal operation *)
Counter.RESET := FALSE; (* Activate Counter: Moves *)
tonCalib.IN := TRUE; (* Activate Calibration lookup *)
IF Counter.Q THEN (* Moves reached *)
status := 0; (* Reset *)
END_IF
(* check for auto calibration *)
(* no lookup for then nearest Position, because opening could make damage by heatings *)
IF tonCalib.Q THEN
tonCalib.IN := FALSE; (* Reset Timer *)
status := 0; (* full restart *)
END_IF
IF NOT EN THEN
IN := 0;
END_IF
(* do the full job now: *)
(* set ramp generator to IN *)
ramp.IN := IN;
(* Postitioning the valve *)
OPEN := ramp.UP ;
CLOSE := ramp.DN ;
(* Adjusting *)
IF IN = 0 THEN (* Closing until Switch reached *)
CLOSE := NOT END_CLOSE;
END_IF
(* tonValve.IN := OPEN OR CLOSE; (* Check Timing *) *)
END_CASE;
(* Count all Movements *)
(* Reset at close-signal or init *)
Counter(CU:= OPEN OR CLOSE, RESET := END_CLOSE OR (status = 0), PV:= next_zero, CV=> moves);
(* internal flap simulation and output activation *)
ramp(OUT := POS, TL := t_LockOut);
(* adjust position if end switch is active *)
IF END_OPEN THEN
pos := 255;
ramp.IN := 255;
END_IF
IF END_CLOSE THEN
pos := 0;
ramp.IN := 0;
(* Counter.RESET := TRUE; (* Reset Moves *) *)
END_IF
END_FUNCTION_BLOCK