TIMER in Bibliotheksfähigen Bausteinen

FrankLA

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

ich hab ein Problem mit einem FC, den ich programmiert hab.
Der FC soll in einem anderen FC aufgerufen werden.
Ich hab alle Timer, Merker und Zähler in dem Baustein Symbolisch adressiert. wenn ich sie in dem zweiten FC, der später auch mehrmals aufgerufen werden soll wieder symbolisch adressieren will funktioniert das nicht.

Ich hab die Timer in beiden FCs als als EIngangsvariable deklareiert. und den Datentyp TIMER gewählt.


ich hoffe jemand von euch kann mir helfen. Danke im voraus.
 
Hallo,

vielleicht verstehe ich dein Problem falsch, aber in bibliotheksfähigen Bausteinen darf man keine "symbolische Adressierung" benutzen, weil die Bausteine dadurch eben nicht mehr bibliotheksfähig sind! :rolleyes:

Ich habe mir vor einiger Zeit auch mal einen FC-Baustein in AWL zusammengestrickt, bei dem ich als Eingangsvariable einen x-beliebigen Timer (z.B. "T5") anlegen kann.

Code:
...
L #Timerwort   /Timerwort mit Zeitwert und Zeitbasis, Datentyp WORD
...
SV #Timer_Nr   /Timer starten; Eingangsvariable vom Datentyp TIMER
...

Gruß! ;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Mit Symbolisch meine ich Variablen in der Symboltabelle bezeichent. diese Tauchen dann ja beim aufrufen des Bausteins wieder als Ein- und Ausgänge des Bausteins auf (Ich programmiere im FUP) wo man sie dann im OB1 mit den absoluten Adressen (T1, T2, E0.0, A1.3...) deklariert. Ich will den FC aber nicht im OB1 aufrufen, sondern in einem anderen FC. In dem kann ich die Variablen wieder nicht absolut deklarieren, weil ich diesen Baustein dann mehrmals aufrufen möchte. Allerdings kann ich diese Eingangsvariablen des "UnterFCs" nicht Mit Variablen des FCs deklarieren. (Mit der absoluten Adresse funktioniert es.)
 
kannst du uns mal den genauen aufbau und die funktion deines programms erklären? es fällt mir etwas schwer, mir darunter etwas vorzustellen.

so verstehe ich es bis jetzt (korrigier mich, wenn ich falsch lieg):
du hast einen fc (sagen wir fc1), den du mehrmals aufrufen möchtest. in diesem wird wieder ein anderer fc (sagen wir fc2) mehrmals aufgerufen. ein beliebiger timer wird an einen eingang von fc1 gelegt und und in diesem an den fc2 "durchgeschleust".

wenn du einen timer innerhalb von mehrfach aufgerufenen bausteinen absolut vergibst (also direkt t1, t2, ...) funktioniert das nicht. ich habe leider noch nicht mit timern als ein- oder ausgängen gearbeitet. für so einen fall habe ich mir immer einen eigenen timer geschrieben.
 
Ich würde das auch so wie PsYchO_LoGiC verstehen.

Ich habe zwar auch noch nicht so viel mit Timern gearbeitet, aber grundsätzlich nehme ich für "spezielle" eigene Bausteine nur AWL und eine allgemeingültige Adressierung mittels Pointer und Adressen etc., um den Baustein bibliotheksfähig zu halten. Hatte bis jetzt damit keine Probleme.

Beschreib dein Programm doch mal genauer. Das macht die Sache vielleicht einfacher zu verstehen. ;)
 
Zuviel Werbung?
-> Hier kostenlos registrieren
kannst du uns mal den genauen aufbau und die funktion deines programms erklären? es fällt mir etwas schwer, mir darunter etwas vorzustellen.

so verstehe ich es bis jetzt (korrigier mich, wenn ich falsch lieg):
du hast einen fc (sagen wir fc1), den du mehrmals aufrufen möchtest. in diesem wird wieder ein anderer fc (sagen wir fc2) mehrmals aufgerufen. ein beliebiger timer wird an einen eingang von fc1 gelegt und und in diesem an den fc2 "durchgeschleust".

