Beiträge anzeigen

Diese Sektion erlaubt es ihnen alle Beiträge dieses Mitglieds zu sehen. Beachten sie, dass sie nur solche Beiträge sehen können, zu denen sie auch Zugriffsrechte haben.


Themen - hugo

Seiten: 1 ... 7 8 [9]
121
Bestehende Module / Existing Modules / PID controller erweitert
« am: 04. Januar 2007, 12:21:11 »
der pid regler hat nun eine strukturumschaltung erhalten. der anwender kann nun festlegen wann der integrator aktiv wird.
PID regler sind grundsätzlich schlecht geeignet wenn der sollwert sprunghaft verstellt wird, der uintegrator läuft dabei von anfang an und kann schnell an die oberen oder unteren limits gelangen, was längere ausregelzeiten und über bzw unterschwingen bedeutet.

mit einem zusätzlichen eingang int_band kann nun festgelegt werden das der integrator nur nahe dem sollwert funktioniert und bei großen regelabweichungen abgeschaltet wird.

FUNCTION_BLOCK FT_PID
VAR_INPUT
   actual, set_point, offset, manual_in : REAL;
   Manual : BOOL;
   rst : BOOL := FALSE;
   int_band : REAL := 100;
END_VAR
VAR_INPUT
   KP, TN, TV, limit_L, limit_H : REAL;
END_VAR
VAR_OUTPUT
   Y : REAL;
   LIM, overflow : BOOL;
END_VAR
VAR
   integ : FT_INT;
   deriv : FT_deriv;
   diff: REAL;
END_VAR

(*
version 1.2   3 jan 2007
programmer    hugo
tested by      tobias

FT_PID is a pid controller with manual functionality.
The PID controller works according to the fomula Y = KP * ( e + 1/TN * INTEG(e) + TV *DERIV(e)) + offset, while e = set_point - actual.
a rst will reset all internal data, while a switch to manual will cause the controller to follow the function Y = manual_in + offset.
limit_h and Limit_l set the possible output range of Y.
the output flags lim will signal that the output limits are active and overflow will signal that the integrator has reached the max or min limit. 

since rev 1.1 the "trapezregel is used for more accuracy.
rev 1.2 added selective integratin which means the integrative component is only active within a small range of the target value
this avoids the integrator to go to limits while an input setpoint change happened and is only causing overshoots.
the int_band is by default 100 which means the int is active all the time and if set to for example to 0.1 the integrator is only active
while the input is between 0.9 and 1.1 of the set_point value.
*)


IF rst OR KP = 0 THEN
   y := offset;
   integ(rst := 1);
   integ.rst := 0;
ELSIF manual THEN
   Y := manual_in + offset;
   integ(rst := 1);
   integ.rst := 0;
ELSE
   (* calcualtion of the actual PID values *)
   diff := set_point - actual;

   (* integrator is only called if TN > 0 and input is within int_band othewrwise it is disabled *)
   IF TN > 0 AND actual > set_point - int_band AND actual < set_point + int_band THEN
      integ(in := diff, K := 1/TN, out_min := (limit_L - offset) / KP, out_max := (limit_H - offset) / KP);
   ELSE
      integ(rst := 1);
      integ.rst := 0;
   END_IF;
   deriv(in := diff, K := TV);

   (* check if integrator has reached the allowed limits and set overflow if necessary *)
   IF integ.Out >= (limit_H - offset) / KP THEN
      Y := limit_H;
      overflow := TRUE;
   ELSIF integ.Out <= (limit_L - offset) / KP THEN
      Y := limit_L;
      overflow := TRUE;
   ELSE
      Y := KP * (integ.Out + deriv.out + diff) + offset;
      overflow := FALSE;
   END_IF;

   (* this portion limits the output to limit_H and limit_L and set the lim flag if limits are exceeded *)
   IF Y > limit_H THEN
      Y := limit_H;
      Lim := TRUE;
   ELSIF Y < limit_L THEN
      Y := limit_L;
      lim := TRUE;
   ELSE
      lim := FALSE;
   END_IF;
END_IF;

(* revision history

hm 1.12.2006 rev 1.1
   changed algorithm to trapezregel for higher accuracy

hm 3.1.2007   rev 1.2
   added integ_band to select when the integrator is active.

*)

122
Bestehende Module / Existing Modules / PT2 Ãœbertragungsglied
« am: 04. Januar 2007, 11:51:37 »
FUNCTION_BLOCK FT_PT2
VAR_INPUT
   in : REAL;
   T1 : TIME;
   T2 : TIME;
   K : REAL := 1;
