Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 9 von 9

Thema: SCL-Konvertierung von Classic nach TIA mit TON / WRREC / RDREC

  1. #1
    Registriert seit
    16.10.2012
    Beiträge
    743
    Danke
    51
    Erhielt 36 Danke für 29 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Moin zusammen.

    Frage: beim Versuch, ein absolut funktionsfähiges Projekt von Classic nach TIA zu migrieren, was ausschließlich in SCL verfasst ist, und wo alle Quellen vorhanden sind, erscheinen Fehlermeldungen, die etwas mit dem Aufruf von SFBs 53, 54 und TON zu tun hat. Im Original wurden z.B. beim Timer nicht im jeden Aufruf alle Variablen versorgt. TIA meckert darüber.

    Mir scheint, als gebe es diskrepanzen bei dem Originalprojekt und bei dem migrierten Projekt hinsichtlich des Aufrufes von "TON" als lokale Instanz und als Einzelinstanz (s. 417 im Berger-Buch).
    Desweiteren werden im Projekt ja wie bereits erwähnt, die WRREC und RDREC genutzt. Allerdings unterscheidet sich deren Schnittstelle und Verwendung von Classic zu TIA ja erheblich. Im klassischen musste ich die E/A-Adressen der Subslots übergeben, während TIA ja mit sogenannter "Hardwarekennung", und zwar intern vergeben arbeitet. Diese unterscheidet sich in der Regel von den E/A Adressen. Es gibt ja jetzt sogar speziellen Datentyp für diese "Hardwarekennung". Inwieweit müsste ich hier von Hand also tätig werden, um das Projekt wieder lauffähig zu machen ?
    Zitieren Zitieren SCL-Konvertierung von Classic nach TIA mit TON / WRREC / RDREC  

  2. #2
    Avatar von Draco Malfoy
    Draco Malfoy ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    16.10.2012
    Beiträge
    743
    Danke
    51
    Erhielt 36 Danke für 29 Beiträge

    Standard

    Also ich wiederhole die Frage mit einem konkreten Beispiel. Wie muss ich hier vorgehen, damit mein Code wieder funktioniert und TIA nicht mehr meckert ?
    Ich habe neuerdings das hier gelesen, denke das hat damit unmittelbar zu tun:
    Bausteinaufrufe in S7-SCL-Quellen
    In den S7-SCL-Quellen bei STEP 7 V5.x konnten Sie die Bausteinparameter vor oder nach dem eigentlichen Aufruf des Bausteins setzen. Das heißt, der Baustein konnte mit unvollständigen Parametern aufgerufen und die In/Out-Parameter der Bausteine an einer anderen Stelle innerhalb der S7-SCL-Quelle mit Variablen oder Werten versorgt werden. Diese Art der Programmierung ist in STEP 7 (TIA Portal) systembedingt nicht möglich und wird auch in Zukunft nicht unterstützt. Sie können das STEP 7 V5.x Projekt zwar in TIA Portal fehlerfrei migrieren und übersetzen, doch ist die Funktion dieses Bausteinaufrufes innerhalb des S7-SCL-Programmes nicht mehr möglich. Bevor Sie Ihre S7-SCL-Quelle in STEP 7 V5.x übersetzen und das Projekt in TIA Portal migrieren, beachten Sie die folgenden Punkte:
    • Alle Parameter des aufgerufenen Bausteins müssen innerhalb der Aufrufanweisung versorgt werden.
    • Es dürfen keine Parameter des aufgerufenen Bausteins gelöscht und an einer anderer Stelle der S7-SCL-Quelle eingefügt und parametriert werden.
    Code:
                    #ISTATE_START:
                            (* reset timer *)
                            #timeout(IN:= FALSE);
                            (* start timer *)
                            #timeout(IN:= TRUE, PT:= #TIMEOUT_60_SECONDS);
                            
                            (* first check PDU size *)
                            #BUF_MAX:= 240;
                            #BUF_MAXDATA:= #BUF_MAX - #BUF_HEADER;
                            #pdu_detection:= TRUE;
                            
                            #state:= #ISTATE_SET_INIT;
                            
                    #ISTATE_SET_INIT:
                            IF #init_active = TRUE THEN
                                    (* initialize some variables *)
                                    #old_CC_H:= FALSE;
                                    #old_CC_L:= FALSE;
                                    #req:= TRUE;
                                    
                                    (* remember AC_H/AC_L *)
                                    #old_AC_H:= #AC_H;
                                    #old_AC_L:= #AC_L;
                                    
                                    (* drop INIT *)
                                    #INIT_cyc:= FALSE;
                                    
                                    (* and wait until init_active is dropped *)
                                    #state:= #ISTATE_INIT_ACTIVE;
                            ELSE
                                    (* check for timeout *)
                                    #timeout();
                                    IF #timeout.Q = TRUE THEN
                                            #state:= #ISTATE_ERROR;

  3. #3
    Registriert seit
    27.05.2004
    Ort
    Thüringen/Berlin
    Beiträge
    12.227
    Danke
    534
    Erhielt 2.698 Danke für 1.950 Beiträge

    Standard

    Na ja, ich fand diese Art des Aufrufs, die du da gepflegt hast schon immer ein wenig abenteuerlich, da recht unübersichtlich, aber das darf jeder für sich entscheiden.
    Ich denke, du hast zwei Möglichkeiten:

    1. Alle Timeout-Aufrufe vollständig machen und mit Zwischenvariablen versorgen. Diese Zwischenvariablen kannst du dann ruhig an den "alten Stellen" befüllen.
    Risiko: Falsche Werte für den Timeout; Code, in dem Timeout aufgerufen wird, wird zu früh verlassen, so dass du bei einem weiteren Aufruf keine Flanke erkennst (Das hattest du ja früher schon, daher der Timeout-Aufruf mit "IN := False".

    2. Nur ein Timeout-Aufruf, der auch immer bearbeitet, also nie umsprungen wird, dieser mit Variablen versorgt.

    #timeout(IN:= #TimeoutStart, PT:= #TIMEOUT_SECONDS);


    Die Variablen werden im Code belegt, Dann startet der Timer, wenn #TimeoutStart --> True wird.

    Das Ergebnis kannst du immer noch überall abfragen (300-er im TIA) mit

    IF #timeout.Q THEN

    END_IF;

    Du kannst natürlich auch #Timout.Q auf eine Variable schreiben und dann damit arbeiten.

    Auch hier ein Problem: Benötigst du #timeout exakt zweimal hintereinander hast du auch hier ein Problem mit der Flanke. Entweder du hast dann einen Zwischenschritt, in dem TimoutStart = False erkannt werden kann oder, wenn das nicht geht, dann nutzt du 2 TimoutTimer abwechselnd.
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

  4. #4
    Registriert seit
    24.04.2013
    Beiträge
    309
    Danke
    23
    Erhielt 160 Danke für 88 Beiträge

    Standard

    Hi

    einen Timer mehrfach im Programm zu verwenden war schon immer sehr problematisch.
    Und dann auch noch um die Timer Befehle herum zu springen sorgt dafür, dass außer dir erstmal jeder 10 min braucht um alle Pfade zu analysieren.

    Es sollt immer genau eine Stelle geben in der der Timer kontrolliert wird. Es mag viele Stellen geben, an der man den Timer fragt ob er abgelaufen ist, aber bitte nur an einer Stelle starten und stoppen (falls) nötig.

    Bei der 300/400 hat man auch noch ein Problem, wenn der SFB nicht aufgerufen wird, denn dann läuft auch die Zeit nicht ab, d.h. es nutzt nix wenn du auf #timer.Q zugreift ohne auch #timer(...) zu durchlaufen. Denn nur im SFB Aufruf, findet eine Zeitmessung statt. Danach steht er wieder.
    Bei der 1200/1500 ist das anders, da läuft die Zeit auch wenn du #timer() nicht mehr aufrufst. Hier wird auch beim Zugriff mit #timer.Q oder #timer.ET gemessen. Der #timer wird bei der 1200/1500 nicht durch einen SFB implementiert. Deswegen muss dort auch PT versorgt werden.

    Vermutlich unterscheidet der Editor aber nicht zwischen 300/400 und 1200/1500 und verlangt jetzt immer die PT Versorgung -- soll man das als Fehler werten?
    Unversorgte Parameter an FB waren aber immer schon Quell vieler Fehler die ich suchen durfte.

    Deswegen: Schreib wie Ralle vorschlägt den Timer vor den Switch-Case, so dass dieser immer aufgerufen wird.
    Alles andere, die Zeit auswählen und das Start-Flag setzten, darf in deinem Zustandsautomaten bleiben. Und wenn du den Timer mehrfach brauchst, dann immer über Zwischenschritt.
    Ich würde das als gute Praxis bezeichnen, spart sehr viel Zeit bei der Fehlersuche!

    'n schön' Tag auch
    HB


    oh Gott, was machen denn diese Holländer?

  5. #5
    Avatar von Draco Malfoy
    Draco Malfoy ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    16.10.2012
    Beiträge
    743
    Danke
    51
    Erhielt 36 Danke für 29 Beiträge

    Standard

    Moin. Vielen Dank schon ma für die gründlichen Erklärungen.
    Ich habe den Code leider nicht selber geschrieben, sonst würde ich vermutlich einiges mehr wissen was und wie dort zu funktionieren hat. Um mal auf der sicheren Seite zu gehen, ich habe jetzt den Timer "nach Außen" verlegt und versorge ihn erst mal außerhalb von den CAS und IF..THEN Anweisungen mit leeren Variablen, die innerhalb der Schleife beschrieben und abgefragt werden. Ist es einigermaßen korrekt so ? Was muss ich noch befürchten ?
    An anderen Stellen wird der Timer nicht beschrieben, sondern nur abgefragt mittels IF #timeout.Q = TRUE THEN.

    Code:
    Ganz zu Anfang:
    
    #timeout(IN := #TimeOut_Start, PT := #timeout_Seconds);   //Ab hier Code von Draco Malfoy 
                                
    <..dann irgendwann im Code...>
    
                    (* substate machine -initialization- *)
                    #ISTATE_START:
                            (* reset timer *)
                        #TimeOut_Start:= FALSE;
                            (* start timer *)
                        #TimeOut_Start := TRUE;
                        #timeout_Seconds := #TIMEOUT_60_SECONDS;
                            
                            (* first check PDU size *)
                            #BUF_MAX:= 240;
                            #BUF_MAXDATA:= #BUF_MAX - #BUF_HEADER;
                            #pdu_detection:= TRUE;
                            
                            #state:= #ISTATE_SET_INIT;
                            
                    #ISTATE_SET_INIT:
                            IF #init_active = TRUE THEN
                                    (* initialize some variables *)
                                    #old_CC_H:= FALSE;
                                    #old_CC_L:= FALSE;
                                    #req:= TRUE;
                                    
                                    (* remember AC_H/AC_L *)
                                    #old_AC_H:= #AC_H;
                                    #old_AC_L:= #AC_L;
                                    
                                    (* drop INIT *)
                                    #INIT_cyc:= FALSE;
                                    
                                    (* and wait until init_active is dropped *)
                                    #state:= #ISTATE_INIT_ACTIVE;
                            ELSE
                                    (* check for timeout *)
                                   // #timeout(); -->> Aufruf nicht mehr benötigt ??
                                    IF #timeout.Q = TRUE THEN // Kann man so lassen ??
                                            #state:= #ISTATE_ERROR;
    An anderer Stelle meckert wiederholt mein Compiler, daß eine Variable angeblich "möglicherweise nicht initialisiert wird". Was soll ich damit tun, sie im Anlauf null setzen ?
    Meint der Compiler hier, daß ich sie abfrage, bevor ich sie beschrieben habe ? Mir ist nicht verständich der Grund dieser Warnung, es kann ja sein daß die Variable im vorherigen Zyklus in einer IF oder CASE Anweisung beschrieben wurde.
    Geändert von Draco Malfoy (13.07.2014 um 14:48 Uhr)

  6. #6
    Registriert seit
    27.06.2009
    Ort
    am Nordharz
    Beiträge
    3.717
    Danke
    443
    Erhielt 920 Danke für 740 Beiträge

    Standard

    Zitat Zitat von Draco Malfoy Beitrag anzeigen
    Code:
    IF #timeout.Q = TRUE THEN





  7. #7
    Avatar von Draco Malfoy
    Draco Malfoy ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    16.10.2012
    Beiträge
    743
    Danke
    51
    Erhielt 36 Danke für 29 Beiträge

    Standard

    Zitat Zitat von hucki Beitrag anzeigen
    Ja nun, so stehts im Originalcode, ich hab es nicht geschrieben!
    Möglicherweise hat der Programmierer aus Lesbarkeitsgründen das in der Form "IF #timeout.Q = TRUE THEN" gemacht anstatt "IF #timeout.Q THEN".

  8. #8
    Registriert seit
    27.05.2004
    Ort
    Thüringen/Berlin
    Beiträge
    12.227
    Danke
    534
    Erhielt 2.698 Danke für 1.950 Beiträge

    Standard

    Ich denke mal, das geht schon, hat halt jeder so seine Vorlieben.
    Abfragen kann man den Timer offensichtlich überall, dass läßt Siemens zu. Insofern kannst du, wie ich schon schrieb, entweder #timeout.Q abfragen oder direkt hinter den Aufruf von Timeout #timeout_output := #timeout.Q schreiben.

    PS: Lt. HelleBarde läuft ja so eine Timer bei einer 1200/1500-er weiter, also verhält er sich dort so wie die Hardwaretimer der 300-er. Das heißt, ein Timer kann jederzeit im Zyklus ablaufen. Fragst du ihn in einem Zyklus an 2 Stellen im Code ab, kann er einmal False und ein anderes Mal True sein, was zu Problemen führen kann. Mit der Zuweisung an eine Variable direkt nach dem Aufruf passiert das nicht, die Variable #timeout_output wird sich nur einmal im Zyklus ändern können, genau dann, wenn sie zugewiesen wird!
    Gruß
    Ralle

    ... there\'re 10 kinds of people ... those who understand binaries and those who don\'t …
    and the third kinds of people … those who love TIA-Portal

  9. Folgender Benutzer sagt Danke zu Ralle für den nützlichen Beitrag:

    Draco Malfoy (13.07.2014)

  10. #9
    Avatar von Draco Malfoy
    Draco Malfoy ist offline Erfahrener Benutzer
    Themenstarter
    Registriert seit
    16.10.2012
    Beiträge
    743
    Danke
    51
    Erhielt 36 Danke für 29 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Ok alles klärchen
    Dann mache ich das besser so, wie von Ralle angeraten wurde.
    Diese Warnung mit der fehlenden Initialisierung, muss ich da noch tätig werden oder einfach ignorieren ?

Ähnliche Themen

  1. rdrec/wrrec
    Von Stephen im Forum Simatic
    Antworten: 4
    Letzter Beitrag: 17.07.2014, 17:42
  2. TIA Classic Projekt mit OP73 nach TIA V12 SP1 migrieren
    Von taylor1982 im Forum Simatic
    Antworten: 6
    Letzter Beitrag: 20.02.2014, 16:32
  3. Antworten: 1
    Letzter Beitrag: 18.12.2013, 10:05
  4. TIA Baustein Export von TIA nach S7 Classic
    Von SPSGreenhorn im Forum Simatic
    Antworten: 3
    Letzter Beitrag: 12.06.2013, 12:26
  5. TIA V11 SCL TON Multiinstanz
    Von MrEASY im Forum Simatic
    Antworten: 14
    Letzter Beitrag: 04.03.2013, 15:17

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •