TIA IEC-Timer in mehreren FB instanzen

Smicon

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

Folgendes Szenario:
Ich programmiere mit Step 7 v13.0+Sp1. Ich habe mir in SCL eine Statemachine geschrieben in der es auch einen Timeout gibt. Dafür habe ich einen IEC-Timer als TON benutzt. Der Speicher für den Timer wird im Instanz-DB des FBs im statischen Bereich angelegt.

Nun zu meinem Problem:

Ich rufe in meiner Funktion bei mir die Main(OB1) zwei Instanzen der State-Machine auf. Beide Statemachine haben ihren eigenen Instanz-DB. Trotzdem sind die Timer global voneinander abhängig. Also wir der Timer in der einen Instanz aktiv wird er das in der 2. automatisch auch.

Ich fände es sehr praktisch wenn ich einen Timer in meinen Instanz-DB integrieren könnte, der nur zu dieser Instanz gehört.

Ich sitze jetzt 2 Wochen an dir TIA Welt. Währe nett, wenn mir jemand helfen könnte. Danke im Vorraus
 
Ich rufe in meiner Funktion bei mir die Main(OB1) zwei Instanzen der State-Machine auf. Beide Statemachine haben ihren eigenen Instanz-DB. Trotzdem sind die Timer global voneinander abhängig. Also wir der Timer in der einen Instanz aktiv wird er das in der 2. automatisch auch.
Da hat sich dann aber irgendein Fehler eingeschlichen.
Woran merkst du dieses Verhalten denn? Zeig und doch mal den Aufruf der 2 Instanzen und vielleicht ein wenig Code der Statemachine.

Ich fände es sehr praktisch wenn ich einen Timer in meinen Instanz-DB integrieren könnte, der nur zu dieser Instanz gehört.
Wenn alles korrekt ist, dann sollte dass auch so sein.
 
Erst mal danke für die schnellen Antworten. Wenn ich von einer Instanz den Timer Starte und ich parallel beide Instanz DBs live anschaue sehe ich, dass der Timer in beiden läuft. Beide Instanzen haben natürlich auch ihren eigenen Baustein.

Hier der Programmcode:
Code:
FUNCTION_BLOCK "SK_State_Machine_Camera"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
VAR_INPUT 
                        Request : Bool;
                       Busy : Bool;
                       IO : Bool;
                       NIO : Bool;
                       Reset : Bool;
   END_VAR

   VAR_OUTPUT 
              Out_Request : Bool;
                Out_IO : Bool;
                Out_NIO : Bool;
                Out_Error : Bool;
          Current_State : Int;
   END_VAR

   VAR 
            state : Int;
            timeout_active : Bool;
            IEC_Timer_0_Instance {OriginalPartName := 'TON'; LibVersion := '1.0'} : TON;
   END_VAR

   VAR_TEMP 
            Starting_Timeout : Bool;
            Test : Bool;
   END_VAR

   VAR CONSTANT 
            waiting_for_request : Int;
            send_request : Int := 1;
            camera_busy : Int := 2;
            timeout : Int := 3;
            camera_ready : Int := 4;
            Time_Timeout : Time := T#10S;
   END_VAR


BEGIN
    
    //....................INIT......................................................................
    IF #Reset THEN
            #state := #waiting_for_request;
            #Starting_Timeout := false;
            #Out_Error := false;      
            #Out_IO := false;
            #Out_NIO := false;
             #Out_Request := false;
    END_IF;
    
    //...............................................................................................
    //
    CASE #state OF
            //Step1.................................................................................    
              #waiting_for_request:
            
                        IF #Request THEN
                                  #state := #send_request;  
                                  #Out_Request := true;   // Writing Request
                                  #Out_IO := false;       // take back old result
                                  #Out_NIO := false;      // take back old result
                
                        END_IF;
            //Step2..................................................................................... 
              #send_request:
                        #Starting_Timeout := TRUE;
                        IF #Busy THEN
                                  #state := #camera_busy;
                                  #Starting_Timeout := false;
                        END_IF;
            //Step3.....................................................................................     
               #camera_busy:
                        #Starting_Timeout := true;
                        IF NOT #Busy THEN
                                  #state := #camera_ready;
                                  #Starting_Timeout := FALSE;
                        END_IF;
            //Step4.....................................................................................     
        #camera_ready:
            #Starting_Timeout := true;
            IF #IO THEN
                #state := #waiting_for_request;
                #Out_IO := true;                //send new result
                #Starting_Timeout := false;
            END_IF;
            
            IF #NIO THEN
                #state := #waiting_for_request;
                #Out_NIO := true;               //send new result
                #Starting_Timeout := false;
            END_IF;
            //step_Timeout.....................................................................................     
        #timeout:
            #Out_Error := true;
            //..........................................................................................     
            // ELSE  // Do nothing
            //..........................................................................................     
    END_CASE;
    
    IF #timeout_active THEN
      #state := #timeout;
    END_IF;
    
    #IEC_Timer_0_Instance(IN := #Starting_Timeout, //#Starting_Timeout
                          PT := #Time_Timeout,
                          Q => #timeout_active
                          );
    
    
    #Current_State := #state;
    
    
        
END_FUNCTION_BLOCK
 
