Hallo,
ich verwende den Actuator_3P nach einem PID-Regler zur Ansteuerung meines Heizkreismischers. Dieser hat keinen Endschalter. Selbst bei einer cal_runtime von 2 Minuten hat er sich schon mehrmals festgefahren (pos 0 der 1 erreicht, obwohl physikalische Endlage noch nicht erreicht war). Die cal_time noch weiter runterzusetzen widerstrebt mir doch. Dann wird ja ständig die ach so schöne Regelung durcheinandergewürfelt.
Ich habe jetzt den Baustein um eine 'Auto_Cal'-Funktion erweitert. Diese beruht unter Umgehung der bereits eingebauten Cal und Diag_funktion darauf, daß bei einem In-Wert von 0 oder 1 grundsätzlich der jeweilige Ausgang mit max_runtime angesteuert wird. Dieser Vorgang wird aber durch einen erneuten In-Wert 0>in<1 wieder unterbrochen.
Für Anwendungen, bei denen es auf die absolute Stellung ankommt, ist das sicher nicht geeignet, aber bei einem vorgeschalteten stetigen Regler halte ich das für sinnvoll.
Bei Interesse, kann ich die Änderung hier reinstellen.
Gruß
Andreas
Hallo Andy,
wegen der problematik mit den dreipunktsignalen (nicht nur oscat) habe ich kpl. auf 0-10V umgestellt. Preislich kaum unterschied zu dreipunkt.
mfg
Hallo,
kannst Du mir Deine Änderung zur Verfügung stellen?
MfG
Controllfreak
Hallo Controlfreak,
da begrenztes Interesse hier, will ich das Forum nicht vollmüllen. Änderung ist zu Dir unterwegs.
Gruß
Andreas
Moin!
Genau so ein Problem habe ich auch gerade. Besteht die Möglichkeit, die geänderte Funktion per eMail zu bekommen oder sie in die nächste Bibliothek einzubauen?
Danke!
viele sonnige Grüße
Arnt
ist unterwegs.
Gruß
Andreas
Ich hatte selbige Probleme und den Baustein inzwischen neu geschrieben. Damit habe ich beste Erfahrungen gemacht und verwende ihn inzwischen ständig auch für sehr kritische Anwendungen, außerdem wollte ich, daß die Synchronisation nur in eine Richtung erfolgt:
Trotzdem muß ich zugeben, daß der Baustein sicher nicht optimal geschrieben wurde (habe ich irgendwo mal auf der Baustelle schnell runtergetippt)
Wenns jemand haben will kann er's verwenden
FUNCTION_BLOCK ACTUATOR_3P_new
VAR_INPUT
In_r:REAL; (* Input in 0 - 100% *)
max_runtime_t:TIME; (* Stellzeit in t#..s *)
Sync_x:BOOL; (* Synchronisation *)
Sync_dir_x:BOOL; (* Sync 0 = Sync auf "0", Sync 1 = Sync auf "100" *)
time_min_off_t:TIME; (* Mindest-Ausschaltzeit Antrieb *)
time_min_on_t:TIME; (* Mindest-Laufzeit Antrieb *)
END_VAR
VAR_OUTPUT
Mode_i: INT; (*0=fully opened 1= open 2=stop 3=close 4=fully closed*)
Y_3p_b:BYTE; (*0=close, 1=stop, 2=open*)
Y_open_x: BOOL;
Y_close_x: BOOL;
Pos_r:REAL;
END_VAR
VAR
Nz: REAL; (* neutral zone *)
Pos_open: REAL;
Pos_close: REAL;
InSy_r: REAL; (* Input in 0 - 100% included Synchronisation*)
acttime_new: DWORD; (* actual time *)
acttime_close: DWORD:=0;
acttime_stop: DWORD:=0;
acttime_open: DWORD:=0;
Stop_close: BOOL;
Stop_open: BOOL;
diffacttime_time_close: DWORD;
diffacttime_time_stop: DWORD;
diffacttime_time_open: DWORD;
Stop_close_del1cyc: BOOL;
Stop_open_del1cyc: BOOL;
max_runtime_r: REAL;
Pos_old_r: REAL;
SYNC_Imp:BOOL;
END_VAR
Nz:=100*TIME_TO_REAL(time_min_on_t)/TIME_TO_REAL(max_runtime_t)-0.001;
max_runtime_r:=TIME_TO_REAL(max_runtime_t);
IF Sync_x=TRUE
THEN
IF SYNC_Imp=TRUE
THEN
acttime_stop:=acttime_new;
SYNC_IMP:=FALSE;
END_IF;
IF Sync_dir_x=FALSE
THEN
InSy_r:=0; (* synchronisation CLOSE *)
ELSE
InSy_r:=100; (* synchronisation OPEN *)
END_IF;
ELSE
SYNC_Imp:=TRUE;
InSy_r:=In_r; (* no synchronisation *)
END_IF
IF InSy_r>0
THEN
Pos_close:=Pos_r-Nz;
ELSE
Pos_close:=Pos_r;
END_IF
IF InSy_r<100
THEN
Pos_open:=Pos_r+Nz;
ELSE
Pos_open:=Pos_r;
END_IF
acttime_new:=TIME_TO_DWORD(TIME());
diffacttime_time_stop:=acttime_new-acttime_stop;
IF diffacttime_time_stop>TIME_TO_DWORD(time_min_off_t)
THEN
IF Pos_r<=0
THEN
IF InSy_r=0
THEN
Mode_i:=0;
Stop_close:=FALSE;
ELSE
Stop_close:=TRUE;
END_IF;
ELSE
IF InSy_r<Pos_close AND Stop_open_del1cyc=TRUE
THEN
IF Mode_i<>1
THEN
acttime_close:=acttime_new;
END_IF;
Mode_i:=1;
Stop_close:=FALSE;
ELSE
IF diffacttime_time_Close>TIME_TO_DWORD(time_min_on_t)
THEN
Stop_close:=TRUE;
END_IF
END_IF;
END_IF;
Stop_open_del1cyc:=Stop_open;
IF Pos_r>=100
THEN
IF InSy_r=100
THEN
Mode_i:=4;
Stop_open:=FALSE;
ELSE
Stop_open:=TRUE;
END_IF;
ELSE
IF InSy_r>Pos_open AND Stop_close_del1cyc=TRUE
THEN
IF Mode_i<>3
THEN
acttime_open:=acttime_new;
END_IF;
Mode_i:=3;
Stop_open:=FALSE;
ELSE
IF diffacttime_time_open>TIME_TO_DWORD(time_min_on_t)
THEN
Stop_open:=TRUE;
END_IF
END_IF;
END_IF;
Stop_close_del1cyc:=Stop_close;
IF Stop_close=TRUE AND Stop_open=TRUE
THEN
IF Mode_i<>2
THEN
acttime_stop:=acttime_new;
END_IF;
Mode_i:=2;
END_IF;
END_IF
diffacttime_time_close:=acttime_new-acttime_close;
diffacttime_time_open:=acttime_new-acttime_open;
(*0=fully closed 1=close 2=stop 3= open 4=fully opened*)
CASE Mode_i
OF
0:
Y_close_x:=TRUE;
Y_open_x:=FALSE;
Y_3p_b:=0;
Pos_r:=0;
Pos_old_r:=Pos_r;
1:
Y_close_x:=TRUE;
Y_open_x:=FALSE;
Y_3p_b:=0;
Pos_r:=Pos_old_r-100*DWORD_TO_REAL(diffacttime_time_close)/max_runtime_r;
2:
Y_close_x:=FALSE;
Y_open_x:=FALSE;
Y_3p_b:=1;
Pos_old_r:=Pos_r;
3:
Y_close_x:=FALSE;
Y_open_x:=TRUE;
Y_3p_b:=2;
Pos_r:=Pos_old_r+100*DWORD_TO_REAL(diffacttime_time_open)/max_runtime_r;
4:
Y_close_x:=FALSE;
Y_open_x:=TRUE;
Y_3p_b:=2;
Pos_r:=100;
Pos_old_r:=Pos_r;
END_CASE