Multiinstanz-FB Aufrufe

Zuviel Werbung?
-> Hier kostenlos registrieren
@Ralle: Ok Ok - habs noch mal gelesen
Wobei in seiner letzten Antwort nicht klar hervor geht in welchem der beiden FBs er den TON wie oft deklariert hat -> die Antwort auf deine Frage hätte zuerst abgewartet werden müssen...

Das andere war lediglich ein anderer Lösungsansatz zum "mal darüber nachdenken" - mehr nicht.
 
@rs-plc-ra

Ja ist klar. Beim Umgang mit TON bin ich auch etwas unsicher, da ich die eigentlich nie verwende. Und Multiinstanzen sind auch nicht gerade mein Ding, da kommen viele nicht mit klar und mancher Instandhalter mag einen dann gar nicht mehr :ROFLMAO: !
 
Zuviel Werbung?
-> Hier kostenlos registrieren
neuer Anlauf

Nun, ich habe das ganze nicht genügend aus Waldi´s sicht gesehen...

Ich habe selbst so was erst kürzlich gemacht da kam sowohl bei einem Schrittketten FB ein und der selbe eingebettete SFB4 100 mal vor (da er ja immer nur in einem Schritt aktiv sein kann und bei einer alternativen Abzweigung muss er eben mit einer neg. Flanke beim Verlassen noch mal kurz gestartet werden daß er für den nächsten Schritt wieder "frisch" zur Verfügung steht) als auch z.B. in einem FB der Grenzwerte überwacht und jedem Wert eine SFB4 Instanz zugewiesen sein muss damit ggf. mehrere gleichzeitg abweichende Werte parallel mit dem (wenn abgelaufenen-)Timer eine Aktion auslösen können.

In Waldi´s Fall also eindeutig für jede Verwendungsstelle ein separater SFB4... (idealerweise in den FB5000 eingebettet)

Multiinstanz ist o.k. wenn solche Standard-FC/FB wie der SFB4 oder auch Regler oder was auch immer eingebettet werden (solche Dinge eben die nie editiert werden müssen / können).

Mit selbst geschriebenen FBs - speziell wenn es sehr umfangreiche sind würde ich es nicht bevorzugen -> schon allein deshalb wenn es ums Beobachten oder um Optimierungen/Änderungen geht.

Für Waldi hätte ich daher empfohlen seinen FB5000 so zu präparieren daß er komplett über die Schnittstelle parametrierbar ist (was er in beiden Fällen ja sowieso sein muss) und diesen dann direkt im OB1 mit lauter Call FB5000,DB1 ; Call FB5000,DB2 ... aneinandergehängt aufzurufen.

Von der Übersicht her würde ich sagen besser und es spart zu dem noch die doppelte parametrierung da er ja u.U. die Parameter der Instanzen die er im Multiinstanz FB für den FB5000 benötigt ja wiederum an diesen auch noch mal übergeben muss - denn dessen Aufruf steht ja dann spätestens auch in einem OB - oder? (= blöd formuliert)
Einfach formuliert: OB ruft FB auf, versorgt ihn mit allen Parametern die der FB intern wiederum seinen (Multi-)Instanzen zur Verfügung stellt -> doppelt gemoppelt...

Und der Bausteinstatus wäre so unübersichtlich da ja erst mal ewig geblättert werden muss bis die Parameter gefunden sind deren Instanz gerade beobachtet werden soll - deshalb würde ich die Variante mit den separaten IDBs klar bevorzugen.

Aber wie gesagt, ist ja kein Muss sondern nur eine mögliche Alternative.
 
Es ist halt die Frage das wenn ich für jeden Aufruf von FB5000 einen eigenen Instanz-DB mache, ob es dann in meinem Fall nicht zu unübersichtig wird. Da ich zur Zeit Tanks Standardisiere werden es im Maximal Fall 89 Instanz-DB's. Da währe wahrscheinlich ein Multiinstanz-DB einfacher, da ich nicht umbedingt 89 DB aufmachen muss und die Daten im Multiinstanz-DB sind ja schön der reihe nach sortiert.

Da andere ist das wenn ich pro Aufruf so ca. 18 Timer brauche. Also für alle möglichen Schaltvorgänge eine Einschaltverzögerung und zwar so das jeder einzelne Verändert werden kann. Das ist die Problematik. Währe diese nicht da würde ich einen Timer mit einer Konstanten Zeit hernemen und diese als FC einbinden.

Die Idee den FB5000 komplett von aussen zu steuern währe die andere möglichkeit. Das bedeutet aber auch dass ich im maximal Fall 1602 timer verschwenden würde und das ist , glaube ich, ein bisschen zu viel.

