Nochmal Actuator_3P

Begonnen von Andy, 01. September 2008, 14:08:01

Vorheriges Thema - Nächstes Thema

0 Mitglieder und 2 Gäste betrachten dieses Thema.

Andy

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

swmggs

Hallo Andy,

wegen der problematik mit den dreipunktsignalen (nicht nur oscat) habe ich kpl. auf 0-10V umgestellt. Preislich kaum unterschied zu dreipunkt.

mfg

Dorfmeister

Hallo,
kannst Du mir Deine Änderung zur Verfügung stellen?
MfG
Controllfreak

Andy

Hallo Controlfreak,

da begrenztes Interesse hier, will ich das Forum nicht vollmüllen. Änderung ist zu Dir unterwegs.

Gruß
Andreas

solare-Ideen

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

Andy

ist unterwegs.

Gruß
Andreas

mg

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