Step 7 FB IN-Parameter nicht beschalten

reinip

Level-1
Beiträge
7
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo Gemeinde,

ich möchte einen Standard-FB programmieren, bei den als IN-Parameter Datentypen von "BLOCK_DB" deklariert sind.
Diese IN-Parameter werden jedoch aussen nicht zwingend beschalten.

Falls diese nicht beschalten werden, soll auch der Programmteil im inneren des FB's nicht bearbeitet werden.

Wie kann ich nun herausfinden ob die IN-Parameter verschalten sind?

Kann man das über Pointer machen? Nur wie funktioniert das bei "BLOCK_DB"?

Merci im Voraus!!!
 
Wenn sich die Parameter vom Typ Block_DB während der Laufzeit für die jeweilige Instanz nicht ändern, könntest Du sie einfach auf 0 abfragen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Bei einem Block_DB Eingang ist es nicht so einfach. Da bekommst Du normal rinen Fehler, wenn die DB Nummer Null ist oder nicht existiert. (Oder hab ich was übersehen?).
Ich würde einen Int Eingang nehmen und den auf eine INT temp Variable legen.
Diese dann vergleichen und entsprechend verschalten.
Wenn OK dann öffne Z.B. DB über indirekten Aufruf.
z.B.
L IN_INT_BSP
T TMP_INT_BSP
L 0
==I
SPB END

AUF DB[TMP_INTBSP]
{ Dein Code}
END: NOP 0
 
INT Eingang würde gehen, verwende ich aber mit Absicht nicht, da bei einer DB-Nummern-Übergabe mit INT, diese DB's in der Referenzliste nicht aufscheinen.

Der Parameter vom Typ Block_DB ändert sich normalerweise nicht und ist mit 0 vorbelegt. Wenn aber jemand den IN Parameter aussen mit einem DB verschaltet und die Verschaltung anschließend wieder löscht, ist mein Aktualwert leider nicht mehr "0".
Deshalb müsste ich wissen ob der IN-Parameter von aussen wirklich beschalten ist.
 
edit: Ich habe deinen Post über Dir nicht gelesen gehabt beim posten. Dann hat sich meine "Lösung" wohl erledigt. Hab es auch noch nicht weiter ausprobiert.


Ich denke, so könnte es gehen. Vorraussetzung ist, das meine Beobachtung stimmt, und ein nicht beschalteter Block_DB eingang wirklich immer '1' liefert. Das müsstest du dann noch rausfinden.

Code:
      AUF   #i_DB1
      L     DBNO
      L     1
      <>I   
      SPBN  END

// Dein Code

END:  NOP   0
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie gesagt, das Problem ist: IN-Parameter mit DB verschalten (z.Bsp. DB20) -> runtergeladen -> IN-Parameter (DB20) wieder gelöscht wird -> runtergeladen -> dann steht im Aktualwert im Instanz-DB der Wert "20" obwohl der IN-Parameter nicht verschalten ist.
 
Evtl. lässt sich das ganze ja kombinieren.
Eine vorgeschalteten FC mir Block_DB Eingang, dort DB Nummer mit DBNO aus lesen und an FB übergeben.
Dort dann Auswertung wie von mir beschrieben.
Dann hast die Referenz und kannst den Programmteil ab Blocken wie von mir beschrieben.

Dann hätte sich auch die Vorbelegung erledigt, denn im FC wird kein Wert gespeichert sondern default genommen.
Nur wirst Du bei der Vorbelegung mit 0 immer einen Fehler erhalten.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dann hätte sich auch die Vorbelegung erledigt, denn im FC wird kein Wert gespeichert sondern default genommen.
Nur wirst Du bei der Vorbelegung mit 0 immer einen Fehler erhalten.
In FC gibt es keine Default-Werte, FC-In/Out-Parameter können nicht unbeschaltet bleiben. Es kann auch keinen Fehler geben, denn FC mit unbeschalteten Eingängen können garnicht erst in die CPU geladen werden.

Harald
 
Das Problem hat man ja schließlich mit allen Parametern eines FB. Ich würde mal behaupten, solche Dinge liegen in der Verantwortung des Programmieres. Bei einem BLOCK_DB sollte man mit der SFC24 "TEST_DB" prüfen ob der DB vorhanden ist und die richtige Länge hat.
 
... es ändert aber nichts an der Sache, dass man nicht wirklich herausfinden kann, ob ein FB-IN-Parameter (ob nun vom Typ Block_DB oder etwas Anderem) aktuell wirklich beschaltet ist oder ob er es nur irgendwann einmal war.

Eine Möglichkeit, die ich mir vorstellen könnte, wäre dies (habe aber noch nicht getestet ob das wirklich geht) :
Beim FB-Aufruf erst beim 2.Zyklus den IN-Parameter akzeptieren.
Beim 1. Aufruf den IN-Parameter (in diesem Fall über einen Pointer) auf '0' schreiben bzw. auch nach jedem neuen Einlesen.
Auf diese Weise könnte eine wieder entfernte Beschaltung in der Instanz gelöscht werden.
Wenn der TE es nicht probiert - ich werde es auf alle Fälle später am Tag mal testen, ob das funktionieren würde ...

Gruß
Larry
 
Ich komme aber nochmal auf meine FC vorschaltung zurück...
Wenn ein Eingang nicht mehr beschalten wird dann muss dies doch Durch einen Eingriff übers "PG" erfolgen oder seh ich da was falsch.
Man kann doch Programmcode nicht durchs Programm ändern lassen oder?
Wenn ich richtig liege kann doch dann ebenfalls ein FC gelöscht oder Übersprungen werden.

Wobei dann wäre auch ein zusätzlicher Eingang am FB denkbar, mit dem man sagt BLOCK_DB aktiv/inaktiv.