wenn du einen timer innerhalb von mehrfach aufgerufenen bausteinen absolut vergibst (also direkt t1, t2, ...) funktioniert das nicht. ich habe leider noch nicht mit timern als ein- oder ausgängen gearbeitet. für so einen fall habe ich mir immer einen eigenen timer geschrieben.

FrankLA hat recht, das Durchreichen von Timern funktioniert so nicht.
Ich habe das eben erst ausprobiert, da ich bislang noch nicht in die Verlegenheit gekommen bin sowas machen zu wollen.:icon_rolleyes:

Edit:
Wenn man Timer in mehrfach aufzurufenden Bausteinen verwenden will ist es besser mit FB´s zu arbeiten und die IEC-Timer SFB 4 bzw. SFB 5 als Multiinstanzen zu verwenden. Damit erspart man sich auch die Timer von "außen" dranlegen zu müssen.
 
Zuletzt bearbeitet:
Ihr habt mein Problem richtig erkannt.
Ich bin allerdings kein Profi im SPS-programmieren und hab bisher noch nie mit FBs gearbeitet. könnt ihr mir grob erklären was für eine Funktion die SFBs 4 und 5 hab und wie man Timer selber programmiert?
 
ich hab ein Problem mit einem FC, den ich programmiert hab.
Der FC soll in einem anderen FC aufgerufen werden.
Ich hab alle Timer, Merker und Zähler in dem Baustein Symbolisch adressiert. wenn ich sie in dem zweiten FC, der später auch mehrmals aufgerufen werden soll wieder symbolisch adressieren will funktioniert das nicht.

Ich hab die Timer in beiden FCs als als EIngangsvariable deklareiert. und den Datentyp TIMER gewählt.

Es ist durchaus möglich, in einer Funktion FC100 eine IN-Variable vom Datentyp TIMER an eine weitere Funktion FC110 zu übergeben.

Hier ist mal ein kurzes Programmbeispiel:

Code:
ORGANIZATION_BLOCK OB 1
TITLE =Hauptprogramm
//18
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : 'TIMER'
VERSION : 1.0
 
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 =Timer
 
      U     E     10.0; 
      =     L     20.0; 
      BLD   103; 
      CALL FC   100 (
           IN_TIMER_EINGANG         := L     20.0,
           IN_TIMER_NUMMER          := T    100,
           IN_TIMER_WERT            := S5T#10S,
           OUT_TIMER_WERT           := MW   100,
           OUT_TIMER_AUSGANG        := A     10.0);
      NOP   0; 
 
NETWORK
TITLE =Timer
 
      U     E     10.1; 
      =     L     20.0; 
      BLD   103; 
      CALL FC   100 (
           IN_TIMER_EINGANG         := L     20.0,
           IN_TIMER_NUMMER          := T    120,
           IN_TIMER_WERT            := S5T#10S,
           OUT_TIMER_WERT           := MW   120,
           OUT_TIMER_AUSGANG        := A     10.1);
      NOP   0; 
 
END_ORGANIZATION_BLOCK

Code:
FUNCTION FC 100 : VOID
TITLE =Timer
//18
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : 'TIMER'
VERSION : 1.0
 
VAR_INPUT
  IN_TIMER_EINGANG : BOOL ; 
  IN_TIMER_NUMMER : TIMER ; 
  IN_TIMER_WERT : S5TIME ;  
END_VAR
VAR_OUTPUT
  OUT_TIMER_WERT : S5TIME ; 
  OUT_TIMER_AUSGANG : BOOL ;    
END_VAR
VAR_TEMP
  TEMP_TIMER_NUMMER : WORD ;    
END_VAR
BEGIN
NETWORK
TITLE =Timer-Nummer
 
      L     P##IN_TIMER_NUMMER; 
      SRD   16; 
      T     #TEMP_TIMER_NUMMER; 
 