END_VAR
VAR_OUTPUT
   out : REAL;
END_VAR
VAR
   last : TIME;
   tx: TIME;
   init: BOOL;
   out1 : REAL;
   out2 : REAL;
END_VAR

(*
version 1.1   1 jan 2007
programmer    hugo
tested by      tobias

FT_PT2 is a 2nd grade filter with programmable times T1, T2 and faktor K.
 
*)

tx := TIME();
IF NOT init THEN
   last := tx;
   init := TRUE;
ELSE
   IF T1> t#0s THEN
      out1 := out1 + (in - out1) * TIME_TO_REAL(Tx - last) / TIME_TO_REAL(T1);
   ELSE
      out1 := in;
   END_IF;
   IF T2 > t#0s THEN
      out2 := out2 + (out1 - out2) * TIME_TO_REAL(Tx - last) / TIME_TO_REAL(T2);
   ELSE
      out2 := out1;
   END_IF;
   out := out2 * K;
END_IF;
last := tx;

123
Bestehende Module / Existing Modules / Heizungs Kennlinie
« am: 02. Januar 2007, 01:19:11 »
ein modul für eine heizungskennlinie
noch anregungen?

FUNCTION_BLOCK HK_KNL
VAR_INPUT
   t_ext : REAL;
   enable : BOOL := TRUE;
   T1 : TIME := t#1h;
   TT : TIME := t#2h;
   t_max: REAL;
   t_max_ext : REAL;
   t_min : REAL;
   t_min_ext : REAL;
   T_1 : REAL;
   T_2 : REAL;
   T_3 : REAL;
   Anhebung : REAL;
   Neigung : REAL;
END_VAR
VAR_OUTPUT
   t_out :    REAL;
END_VAR
VAR
   t_e : REAL;
   delay : FT_TN8;
   filter : FT_PT1;
END_VAR

(*
version 1.0   1 jan 2007
programmer    oscat
tested by      tobias

Der Funktionsblock HK_KNL berechnet die vorlauftemperatur in abhaengigkeit von aussentemperatur, 3 fixen temperaturanforderungen (z.B. Boiler) und absenkung und Anhebungsinformationen
t_ext ist der Anschluß der externen Temperatur, es wird empfohlen dort das modul temp_ext zu verwenden, was aber nicht zwingend noetig ist.
wenn temp_ext verwendet wird sollte der ausgang Heat an den Eingang enable gelegt werden.
unabhängig von enable welches die heizung einschaltet, sind 3 eingänge t_1 .. T_3 verfuegbar, wobei hier der hoechste wert verwendet wird und die heizung auf diesen wert gefahren wird unabhaengig vom eingang enable.
dies dient fuer separate verbraucher wie z.B. Boiler oder Schwimmbad u.s.w.

t_max und t_min sind die grenztemperaturen fuer den Ausgang T_out.
T_max_ext und T_min_ext sind die t_ext temperaturen bei denen der knickpunkt fuer t_max und T_min erreicht wird.
z.B. t_min_ext = -18, t_min = 50, t_max_ext = 20, t_max = 35.
unabhaengig von der Einstellung von t_max oder t_max_ext kann jederzeit durch den Eingang enable bereits bei niedrigeren Temperaturen
die Heizung abgeschaltet werden.

der Eingang Absenkung wird zur Kennlinie addiert, also die kennlinie nach oben oder unten entlang der Y achse verschoben,
wobei die Grenztemperaturen t_min und t_max nicht ueberschritten bzw unterschritten werden.

der Eingang Neigung veraendert dabei nur die untere grenztemperatur (t_min) nicht die obere / t_max).
die kurve wird also steiler oder flacher.

Die eingaenge T1 und TT spezifizieren die verzögerung und die Zeitkonstante des Tiefpasses für den eingang t_ext
dadurch kann sowohl eine verzoegerung als auch ein tiefpass für t_ext definiert werden.
per default liegen diese werte bei 2h fuer tt und 1h fuer t1. je nach bauart des gebaeudes sind hier andere werte noetig.

*)


delay(in := t_ext, T := TT);
filter(in := delay.out, T := T1);
t_out := F_Lin2(filter.out, t_min_ext, t_min , t_max_ext, t_max + Neigung) + Anhebung;
IF t_out < t_min THEN
   t_out := t_min;