Zuletzt bearbeitet:
Hmm.. auf die Schnelle sehe ich nichts am Timeraufruf. Wie sieht der FB-Aufruf der beiden Instanzen aus?
Schon mal versucht den Aufruf einer der Instanzen zu deaktivieren.
Die Bedingung "StartTimeout" wird ja recht häufig gesetzt. Nicht dass da was Anderes beim Testen reinspielt und
in beiden FBs eine der Bedingungen erfüllt wird.

Bearbeite doch bitte noch mal deinen vorigen Beitrag.
Pack einfach nochmal den Code aus der Quelle in die [ CODE] [ /CODE] - Klammen (Ohne Leerzeichen).
Oder verwende das #-Zeichen in der Menüleiste.
Dann kann man den Code besser lesen. Sieht z.B. so aus:
Code:
IF #NIO THEN
    #state := #waiting_for_request;
    #Out_NIO := true; //send new result
    #Starting_Timeout := false;
END_IF;
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe mir deinen Programmcode nicht ganz nachverfolgt.
Aber:
die Variable #Starting_Timeout ist eine Temp-Variable
und
die Variable #Starting_Timeout wird immer nur bedingt gesetzt.

In SPS-Zyklen, in welchen keine Bedingung erfüllt ist, enthällt die Variable der zweiten Instanz mit hoher Warscheinlichkeit den Inhalt der ersten Instanz (identische Stack-Adresse)!!

Deklariere mal #Starting_Timeout als Statische Variable !
 
Zuletzt bearbeitet:
Jaaaa, die Temp-Variable war das Problem. Jetzt funktioniertes ;). Entschuldigt noch mal wegen dem schlecht lesbaren Code. Ich hab mein bestes versucht konnte aber mit [ CODE] [ /CODE] nichts erreichen. Anders ausgedrückt ich hab nicht wirklich verstanden wie ich den Code ändern sollte, dass er ihn hier im Forum strukturiert anzeigt.
 
Ich hab mein bestes versucht konnte aber mit [ CODE] [ /CODE] nichts erreichen.

Damit ich die Code-Klammen nicht automatisch ersetzt werden hab ich ein Leerzeichen eingefügt, so wie ich jetzt ein "x" eingefügt habe.
[x/CODE]

[CODE]
Dann kommt dein Code
[/CODE]

Es gibt im Beitragseditor in der Symbolleiste auch ein #-Zeichen. Das fügt auch die Code-Tags ein.
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Damit ich die Code-Klammen nicht automatisch ersetzt werden hab ich ein Leerzeichen eingefügt, so wie ich jetzt ein "x" eingefügt habe.
Damit das nicht passiert, kannst Du mit den noparse-Tags arbeiten. Den Tip hat PN/DP neulich gegeben.

Guckst Du:
[code] ... [/code]
 
Am Ende hab ichs doch gerafft. Mich wundert nur das der Compiler die Variablen über einen Haufen wirft. Normalerweise wird bei einem Funktionsaufruf die Variablen neu im Speicher angelegt und beim Verlassen gelöscht. Auf den Stack werden die Variablen nur geschoben, wenn ich in der Funktion wieder eine andere öffne. Beim Verlassen des Funktonsaufrufes in der Funktion wird diese dann wieder vom Stack gepoppt. Wieso kommen sich die temporären Variablen in die Quäre? Vielleicht kann jemand ein Beispiel machen.
 
Zuletzt bearbeitet:
TEMP-Variablen werden im von allen Programmbausteinen gemeinsam genutzten Stack angelegt. Der Inhalt des Speicherplatzes wird jedoch NICHT extra gelöscht! Weder beim Funktionsaufruf noch beim Beenden. So kommt es, daß da noch Werte vom vorherigen Nutzer des Speicherplatzes drinstehen, solange bis man selbst was reinschreibt ("initialisiert"). Man darf den TEMP-Speicherplatz nicht zum Merken von Werten bis zum nächsten Durchlauf benutzen, weil nach Ende des Programmbausteins der Stack zur Nutzung für andere Programmbausteine freigegeben wird und man nicht wissen kann, wer was mit dem Speicherplatz anstellt. Man KANN Glück haben, daß der eigene Wert da noch drinsteht, wenn man der Baustein mit dem höchsten Stackbedarf ist.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Der Inhalt des Speicherplatzes wird jedoch NICHT extra gelöscht! Weder beim Funktionsaufruf noch beim Beenden.
Hier scheint sich mit TIA und den neuen CPUs auch was geändert zu haben. Hab's aber noch nie selbst beobachtet.

http://support.automation.siemens.com/CH/view/de/78668321

Im Endeffekt gilt das aber wieder nur für optimierte Bausteine ohne Arrays im Temp. Also wieder ein paar Ausnahmen.
Fazit: Immer mit selbst initialisierten Temps arbeiten. Gehört einfach zum guten Ton.;)
 
Auf solche spezial-Sachen, welche Siemens extra für ungebildete "Programmierer" in TIA einbaut, werde ich mich sicherheitshalber nie verlassen. Dem TE hat's auch nicht geholfen. Ich kann mir einfacher merken "TEMP-Variablen = Inhalt unbestimmt" als die vielen Spezialfälle, welche manchmal gehen und auch nur bei manchen CPU bei manchen Firmware-Versionen...

Harald
 
Stimme ich vollkommen zu, hab mich ebenso gewundert als ich auf den Blödsinn gestoßen bin.
*ACK*
 
Zurück
Oben