NETWORK
TITLE =Timer
 
      U     #IN_TIMER_EINGANG; 
      =     L      2.0; 
      BLD   103; 
      CALL FC   110 (
           IN_TIMER_EINGANG         := L      2.0,
           IN_TIMER_NUMMER          := #TEMP_TIMER_NUMMER,
           IN_TIMER_WERT            := #IN_TIMER_WERT,
           OUT_TIMER_WERT           := #OUT_TIMER_WERT,
           OUT_TIMER_AUSGANG        := #OUT_TIMER_AUSGANG);
      NOP   0; 
 
END_FUNCTION

Code:
FUNCTION FC 110 : VOID
TITLE =Timer
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : 'TIMER'
VERSION : 1.0
 
VAR_INPUT
  IN_TIMER_EINGANG : BOOL ; 
  IN_TIMER_NUMMER : WORD ;  
  IN_TIMER_WERT : S5TIME ;  
END_VAR
VAR_OUTPUT
  OUT_TIMER_WERT : S5TIME ; 
  OUT_TIMER_AUSGANG : BOOL ;    
END_VAR
VAR_TEMP
  TEMP_TIMER_NUMMER : WORD ;    
END_VAR
BEGIN
NETWORK
TITLE =Timer
 
      L     #IN_TIMER_NUMMER; 
      T     #TEMP_TIMER_NUMMER; 
 
      U     #IN_TIMER_EINGANG; 
      L     #IN_TIMER_WERT; 
      SE    T [#TEMP_TIMER_NUMMER]; 
      LC    T [#TEMP_TIMER_NUMMER]; 
      T     #OUT_TIMER_WERT; 
      U     T [#TEMP_TIMER_NUMMER]; 
      =     #OUT_TIMER_AUSGANG;
 
END_FUNCTION

Gruß Kai
 

Anhänge

  • OB1.pdf
    3,7 KB · Aufrufe: 17
  • FC100.pdf
    3,2 KB · Aufrufe: 22
  • FC110.pdf
    2,7 KB · Aufrufe: 22
  • FC100 ONLINE HEX.jpg
    FC100 ONLINE HEX.jpg
    299,6 KB · Aufrufe: 33
  • Timer.zip
    30,9 KB · Aufrufe: 7
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Programmcode wird noch etwas einfacher, wenn man in der Funktion FC100 für die Nummer des TIMERS eine IN-Variable vom Datentyp INT an die Funktion FC110 übergibt. In der Funktion FC110 wird dann der TIMER mit der übergebenen Nummer indirekt aufgerufen.

Code:
ORGANIZATION_BLOCK OB 1
TITLE =Hauptprogramm
//18
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : 'TIMER'
VERSION : 1.0
 
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 =Timer
 
      U     E     10.0; 
      =     L     20.0; 
      BLD   103; 
      CALL FC   100 (
           IN_TIMER_EINGANG         := L     20.0,
           IN_TIMER_NUMMER          := 100,
           IN_TIMER_WERT            := S5T#10S,
           OUT_TIMER_WERT           := MW   100,
           OUT_TIMER_AUSGANG        := A     10.0);
      NOP   0; 
 
NETWORK
TITLE =Timer
 
      U     E     10.1; 
      =     L     20.0; 
      BLD   103; 
      CALL FC   100 (
           IN_TIMER_EINGANG         := L     20.0,
           IN_TIMER_NUMMER          := 120,
           IN_TIMER_WERT            := S5T#10S,
           OUT_TIMER_WERT           := MW   120,
           OUT_TIMER_AUSGANG        := A     10.1);
      NOP   0; 
 
END_ORGANIZATION_BLOCK

Code:
FUNCTION FC 100 : VOID
TITLE =Timer
//18
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : 'TIMER'
VERSION : 1.0
 
VAR_INPUT
  IN_TIMER_EINGANG : BOOL ; 
  IN_TIMER_NUMMER : INT ;   
  IN_TIMER_WERT : S5TIME ;  
END_VAR
VAR_OUTPUT
  OUT_TIMER_WERT : S5TIME ; 
  OUT_TIMER_AUSGANG : BOOL ;    
END_VAR
BEGIN
NETWORK
TITLE =Timer
 
      U     #IN_TIMER_EINGANG; 
      =     L      0.0; 
      BLD   103; 
      CALL FC   110 (
           IN_TIMER_EINGANG         := L      0.0,
           IN_TIMER_NUMMER          := #IN_TIMER_NUMMER,
           IN_TIMER_WERT            := #IN_TIMER_WERT,
           OUT_TIMER_WERT           := #OUT_TIMER_WERT,
           OUT_TIMER_AUSGANG        := #OUT_TIMER_AUSGANG);
      NOP   0; 
 
END_FUNCTION

Code:
FUNCTION FC 110 : VOID
TITLE =Timer
AUTHOR : KAI
FAMILY : SPSFORUM
NAME : 'TIMER'
VERSION : 1.0
 
VAR_INPUT
  IN_TIMER_EINGANG : BOOL ; 
  IN_TIMER_NUMMER : INT ;   
  IN_TIMER_WERT : S5TIME ;  
END_VAR
VAR_OUTPUT
  OUT_TIMER_WERT : S5TIME ; 
  OUT_TIMER_AUSGANG : BOOL ;    
END_VAR
VAR_TEMP
  TEMP_TIMER_NUMMER : WORD ;    
END_VAR
BEGIN
NETWORK
TITLE =Timer
 
      L     #IN_TIMER_NUMMER; 
      T     #TEMP_TIMER_NUMMER;
 
      U     #IN_TIMER_EINGANG; 
      L     #IN_TIMER_WERT; 
      SE    T [#TEMP_TIMER_NUMMER]; 
      LC    T [#TEMP_TIMER_NUMMER]; 
      T     #OUT_TIMER_WERT; 
      U     T [#TEMP_TIMER_NUMMER]; 
      =     #OUT_TIMER_AUSGANG; 
 
END_FUNCTION

Gruß Kai
 

Anhänge

  • OB1 NEU.pdf
    3,7 KB · Aufrufe: 11
  • FC100 NEU.pdf
    3,1 KB · Aufrufe: 10
  • FC110 NEU.pdf
    2,7 KB · Aufrufe: 10
  • Timer_ne.zip
    31,3 KB · Aufrufe: 8
@OHGN
ich habe ja auch nur gesagt, dass ich das problem so verstehe, nicht, dass es (meinem momentanen wissensstand nach) funktioniert ;)


ich glaube, es wäre noch wichtig zu wissen, ob hier immer nur ein timer auf einmal läuft oder ob hier mehrere zeiten parallel laufen sollen.
 
Zuletzt bearbeitet:
Ich hab inzwischen mal versucht die Funktion in einem FB mit Multiinstanzen zu schreiben. Allerdings ist das ja wie gesagt Neuland für mich.
Dabei ist das Problem aufgetaucht, wenn ich das Programm mit PLCSim teste schalten die Zeitglieder sofort durch. Ich hab die Zeiten als Datentyp Time am Eingang PT eingegebn, war das Falsch, oder woran könnte das sonst noch liegen?
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja, Datentyp Time am Eingang PT ist richtig.
Und Du musst natürlich jedem Timeraufruf eine eigene Instanz zuweisen, dann sollte es eigentlich funktionieren.
 
Vorsicht mit dem PLC-Sim und dem TON-Baustein.
Da gibt es bis zu einer bestimmten Version von PLC-Sim gerade
eben diesen Fehler, das der TON-FB sofort durchschaltet.
Von Siemens gibts dazu einen Hotfix.
 
Hallo,

ich bin mit einem Kollegen zusammen auf das gleiche Problem gestoßen. Die Lösung: anstatt einen DB direkt im FB zu definieren, kann man eine Schnittstelle benutzen. Das funktioniert auch bei mehreren IEC Timern im gleichen FB. Was danach passiert: fügt man den FB in den OB der Wahl ein, wird ein neuer DB generiert, welcher die Daten der Timer beinhaltet. Falls ein Zeitwert oder etwas ähnliches benötigt, kann dieser Wert direkt aus dem jeweiligen DB bezogen werden.

Mfg zingarra
 
Zurück
Oben