ELSIF t_out > t_max THEN
   t_out := T_max;
END_IF;
IF NOT enable THEN t_out := 0; END_IF;
IF max3(T_1,t_2,T_3) > t_out THEN t_out := max3(t_1, t_2, t_3); END_IF;

124
eine lineare gleichung y= ax + b die durch zwei wertepaare x1/y1 und x2/y2 beschrieben wird.

FUNCTION F_Lin2 : REAL
VAR_INPUT
   X : REAL;
   X1: REAL;
   Y1 : REAL;
   X2 : REAL;
   Y2 : REAL;
END_VAR
VAR

END_VAR

(*
version 1.0   1 jan 2007
programmer    hugo
tested by      tobias

this function calculates the linear equation f_lin = a*x + b given by two points x1/y1 and x2/y2.

*)

F_Lin2 := (Y2 - Y1) / (X2 - X1) * X + (Y1 * X1 - Y2 * X1) / (X2 - X1) + Y1;

125
Bestehende Module / Existing Modules / FT_PT1
« am: 01. Januar 2007, 13:21:12 »
die version 1.0 des pt1 gliedes weist fehler auf bei sehr kleinen t werten.

die version 1.1 korrigiert diese fehler:

FUNCTION_BLOCK FT_PT1
VAR_INPUT
   in : REAL;
   T : TIME;
END_VAR
VAR_OUTPUT
   out : REAL;
END_VAR
VAR
   last : TIME;
   tx: TIME;
   init: BOOL;
END_VAR

(*
version 1.1   1 jan 2007
programmer    hugo
tested by      tobias

FT_PT1 is an low pass filter with a programmable time T.
 
*)

tx := TIME();
IF NOT init THEN
   last := tx;
   init := TRUE;
ELSIF T = t#0s THEN
   out := in;
ELSE
   out := out + (in - out) * TIME_TO_REAL(Tx - last) / TIME_TO_REAL(T);
   IF out > in THEN out := in; END_IF;
END_IF;
last := tx;

(*
hm 1.1.2007   rev 1.1
   corrected error while startup value was not correct
   for very small time values real output would run out of range.

*)

126
Bestehende Module / Existing Modules / Totzeitglied
« am: 01. Januar 2007, 12:11:45 »
zur regelungstechnik ist vielfach ein totzeitglied noetig, welches aber in software nur unzureichend implememtiert werden kann da es nur endliche samples eines eingangs innerhalb gegebener zeit machen kann.
da je nach anwendung unterschiedliche aufloesung (anzahl der samples) nötig sind haben wir uns entschlossen mehrere totzeitglieder (verzoegerungsglied) mit unterschiedlicher auflösung zu programmieren.
FT_TN8, FT_TN16 und FT_TN64

anbei der code fuer das FT_TN8

FUNCTION_BLOCK FT_TN8
VAR_INPUT
   in : REAL;
   T : TIME;
END_VAR
VAR_OUTPUT
   out : REAL;
END_VAR
VAR
   length : INT := 8;
   X : ARRAY[0..7] OF REAL;
   cnt : INT;
   last : TIME;
   tx: TIME;
   init: BOOL;
END_VAR

(*
version 1.0   1 Jan 2007
programmer    hugo
tested by      tobias

FT_TN8 is delay function, it will delay a signal by a specified time : T and will store 8 values of in before they are put thru to out.
if higher resolution is needed, pls use FT_TN16 or FT_TN64 instead.
 
*)

tx := TIME();
IF NOT init THEN
   x[cnt] := in;
   init := TRUE;
   last := tx;
ELSIF tx - last >= T / length THEN
   IF cnt = length - 1 THEN cnt := 0; ELSE cnt := cnt + 1; END_IF;
   Out := X[cnt];
   x[cnt] := in;
   last := tx;
END_IF;

127
Bestehende Module / Existing Modules / Brennersteuerung
« am: 31. Dezember 2006, 13:31:50 »
FUNCTION_BLOCK Burner
VAR_INPUT
   in : BOOL;
   over_temp : BOOL;
   oil_temp : BOOL := TRUE;
   Flame : BOOL;
   rst : BOOL;
   rst_timer : BOOL;
END_VAR
VAR_INPUT CONSTANT
   vorheizzeit : TIME := t#5s;
   vorbelueftungszeit : TIME := t#15s;
   vorzuendzeit : TIME := t#5s;
   nachzuendzeit : TIME := t#25s;
   sicherheitszeit : TIME := t#5s;
   sperrzeit : TIME := t#10s;
   mehrfachzuendung : BOOL := TRUE;
   KW : REAL;