Oder man nimmt einen Platzhalter DB, und fragt dann ab ob der zu öffnende DB der Platzhalter ist.
Dies wäre dann auch unter zu Hilfename von CREATE_DB dynamisch erstellbar.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
So ... hier mal mein Vorschlag dazu :
Code:
FUNCTION_BLOCK FB 2
TITLE = 
VERSION : 0.1
VAR_INPUT
  myDB1 : BLOCK_DB ; 
  myDB2 : BLOCK_DB ; 
END_VAR
VAR
  first_Call : BOOL  := TRUE; 
END_VAR
VAR_TEMP
  myDB1_beschaltet : BOOL ; 
  myDB2_beschaltet : BOOL ; 
END_VAR
BEGIN
NETWORK
TITLE = 
      U     #first_Call; 
      SPB   Ende; 
NETWORK
TITLE = 
      LAR1  P##myDB1; 
      TAR2  ; 
      +AR1  ; 
      L     W [AR1,P#0.0]; 
      L     0; 
      <>I   ; 
      =     #myDB1_beschaltet; 
      LAR1  P##myDB2; 
      TAR2  ; 
      +AR1  ; 
      L     W [AR1,P#0.0]; 
      L     0; 
      <>I   ; 
      =     #myDB2_beschaltet; 
NETWORK
TITLE = 
 
NETWORK
TITLE = 
 
NETWORK
TITLE = 
Ende: U     #first_Call; 
      R     #first_Call; 
      LAR1  P##myDB1; 
      TAR2  ; 
      +AR1  ; 
      L     0; 
      T     W [AR1,P#0.0]; 
      LAR1  P##myDB2; 
      TAR2  ; 
      +AR1  ; 
      L     0; 
      T     W [AR1,P#0.0]; 

END_FUNCTION_BLOCK

Gruß
Larry
 
Ich komme aber nochmal auf meine FC vorschaltung zurück...
Wenn ein Eingang nicht mehr beschalten wird dann muss dies doch Durch einen Eingriff übers "PG" erfolgen oder seh ich da was falsch.
Ich musste auch lange darüber nachdenken.
Ich sehe das im Prinzip genauso, wie Du. Entweder, der Parameter ist beschaltet oder nicht, er ist nicht mal beschaltet und mal nicht, AUßER der FB wird mehrfach mit der gleichen Instanz aufgerufen. Dann kann der Parameter mal beschaltet sein und mal nicht.
 
Oh stimmt das war ja auch noch eine Variante. [emoji4]

Dann ist wohl (ausser Pointer) nur noch ein Platzhalter_DB möglich.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wenn der FB eine "eierlegende Wollmilchsau" mit wechselnden Eingangsbeschaltungen werden soll, dann würde ich dem FB noch einen "MODE"-Eingang spendieren, wo über einen Funktionscode angegeben wird, welche Funktion er ausführen soll und er dadurch weiß welche Eingänge auszuwerten sind.


"Eingang beschaltet" - zählt da nur, wenn direkt beim FB-Call eine Konstante oder Variable angeschaltet ist?
Wie sollen folgende Konstrukte interpretiert werden? Die Eingänge sind "beschaltet" oder nicht? :
Code:
Instanz.Eingang1 := 1234;
Instanz(Eingang1 := , Eingang2 := TRUE);

IF Bedingung THEN
  Instanz.Eingang1 := #MyVar;
END_IF;
Instanz(Eingang1 := , Eingang2 := );

(einem "Block_DB"-Eingang läßt sich natürlich nicht ganz so einfach etwas zuweisen, es geht aber Registerindirekt in AWL)

Harald
 
He hatte ich so nen Eingang nicht auch mal ins Spiel gebracht?
Ich glaub ja, aber irgendwie hats jeder übersehen/vergessen incl. uch selbst. ;)
 
So ... hier mal mein Vorschlag dazu :
Code:
FUNCTION_BLOCK FB 2
TITLE = 
VERSION : 0.1
VAR_INPUT
  myDB1 : BLOCK_DB ; 
  myDB2 : BLOCK_DB ; 
END_VAR
VAR
  first_Call : BOOL  := TRUE; 
END_VAR
VAR_TEMP
  myDB1_beschaltet : BOOL ; 
  myDB2_beschaltet : BOOL ; 
END_VAR
BEGIN
NETWORK
TITLE = 
      U     #first_Call; 
      SPB   Ende; 
NETWORK
TITLE = 
      LAR1  P##myDB1; 
      TAR2  ; 
      +AR1  ; 
      L     W [AR1,P#0.0]; 
      L     0; 
      <>I   ; 
      =     #myDB1_beschaltet; 
      LAR1  P##myDB2; 
      TAR2  ; 
      +AR1  ; 
      L     W [AR1,P#0.0]; 
      L     0; 
      <>I   ; 
      =     #myDB2_beschaltet; 
NETWORK
TITLE = 
 
NETWORK
TITLE = 
 
NETWORK
TITLE = 
Ende: U     #first_Call; 
      R     #first_Call; 
      LAR1  P##myDB1; 
      TAR2  ; 
      +AR1  ; 
      L     0; 
      T     W [AR1,P#0.0]; 
      LAR1  P##myDB2; 
      TAR2  ; 
      +AR1  ; 
      L     0; 
      T     W [AR1,P#0.0]; 

END_FUNCTION_BLOCK

Gruß
Larry

Danke für Dein Bsp. Larry. Eine Frage noch: für was benötige ich TAR2 u. +AR1?

Wäre
LAR1 P##myDB1;
L 0;
T W [AR1,P#0.0];
nicht ausreichend?
 
Zurück
Oben