Mit dem SFB4 brauche ich auch dutzende DB. Und genau das ist was ich vermeiden will. Ich will eine Konstruktion schaffen die mit möglichst wenigen Timer und DB's auskommt.

Wenn jemand eine gute Idee hat der kann doch auch bitte ein stücken code einstzten damit es ersichtlicher ist was er meint.:)

Was noch eine möglichkeit währe ist dass ich die Aufrufe bedingt durch die zuvor wirkenden Aufrufe steuere. Sprich wenn ich den FB5000 aufrufe lasse ich an desen Ende einen Merker setzten und gebe diesen raus. Erst wenn dieser Merker vorhanden ist werden die 18 Timer zurückgesetzt und der nächste Aufruf wird angesprungen/angeschaltet.
 
Zuletzt bearbeitet:
Mir ist da noch etwas eingefallen.

1. In der Dokumentation steht das mit den Multiinstanzen drin. Das Bild zur Erklärung habe ich angehängt.

2. In meinem FB5000 nutze ich den FC105. Diesen rufe ich jedes mal neu auf und da klappt es. Sprich die Analogsignalverarbeitung aller 89 Tanks funktioniert einwandfrei.

3. Was ist wenn ich anstatt dem FB5000 einen FC5000 einsetzte. Sprich ich mache einen Aufruf mit dem FC. Da dieser FC mir meine Funktionen ausführt und danach alle Daten verliert sind auch die Timer weg und beim nächsten Aufruf werden die Timer frisch geladen. Das könnte doch funktionieren. :p
Da FC's auch auf einen Globalen DB zugreifen können werde ich auch so auf all meine Daten zugreifen können. Mal probieren.
 

Anhänge

  • Multiinstanzen.JPG
    Multiinstanzen.JPG
    32,4 KB · Aufrufe: 23
Zuviel Werbung?
-> Hier kostenlos registrieren
Prinzipiell funktioniert das schon wie du schreibst, aber der Teufel
steckt bekanntlich im Detail.

Stell mal deinen kompletten FB5000 als AWL-Quelle hier Online,
ansonsten ist das alles nur heiteres Rätselraten.

Mfg
Manuel
 
Nun gut überredet. hier folgt der ganze FB5000.
Code:
FUNCTION_BLOCK FB 5000
TITLE =Tank Instrumentation
AUTHOR : WN
FAMILY : Tank
VERSION : 0.3
 
VAR_INPUT
  Level_Transmitter : INT ; 
  Temp_Transmitter : INT ; 
  LAHHH_dig_IN : BOOL ; 
  LAHH_dig_IN : BOOL ; 
  LAH_dig_IN : BOOL ; 
  LAL_dig_IN : BOOL ; 
  LALL_dig_IN : BOOL ; 
  LALLL_dig_IN : BOOL ; 
END_VAR
VAR_OUTPUT
  LAHHH_out : BOOL ; 
  LAHH_out : BOOL ; 
  LAH_out : BOOL ; 
  LAL_out : BOOL ; 
  LALL_out : BOOL ; 
  LALLL_out : BOOL ; 
  TAHHH_out : BOOL ; 
  TAHH_out : BOOL ; 
  TAH_out : BOOL ; 
  TAL_out : BOOL ; 
  TALL_out : BOOL ; 
  TALLL_out : BOOL ; 
  Level : REAL ; 
  Percent : REAL ; 
  next : BOOL ; 