END_VAR
VAR_OUTPUT
   motor : BOOL;
   oel_ventil : BOOL;
   pre_heat: BOOL;
   zuendung : BOOL;
   betriebsstunden : REAL;
   KWh : REAL;
   fail : BYTE;
END_VAR
VAR
   state : BYTE;
   last : TIME;
   tx: TIME;
   last_change: TIME;
   timer : ontime;
   oil_temp_last: BOOL;
END_VAR

(*
version 1.3   31 dec 2006
programmer    oscat
tested by      tobias

burner ist eine Oel-Brenner_steuerung fuer nichtmodulierende Oelbrenner
die steuerung kann ueber setup werte programmiert werden und entsprechenden brennern angepasst werden.
die vorheizzeit ist die zeit die eine oelvorwaermung aufgeheizt wird bevor der motor gestartet wird.
der eingang oil_temp gibt an ob die oil_temp erreicht wurde, er ist default auf true und kann auch offen gelassen werden.
die vorbelueftungszeit ist die zeit die der luefter laeuft bevor die oelzufuhr freigegeben wird.
die vorzuendzeit iust diejenige zeit die die zuendung vor offnen des oelventiel gestartet wird.
nachzuendzeit ist die zeit die nach entzuendung der flamme noch gezuendet wird.
die sicherheitszeit ist die zeit nach der die oelzufuhr gesperrt wird wenn keine flamme entsteht.
nach ablauf der sicherheitszeit wird ein fehler flag gesetzt und kann erst nach der sperrzeit wieder durch einen reset geloescht werden.
waehrend der sperrzeit ist keine weitere zuendung oder einschalten moeglich.
das flag mehrfachzuendung gibt an ob eine erloschene flamme in betrieb automatisch wieder gezuendet werden soll.
der flammwaechster liegt auf eingang flamme, ein uebertemperaturschutz auf dem eingang over_temp
der betriebsstundenzaehler gibt die brennerstunden in stunden als real ausgabewer an.
der ausgang motor steuert den luefter / pumpenmotor, oil_ventil schaltet das oil ventil und zuendung schaltet die zuendung ein.

if output fail > 0 an error happened and the output has an error code:
0 :   no error
1 :   pre heating time expired and oil temp input is not true
2 :   flame monitor is active during preheating time
3 :   flame monitor active during pre_ventilation_time
4 :   no ignoition during safety time
5 :   no flame during operation
9 :   overtemp input is true

*)

tx := TIME();

(* check rst input and rst if true *)
IF rst OR over_temp OR state = 0 THEN
   IF fail > 0 AND tx - last >= sperrzeit AND rst THEN
      fail := 0;
   ELSE
      (* normaler reset *)
      motor := FALSE;
      oel_ventil := FALSE;
      zuendung := FALSE;
      pre_heat := FALSE;
      IF over_temp THEN fail := 9; END_IF;
      last_change := tx;
      last := tx;
      state := 1;
   END_IF;
END_IF;

(* check for timer rst and rst timer if true *)
IF rst_timer THEN
   timer( rst := TRUE);
   timer.rst := FALSE;
END_IF;

CASE state OF

1:   (* in signal starts oil pre heating *)
   IF in AND NOT flame THEN
      pre_heat := TRUE;
      state := 2;
      last_change := tx;
   END_IF;

2:   (* after pre_heating time start motor *)
   IF (tx- last_change >= vorheizzeit AND oil_temp) OR (oil_temp AND NOT oil_temp_last) THEN
      motor := TRUE;
      state := 3;
      last_change := tx;
   (* vorheizzeit ist abgelaufen und oil_temp ist nicht aktiv *)
   ELSIF tx - last_change >= vorheizzeit AND NOT oil_temp THEN
      state := 7;
      pre_heat := FALSE;
      fail := 1;
      last_change := tx;
   (* flame monitor cannot be active at this time *)
   ELSIF flame THEN
      state := 7;
      pre_heat := FALSE;
      fail := 2;
      last_change := tx;
   END_IF;

