Bausteine aufrufen für dummies

Zuviel Werbung?
-> Hier kostenlos registrieren
Es können dann allerdings keine Parameter bzw. Instanz-DB angegeben werden.


Also kaum für eine Anwendung geeignet, nümm?

Sprünge sind ok. Man muß halt bedenken dass die bearbeiteten Daten "eingefroren werden" bis der FC wieder aufgerufen wird.
 
Zuletzt bearbeitet:
He 4L, geiler Satzbau, aber kannst du das bitte nochmal eindeutschen! :ROFLMAO:

hier wird vielleicht deutlicher, was ich meine:

Code:
*
FUNCTION_BLOCK FB 2
TITLE =
VERSION : 0.1

VAR_INPUT
  in1 : BOOL ; 
  in2 : BOOL ; 
END_VAR
VAR
  _1 : BOOL ; 
  _2 : BOOL ; 
  _3 : BOOL ; 
  _4 : BOOL ; 
  _5 : BOOL ; 
  _6 : BOOL ; 
  _7 : BOOL ; 
  _8 : BOOL ; 
END_VAR
BEGIN
NETWORK
TITLE =
      U     #_6; 
      U     #_7; 
      =     #_5; 
END_FUNCTION_BLOCK
FUNCTION_BLOCK FB 1
TITLE =
VERSION : 0.1

VAR_INPUT
  in1 : BOOL ; 
  in2 : BOOL ; 
END_VAR
VAR
  _1 : BOOL ; 
  _2 : BOOL ; 
  _3 : BOOL ; 
  _4 : BOOL ; 
  _5 : BOOL ; 
  _6 : BOOL ; 
  _7 : BOOL ; 
  _8 : BOOL ; 
END_VAR
BEGIN
NETWORK
TITLE =
      U     #in1; 
      =     #_1; 
      U     #in2; 
      =     #_2; 
NETWORK
TITLE =
      U     #_1; 
      U     #_2; 
      =     #_4; 
NETWORK
TITLE =
      SET   ; 
      =     #_6; 
      CLR   ; 
      =     #_7; 
      UC    FB     2; //unbedingter aufruf, IDB bleibt erhalten

NETWORK
TITLE =
      U     #_5; 
      U     #_4; 
      =     #_8; //geht nicht, weil 7 auf null
END_FUNCTION_BLOCK
DATA_BLOCK DB 1
TITLE =
VERSION : 0.0
 FB 1
BEGIN
   in1 := FALSE; 
   in2 := FALSE; 
   _1 := FALSE; 
   _2 := FALSE; 
   _3 := FALSE; 
   _4 := FALSE; 
   _5 := FALSE; 
   _6 := FALSE; 
   _7 := FALSE; 
   _8 := FALSE; 
END_DATA_BLOCK
ORGANIZATION_BLOCK "Cycle Execution"
TITLE = "Main Program Sweep (Cycle)"
VERSION : 0.1

VAR_TEMP
  OB1_EV_CLASS : BYTE ; //Bits 0-3 = 1 (Coming event), Bits 4-7 = 1 (Event class 1)
  OB1_SCAN_1 : BYTE ; //1 (Cold restart scan 1 of OB 1), 3 (Scan 2-n of OB 1)
  OB1_PRIORITY : BYTE ; //Priority of OB Execution
  OB1_OB_NUMBR : BYTE ; //1 (Organization block 1, OB1)
  OB1_RESERVED_1 : BYTE ; //Reserved for system
  OB1_RESERVED_2 : BYTE ; //Reserved for system
  OB1_PREV_CYCLE : INT ; //Cycle time of previous OB1 scan (milliseconds)
  OB1_MIN_CYCLE : INT ; //Minimum cycle time of OB1 (milliseconds)
  OB1_MAX_CYCLE : INT ; //Maximum cycle time of OB1 (milliseconds)
  OB1_DATE_TIME : DATE_AND_TIME ; //Date and time OB1 started