END_VAR
VAR
  LAHHH_analog : REAL  := -1.000000e+000; 
  LAHH_analog : REAL  := -1.000000e+000; 
  LAH_analog : REAL  := -1.000000e+000; 
  LAL_analog : REAL  := -1.000000e+000; 
  LALL_analog : REAL  := -1.000000e+000; 
  LALLL_analog : REAL  := -1.000000e+000; 
  LAHHH_digital : BOOL ; 
  LAHH_digital : BOOL ; 
  LAH_digital : BOOL ; 
  LAL_digital : BOOL ; 
  LALL_digital : BOOL ; 
  LALLL_digital : BOOL ; 
  LAHHH_delay : S5TIME  := S5T#2S; 
  LAHH_delay : S5TIME  := S5T#2S; 
  LAH_delay : S5TIME  := S5T#2S; 
  LAL_delay : S5TIME  := S5T#2S; 
  LALL_delay : S5TIME  := S5T#2S; 
  LALLL_delay : S5TIME  := S5T#2S; 
  LAHHH_hysteresis : REAL  := 1.000000e+001; 
  LAHH_hysteresis : REAL  := 1.000000e+001; 
  LAH_hysteresis : REAL  := 1.000000e+001; 
  LAL_hysteresis : REAL  := 1.000000e+001; 
  LALL_hysteresis : REAL  := 1.000000e+001; 
  LALLL_hysteresis : REAL  := 1.000000e+001; 
  TAHHH : REAL  := -1.000000e+000; 
  TAHH : REAL  := -1.000000e+000; 
  TAH : REAL  := -1.000000e+000; 
  TAL : REAL  := -1.000000e+000; 
  TALL : REAL  := -1.000000e+000; 
  TALLL : REAL  := -1.000000e+000; 
  LAHHH_dig_enable : BOOL ; 
  LAHH_dig_enable : BOOL ; 
  LAH_dig_enable : BOOL ; 
  LAL_dig_enable : BOOL ; 
  LALL_dig_enable : BOOL ; 
  LALLL_dig_enable : BOOL ; 
  TAHHH_enable : BOOL ; 
  TAHH_enable : BOOL ; 
  TAH_enable : BOOL ; 
  TAL_enable : BOOL ; 
  TALL_enable : BOOL ; 
  TALLL_enable : BOOL ; 
  max_level : REAL  := 1.000000e+000; 
  min_level : REAL ; 
  max_temp : REAL  := 1.000000e+002; 
  min_temp : REAL ; 
  Timer1 : "TON"; 
  Timer2 : "TON"; 
  Timer3 : "TON"; 
  Timer4 : "TON"; 
  Timer5 : "TON"; 
  Timer6 : "TON"; 
END_VAR
VAR_TEMP
  Level_Transmitter_Merker : REAL ; 
  Merker1 : REAL ; 
  Merker2 : INT ; 
  TEMP13 : BOOL ; 
  Temp_Transmitter_Merker : REAL ; 
  delay1 : BOOL ; 
  delay2 : BOOL ; 
  delay3 : BOOL ; 
  delay4 : BOOL ; 
  delay5 : BOOL ; 
  delay6 : BOOL ; 
  hysteresis1 : REAL ; 
  hysteresis2 : REAL ; 
  hysteresis3 : REAL ; 
  hysteresis4 : REAL ; 
  hysteresis5 : REAL ; 
  hysteresis6 : REAL ; 
  Merker_Timer1 : BOOL ; 
  Merker2_Timer1 : BOOL ; 
  Merker_Timer2 : BOOL ; 
  Merker_Timer3 : BOOL ; 
  Merker_Timer4 : BOOL ; 
  Merker_Timer5 : BOOL ; 
  Merker_Timer6 : BOOL ; 