3:   (* abwarten bis zündung eingeschaltet werden kann *)
   IF tx - last_change >= vorbelueftungszeit - vorzuendzeit THEN
      zuendung := TRUE;
      state := 4;
      last_change := tx;
   (* flame monitor cannot be active at this time *)
   ELSIF flame THEN
      state := 7;
      pre_heat := FALSE;
      motor := FALSE;
      fail := 3;
      last_change := tx;
   END_IF;

4:   (* warten bis oelzufuhr geoeffnet werden darf *)
   IF tx - last_change >= vorzuendzeit THEN
      oel_ventil := TRUE;
      state := 5;
      last_change := tx;
   END_IF;

5:   (* warten auf flammwaechter und falls noetig abschalten *)
   IF tx - last_change >= sicherheitszeit OR flame THEN
      IF NOT flame THEN
         (* notabschaltung da flammwaechster nicht angesprochen hat *)
         state := 7;
         motor := FALSE;
         oel_ventil := FALSE;
         pre_heat := FALSE;
         zuendung := FALSE;
         fail := 4;
         last_change := tx;
      ELSE
         state := 6;
         last_change := tx;
      END_IF;
   END_IF;

6:   (* brenner läuft, flammueberwachung und nach ablauf der nachzuendungszeit zuendung abschalten *)
   IF NOT flame AND NOT mehrfachzuendung THEN
      (* notabschaltung da flammwaechster keine flamme meldet *)
      state := 7;
      motor := FALSE;
      oel_ventil := FALSE;
      pre_heat := FALSE;
      zuendung := FALSE;
      fail := 5;
      last_change := tx;
   ELSIF NOT flame AND mehrfachzuendung THEN
      zuendung := TRUE;
      state := 5;
      last_change := tx;
   ELSIF tx - last_change >= nachzuendzeit THEN
      (* nachzuendzeit abgelaufen, zuendung abschalten *)
      zuendung := FALSE;
   END_IF;

END_CASE;

(* abschaltung wenn kein eingangssignal *)
IF NOT in AND state > 1 THEN
   state := 1;
   motor := FALSE;
   oel_ventil := FALSE;
   zuendung := FALSE;
   pre_heat := FALSE;
   last_change := tx;
END_IF;

(* betriebsstundenzähler *)
timer(in := flame AND in AND motor AND oel_ventil);
betriebsstunden := timer.ontime;
KWH := betriebsstunden * KW;

(* zeit fuer naechsten aufruf merken *)
last := tx;


(*
31.12.2006   hm      rev 1.1
   added pre_heat timing and output
   flame monitor bofe ignition will generate failure output
   added output for KWh

31.12.2006   hm      rev 1.2
   added oil_temp_input

31.12.2006   hm      rev 1.3
   changed fail output to be byte instead of bool

*)

128
Modulentwicklung / Module Development / wuensche und anregungen
« am: 31. Dezember 2006, 11:17:58 »
hier bitte wuensche fuer module einstellen, oscat bemueht sich die weiterentwicklung an die wuensche der benutzer anzupassen

129
Bestehende Module / Existing Modules / Abstand zweier Datums
« am: 29. Dezember 2006, 14:58:41 »
die funktion date_delta(date1, date2)
berechnet den abstand zweier datumswerte in tagen

130
Bestehende Module / Existing Modules / Datum und Zeiträume addieren
« am: 29. Dezember 2006, 14:57:32 »
add_date(datum, tage, wochen, Monate, Jahre)

addiert zu einem gegebenen Datum tage, wochen, Monate, oder Jahre.
es koennen sowohl positive als auch negative Zahlen addiert also auch subtrahiert werden.


131
Bestehende Module / Existing Modules / Berechnung des Osterdatums
« am: 29. Dezember 2006, 14:55:09 »
funktion easter(date); berechnet den ostersonntag für ein bestimmtes jahr
die meisten kirchlichen feiertage haben einen festen abstand von ostern

132
Bestehende Module / Existing Modules / Berechnung von Feiertagen
« am: 29. Dezember 2006, 14:52:12 »
functiopn block holiday(date);
leifert ein boolsches ausgangssignal wenn am aktuellen datum ein feiertag ist und zugleich einen string mit dem namen des feiertags.
die feiertage sind in arrays constant gespeichert und koennen beliebig veraendert werden.
die feiertage koennen festes datum, referenz zu ostern oder mit wochentag vor einem datum beschrieben werden und erlauben so die einfache definition aller möglichen feiertage.
die derzeit in deutschland gültigen feiertage sind bereits vordefiniert und koennen ganz einfach erweitert werden.

Seiten: 1 ... 7 8 [9]