END_VAR
BEGIN
NETWORK
TITLE =
      CALL FB     1 , DB     1 (
           in1                      := E      0.0,
           in2                      := E      0.1);
END_ORGANIZATION_BLOCK
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@4L

Damit können sich ein paar spezielle Jungs dann wieder ordentlich austoben. :ROFLMAO:
Hinterher dürfen wir ran und am Besten mit einem neuen Programm für Klarheit sorgen.
 
@4L

Damit können sich ein paar spezielle Jungs dann wieder ordentlich austoben. :ROFLMAO:
Hinterher dürfen wir ran und am Besten mit einem neuen Programm für Klarheit sorgen.

ich find das, ehrlich gesagt, ziemlich geil. du hast einen übergeordneten baustein, mit einer festgelegten struktur. diese struktur trägst du in alle aufgerufenen FBs ein und kannst so innerhalb von überall auf alles zugreifen ohne global adressieren zu müssen ... also auch die portierbarkeit bleibt erhalten

feine sache das - das beispiel nicht, das war ein bißchen dürftig und nur schnell zusammengeschustert :rolleyes:
 
ich find das, ehrlich gesagt, ziemlich geil. du hast einen übergeordneten baustein, mit einer festgelegten struktur. diese struktur trägst du in alle aufgerufenen FBs ein und kannst so innerhalb von überall auf alles zugreifen ohne global adressieren zu müssen ... also auch die portierbarkeit bleibt erhalten

feine sache das - das beispiel nicht, das war ein bißchen dürftig und nur schnell zusammengeschustert :rolleyes:

Das war mir klar, daß du das gut findest.:ROFLMAO:
Ich finde das 100%-ige Sch...
Wenn da einer drin ändert, ohne immer alle FB nachzuführen ist Sense.
Da wäre es doch wirklich, gerade in diesem Falle, intelligenter, einen globalen DB herzunehmen. Aber das ist ja eh der alte Streit.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
der vorteil ist, dass du in einer anlage mit vielen ähnlichen maschinen, gleiche funktionen auslagern kannst und dich nur noch auf eine gesamte datenstruktur einigen brauchst.
 
der vorteil ist, dass du in einer anlage mit vielen ähnlichen maschinen, gleiche funktionen auslagern kannst und dich nur noch auf eine gesamte datenstruktur einigen brauchst.

4L glaub mir, ich hab gerade so ein Ding hier auf dem Tisch liegen und hau den ganzen Mist raus. (Graph7 + PDiag, eigentlich ne tolle Sache) Die haben allerdings immer am Anfang ihrer FB die Daten per indirekter Adressierung in ihren IDB rein kopiert und noch ein paar andere Gimmicks angewandt. Fakt ist, daß es für "Nicht Eingeweihte" extrem schwierig ist alle Zugriffe auf die Daten auch zu finden. Und selbst wenn, dauert das jedes mal ewig lange, weil man mehrere Möglichkeiten beim Suchen durchspielen muß. Das ist definitiv nicht so toll für Wartung und Instandhaltung.
 
ich sitz hier grad in einer anlage wo es genau so gemacht ist ... und es ist gut so - sorry - ich war auch mal instandhalter und hab mich auch während dieser zeit nicht vor einer, auf die anwendung zugeschnittene datenstruktur gescheut.
sicher könnte man das ganze auch mit globalen DBs machen, aber bitte wie willst du da portierbare bausteine schreiben ... jetz hör mir aber auf mit AUF DB ... und vielleicht noch als INT übegeben oder so ... das ist IMHO wesentlich schlimmer als eine anlage mit 15 CPUs die nach obigen schema alle die struktur beinhalten.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
was ja kein Geheimnis ist und wohl auch schon lange bekannt sein dürfte: da stehe ich klar auf Ralles Seite.