END_VAR
BEGIN
NETWORK
TITLE =Pre Transmitter & Pre Calculation
// Scale Level_Transmitter
      CALL FC   105 (
           IN                       := #Level_Transmitter,
           HI_LIM                   := #max_level,
           LO_LIM                   := #min_level,
           BIPOLAR                  := FALSE,
           RET_VAL                  := MW     0,
           OUT                      := #Level_Transmitter_Merker);
// Scale Temp_Transmitter
      CALL FC   105 (
           IN                       := #Temp_Transmitter,
           HI_LIM                   := #max_temp,
           LO_LIM                   := #min_temp,
           BIPOLAR                  := FALSE,
           RET_VAL                  := MW     8,
           OUT                      := #Temp_Transmitter_Merker);
//Load and Calulate the Level and the Percent
      L     #Level_Transmitter_Merker; 
      T     #Level; 
      L     #max_level; 
      L     1.000000e+003; 
      >=R   ; 
      SPB   M001; 
      L     #max_level; 
      L     1.000000e+002; 
      >=R   ; 
      SPB   M002; 
      L     #max_level; 
      L     1.000000e+001; 
      >=R   ; 
      SPB   M003; 
      L     #max_level; 
      L     1.000000e+000; 
      >=R   ; 
      SPB   M004; 
      L     #max_level; 
      L     1.000000e-001; 
      >=R   ; 
      SPB   M005; 
      L     #max_level; 
      L     1.000000e-002; 
      >=R   ; 
      SPB   M006; 
      L     #max_level; 
      L     1.000000e-003; 
      >=R   ; 
      SPB   M007; 
M001: NOP   0; 
      L     #Level; 
      L     1.000000e-001; 
      *R    ; 
      T     #Percent; 
      SPA   M008; 
// aus platzgründen entfernt. Prozent umrechnungen
M007: NOP   0; 
      L     #Level; 
      L     1.000000e+005; 
      *R    ; 
      T     #Percent; 
      SPA   M008; 
M008: NOP   0; 
 
//Set the delay function
      L     #LAHHH_delay; 
      L     0; 
      >I    ; 
      =     #delay1; 
      L     #LAHH_delay; 
      L     0; 
      >I    ; 
      =     #delay2; 
      L     #LAH_delay; 
      L     0; 
      >I    ; 
      =     #delay3; 
      L     #LAL_delay; 
      L     0; 
      >I    ; 
      =     #delay4; 
      L     #LALL_delay; 
      L     0; 
      >I    ; 
      =     #delay5; 
      L     #LALLL_delay; 
      L     0; 
      >I    ; 
      =     #delay6; 
//Set the hysteresis
      L     #LAHHH_hysteresis; 
      L     1.000000e+002; 
      /R    ; 
      L     #max_level; 
      *R    ; 
      L     #LAHHH_analog; 
      TAK   ; 
      -R    ; 
      T     #hysteresis1; 
      L     #LAHH_hysteresis; 
      L     1.000000e+002; 
      /R    ; 
      L     #max_level; 
      *R    ; 
      L     #LAHH_analog; 
      TAK   ; 
      -R    ; 
      T     #hysteresis2; 
      L     #LAH_hysteresis; 
      L     1.000000e+002; 
      /R    ; 
      L     #max_level; 
      *R    ; 
      L     #LAH_analog; 
      TAK   ; 
      -R    ; 
      T     #hysteresis3; 
      L     #LAL_hysteresis; 
      L     1.000000e+002; 
      /R    ; 
      L     #max_level; 
      *R    ; 
      L     #LAL_analog; 
      TAK   ; 
      +R    ; 
      T     #hysteresis4; 
      L     #LALL_hysteresis; 
      L     1.000000e+002; 
      /R    ; 
      L     #max_level; 
      *R    ; 
      L     #LALL_analog; 
      TAK   ; 
      +R    ; 
      T     #hysteresis5; 
      L     #LALLL_hysteresis; 
      L     1.000000e+002; 
      /R    ; 
      L     #max_level; 
      *R    ; 
      L     #LALLL_analog; 
      TAK   ; 
      +R    ; 
      T     #hysteresis6; 
 
NETWORK
TITLE =Mixing + Temperature ( Konfiguration 3) - Analog + digital
 
M015: NOP   0; 
      L     -1.000000e+000; 
      L     #LAHHH_analog; 
      >=R   ; 
      SPB   M030; 
      L     #Level_Transmitter_Merker; 
      L     #LAHHH_analog; 
      >=R   ; 
      L     #LAHHH_delay; 
      SE    "Delay_Timer_HHH_analog"; 
      U     "Delay_Timer_HHH_analog"; 
      S     #LAHHH_out; 
 
// Neu ausgetestet
//      S     #Merker_Timer1
//      CALL  FC   500
//       Input :=#Merker_Timer1
//       Zeit  :=#LAHHH_delay
//       Output:=#Merker2_Timer1
//      U     #Merker2_Timer1
//      S     #LAHHH_out
//      CALL  "TON" , DB2
//       IN:=#Merker_Timer1
//       PT:=#LAHHH_delay
//       Q :=#LAHHH_out
//       ET:=
      L     #Level_Transmitter_Merker; 
      L     #hysteresis1; 
      <=R   ; 
      R     #LAHHH_out; 
 
M030: NOP   0; 
      L     -1.000000e+000; 
      L     #LAHH_analog; 
      >=R   ; 
      SPB   M031; 
      L     #Level_Transmitter_Merker; 
      L     #LAHH_analog; 
      >=R   ; 
      S     #LAHH_out; 
 
//      CALL  #Timer2
//       IN:=#Merker_Timer2
//       PT:=#LAHH_delay
//       Q :=#LAHH_out
//       ET:=
      L     #Level_Transmitter_Merker; 
      L     #hysteresis2; 
      <=R   ; 
      R     #LAHH_out; 
M031: NOP   0; 
      L     -1.000000e+000; 
      L     #LAH_analog; 
      >=R   ; 
      SPB   M032; 
      L     #Level_Transmitter_Merker; 
      L     #LAH_analog; 
      >=R   ; 
      S     #LAH_out; 
//      CALL  #Timer3
//       IN:=#Merker_Timer3
//       PT:=#LAH_delay
//       Q :=#LAH_out
//       ET:=
      L     #Level_Transmitter_Merker; 
      L     #hysteresis3; 
      <=R   ; 
      R     #LAH_out; 
M032: NOP   0; 
      L     -1.000000e+000; 
      L     #LAL_analog; 
      >=R   ; 
      SPB   M033; 
      L     #Level_Transmitter_Merker; 
      L     #LAL_analog; 
      <=R   ; 
      S     #Merker_Timer4; 
//      CALL  #Timer4
//       IN:=#Merker_Timer4
//       PT:=#LAL_delay
//       Q :=#LAL_out
//       ET:=
      L     #Level_Transmitter_Merker; 
      L     #hysteresis4; 
      >=R   ; 
      R     #Merker_Timer4; 
M033: NOP   0; 
      L     -1.000000e+000; 
      L     #LALL_analog; 
      >=R   ; 
      SPB   M034; 
      L     #Level_Transmitter_Merker; 
      L     #LALL_analog; 
      <=R   ; 
      S     #Merker_Timer5; 
//      CALL  #Timer5
//       IN:=#Merker_Timer5
//       PT:=#LALL_delay
//       Q :=#LALL_out
//       ET:=
      L     #Level_Transmitter_Merker; 
      L     #hysteresis5; 
      >=R   ; 
      R     #Merker_Timer5; 
M034: NOP   0; 
      L     -1.000000e+000; 
      L     #LALLL_analog; 
      >=R   ; 
      SPB   M035; 
      L     #Level_Transmitter_Merker; 
      L     #LALLL_analog; 
      <=R   ; 
      S     #Merker_Timer6; 
//      CALL  #Timer6
//       IN:=#Merker_Timer6
//       PT:=#LALLL_delay
//       Q :=#LALLL_out
//       ET:=
      L     #Level_Transmitter_Merker; 
      L     #hysteresis6; 
      >=R   ; 
      R     #Merker_Timer6; 
M035: NOP   0; 
      S     #next; 
      BE    ; 
END_FUNCTION_BLOCK

ich hoffe ihr könnt mir ein bisschen weiter helfen :rolleyes:

aus platzgründen wurde der Code ein bisschen gekürtzt, aber ich denke das wesentliche ist drauf.
 
möglicher, zum Teil funktionierende Lösung

Also ich habe nun eine halbwegs funktionierende Lösung erstellt.
Ich habe die Zeitkritischen Funktionen als FC5000 ausgelagert und rufe diese immer wieder auf. Ähnlich wie der TON nur als Funktion.
Sprich ich übergebe der Funktion das einschalt Signal, die Dauer, den Timer und bekomme das Schaltsignal. Nun habe ich für die LAHHH-LALLL analog sechs Timer verwendet. Diese Funktionieren auch bei allen 89 Tanks, aber wie schon gesagt wurde,
Der Teufel liegt im Detail

Ich habe halt das Problem dass wenn zwei oder mehr aufrufe vorhanden sind und bei einem Aufruf sich der Analog Wert über die eingestellte Größe hin ändert, so wird der Ausgang auch nach der eingestellten Zeit eingeschaltet. So das Problem ist dass der Timer dann nicht bei 0 stehen bleibt sondern immer wieder neu anfängt.

Dass ist ja eigentlich nicht so schlimm. Sollte nun bei einem anderen Aufruf der selbe analoge Wert sich ändern so fällt dieser in den zuvor laufenden Timer rein. Also ist es nicht garantiert dass der zweite Aufruf exakt mit der eingestellten Zeit abläuft.


?????????????????????????????????????????????????????

Wie muüsste ich den Aufruf verändern dass der Timer nicht wieder von vorne anläuft.

Timer:
U #Input
L #Zeit
SE #Timer_0
U #Timer_0
= #Output
BE

FB5000:
M015: NOP 0
L -1.000000e+000
L #LAHHH_analog
>=R
SPB M030
L #Level_Transmitter_Merker
L #LAHHH_analog
>=R
S #Merker_Timer1

CALL FC 500
Input :=#Merker_Timer1
Zeit :=#LAHHH_delay
Timer_0:=T50
Output :=#Merker2_Timer1
R #Merker_Timer1
U #Merker2_Timer1
S #LAHHH_out
L #Level_Transmitter_Merker
L #hysteresis1
<=R
R #LAHHH_out

Bin für jeden Ratschlag offen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Du hast da was noch nicht richtig verstanden...

Wenn du die SFB4 Timer in der Anzahl die 1* FB5000 braucht in den FB5000 einbettest und diesen dann mit verschiedenen Instanz-DBs aufrufst (wo auch immer) dann brauchen die SFB4 Timer KEINEN zusätzlichen IDB mehr -> da ja im STAT (=IDB des FBs) eingebettet !

Du hättest also im schlimmsten fall 89 IDBs des FB5000 !
(Da reservierst du irgend einen 100er Bereich an DB Nummern und benennst sie fortlaufend und gut is)
 
Zurück
Oben