@4L: was ich sehr empfehlen würde, um den Gleichklang der Deklarationen in den verschiedenen FB sicherzustellen: einen UDT definieren und den in die Deklaration der verschiedenen FB reinschreiben. Dann ist die Datenstruktur für die beteiligten FB an zentraler Stelle änderbar und auch klar ersichtlich, welche FB gemeinsam auf diese Struktur zugreifen.
 
@4L: was ich sehr empfehlen würde, um den Gleichklang der Deklarationen in den verschiedenen FB sicherzustellen: einen UDT definieren und den in die Deklaration der verschiedenen FB reinschreiben. Dann ist die Datenstruktur für die beteiligten FB an zentraler Stelle änderbar und auch klar ersichtlich, welche FB gemeinsam auf diese Struktur zugreifen.

ich hoffe, du beziehst dich jetzt nicht aufs beispiel :rolleyes: ...

ansonsten, ja, durchaus eine richtige und wichtige anmerkung und so ist es auch realisiert.
 
@4L: entschuldige, ich hatte da etwas flüchtig drübergelesen:
... übergeordneten baustein, mit einer festgelegten struktur. diese struktur trägst du in alle aufgerufenen FBs ein ...
und nach dieser Anmerkung:
... Wenn da einer drin ändert, ohne immer alle FB nachzuführen ist Sense. ...
dann wirklich an eine Strukturierung, wie Du sie im Beispiel angeführt hast, gedacht.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
@4L
Es sind nun mal nicht alle SPS-Programmierer und nicht alle Instandhalter die großen Superprogrammierer (Ich zähle mich auch nicht dazu, das zeigt offensichtlich meine schwache Begeisterung für das, was du so Klasse findest). Besonders, wenn in den Firmen die Instandhalter nur selten nach Fehlern suchen müssen und viele Systeme zu betreuen haben, ist das unmöglich. Daher bin ich nach wie vor der Meinung, daß man es den Leuten ja nicht gar zu schwer machen muß, nur, um seinen Genius zu beweisen. Wir reden hier wohlgemerkt nicht über Serienmaschinen zu 1000 Stück, sondern über Sondermaschinenbau.
 
am Rande angemerkt: mir ist das Problem des Kollegen rs-plc-aa wieder eingefallen: "Großen FB in 2 Teile splitten - knifflig."
http://www.sps-forum.de/showthread.php?t=16404

da kam dann auch der CC/UC als Lösungsansatz drin vor:
Hallo!

Ja die zwei FB's müssen in der Deklaration gleich sein und den zweiten FB rufst du dann mit CC / UC auf dann brauchst du keine Parameter mehr übergeben.
siehe dazu http://www.sps-forum.de/showthread.php?t=14604&highlight=fb+aufruf
zum Schluss von dem Thread habe ich das mal ausprobiert einen FB mit CC / UC aufrufen.

godi
 
Moin vierlagig,

das finde ich sehr interessant. Ich habe mich schon immer gefragt, wofür man "UC" braucht.
Man könnte allerdings auch die IDB-Nummer des ersten FB abfragen, den Wert dem aufgerufenen FB als Eingangsvariable übergeben und dann den IDB der ersten öffnen (AUF DI [IDB-Nummer]). Dann greift man direkt auf den IDB des ersten FB zu...
 
Moin vierlagig,

ich hatte mal einen Code, wie folgt vorliegen:

Code:
      L     #Scannp_db                  // Kopieren der Daten in den Telegrammsendebereich
      T     #P_Db


      L     #Scann_dw
      SLW   3
      LAR1  


      L     0
      SLW   3
      LAR2  


      AUF   DI   179


      AUF   DB [#P_Db]


      L     5
loop: T     #Za


      L     #Scannp_db
      T     DBW [AR1,P#0.0]


      +AR1  P#1.0
      +AR2  P#1.0


      L     #Za
      LOOP  loop
      L     0
      T     #Fehl
      CALL  "Daten_löschen"
       Db_quelle:=179
       Von      :=0
       Nach     :=30
       wert     :=B#16#20


      BEA   


old:  NOP   0

Dabei werden Daten aus dem DB179 an den DB5103 (IN #Scannp_db als int) übergeben.
Mal abgesehen davon, dass die DBW-Adresse immer nur um ein Byte hochgezählt wird und ich auf diese Weise bei fünf Durchläufen 6 Byte übergeben werden,
wird innerhalb der Schleife symbolisch auf #Scannp_db zugegriffen. Dabei ist hier der erste int-Wert aus DB179 abgefragt worden, weil als DI geöffnet.
Das hier nicht der übergebene IN-Wert stand, war der Knackpunkt und es hat echt gedauert, bis ich das verstanden habe :rolleyes:

Könnte man auf diese Weise nicht auf (gleiche) Deklarationen zugreifen, wobei man als IDB einen anderen, als den bei Bausteinaufruf angegebenen öffnet?


Gruß

MFreiberger
 
Könnte man auf diese Weise nicht auf (gleiche) Deklarationen zugreifen, wobei man als IDB einen anderen, als den bei Bausteinaufruf angegebenen öffnet?

und genau damit ist der Witz gemordet. man muss für jeden CALL-Aufruf eine Instanz, sei es nun ein Instanz-DB pro Aufruf oder eine Multiinstanzdefinition angeben.
Ferner muss die Nummer übergeben werden.
Schmutziger ist nur, auf die Lokaldaten des Vorgängers zu zugreifen :roll:

Dabei werden Daten aus dem DB179 an den DB5103 (IN #Scannp_db als int) übergeben.
Mal abgesehen davon, dass die DBW-Adresse immer nur um ein Byte hochgezählt wird und ich auf diese Weise bei fünf Durchläufen 6 Byte übergeben werden,
wird innerhalb der Schleife symbolisch auf #Scannp_db zugegriffen. Dabei ist hier der erste int-Wert aus DB179 abgefragt worden, weil als DI geöffnet.
Das hier nicht der übergebene IN-Wert stand, war der Knackpunkt und es hat echt gedauert, bis ich das verstanden habe :rolleyes:

An welcher stelle wird Symbolisch auf den zweiten geöffneten Datenbaustein zugegriffen?
Das sieht zumindest nach einer ziemlichen Sauerei aus!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin vierlagig,

und genau damit ist der Witz gemordet. man muss für jeden CALL-Aufruf eine Instanz, sei es nun ein Instanz-DB pro Aufruf oder eine Multiinstanzdefinition angeben.
Ferner muss die Nummer übergeben werden.
Schmutziger ist nur, auf die Lokaldaten des Vorgängers zu zugreifen :roll:

alles klar. habe ich verstanden.

Code:
      L     #Scannp_db                  // Kopieren der Daten in den Telegrammsendebereich     >>> hier war der Zugriff noch i.O. (Wert 5103, IN-Parameter)
      T     #P_Db


      L     #Scann_dw
      SLW   3
      LAR1  


      L     0
      SLW   3
      LAR2  


      AUF   DI   179             >>> bis hier war es der, für den FB angegebene IDB80. Danach 179


      AUF   DB [#P_Db]


      L     5
loop: T     #Za


      L     #Scannp_db            >>> hier erfolgte der (unrechtmäßige) Zugriff! (Wert aus [FONT=Verdana, Arial, Tahoma, Calibri, Geneva, sans-serif][B][I]IDB[/I][/B]179 mit Adresse der in diesem FB deklarierten Variablen #Scannp_db)[/FONT]

      T     DBW [AR1,P#0.0]


      +AR1  P#1.0
      +AR2  P#1.0


      L     #Za
      LOOP  loop
      L     0
      T     #Fehl
      CALL  "Daten_löschen"
       Db_quelle:=179
       Von      :=0
       Nach     :=30
       wert     :=B#16#20


      BEA   
 [COLOR=#333333] [/COLOR][COLOR=#333333]old: NOP 0[/COLOR]



Habs ja gefunden :)

Gruß

MFreiberger
 
Zurück
Oben