TIA Bereichslängenfehler SCL

ThomasM

Level-1
Beiträge
114
Reaktionspunkte
9
Zuviel Werbung?
-> Hier kostenlos registrieren
Servus Leute,

wie mein Titel schon sagt bekomme ich einen Bereichslängenfehler in einem SCL Baustein. Ich kann mir leider nicht erklären woher dieser Fehler kommt.
Kurz zur Erklärung:
Der betroffene Baustein prüft einen erhaltenen Fahrauftrag auf plausibilität. Der Fehler taucht auch nicht bei jedem Fahrauftrag auf. Ich hoffe ihr habt vielleicht ne Idee was es sein könnte, oder könnt mir vielleicht helfen wie ich den Fehler diagnostizieren kann.

Hier der Auszug aus dem Diagnosepuffer der CPU

Code:
Diagnosepuffer der Baugruppe Kran1_3100 [CPU 1515F-2 PN]


Artikel-Nr. / Bezeichn.       Komponente                    Version
6ES7 515-2FM01-0AB0           Hardware                      3
- - -                         Firmware                      V 2.0.1
Firmware-Erweiterung          Firmware-Erweiterung          ---



103 von 523; Ereignis-ID: 16# 02:2522
Temporärer CPU-Fehler: Bereichslängenfehler in FB 11 
betrifft OB 1 Ausführung 
Lesezugriff Gepufferter DB-Bereich 
fehlerhafte Adresse, Operand ersetzt 
 
 Kran1_3100
interne Adressierungsdetails: Caddr=16#00000146, Bereich: Gepufferter DB-Bereich, Adr: 11357

Kommendes Ereignis
11.05.2017 17:11:08.305



Und hier der Quellcode des Bausteins, ich habe die Stelle rot markiert an die er mir springt wenn ich auf den Butten im Editor öffnen klicke.

Code:
FUNCTION_BLOCK "FB_Auftragspruefung_NEU"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      IN_Einlagern : Bool;   // Auftrag: Einlagern eines Stapels
      IN_Auslagern : Bool;   // Auftrag: Auslagern eines Stapels
      IN_Umlagern : Bool;   // Auftrag: Umlagern eines Stapels
      IN_Kantholz : Bool;   // Auftrag ist eine Kantholzbox
      IN_Reset : Bool;   // Zurücksetzen der Auftrag OK/nicht OK Merker
      IN_Quelle : String[4];   // Bezeichnung der Quelle
      IN_Ziel : String[4];   // Bezeichnung des Lagerorts
      IN_Aufnahmefoerd : String[4];   // Kennung des Aufnahmeförderers
      IN_Abgabefoerd : String[4];   // Kennung des Abgabeförderers
      IN_Kantholzfoerd : String[4];   // Kennung des Kantholzförderers
      IN_Reihe_Ein : Int;   // Nummer der Lagerreihe (Einlagern)
      IN_Tiefe_Ein : Int;   // Nummer der Lagertiefe (Einlagern)
      IN_Ebene_Ein : Int;   // Nummer der Lagerebene (Einlagern)
      IN_Hoehe_Ein : DInt;   // Physikalische Höhe (Einlagern)
      IN_Reihe_Aus : Int;   // Nummer der Lagerreihe (Auslagern)
      IN_Tiefe_Aus : Int;   // Nummer der Lagertiefe (Auslagern)
      IN_Ebene_Aus : Int;   // Nummer der Lagerebene (Auslagern)
      IN_Hoehe_Aus : DInt;   // Physikalische Höhe (Auslagern)
      IN_TE_Hoehe : Int;   // Höhe der TE aus Fahrauftrag
      IN_uGrenzw_Hoehe : DInt;   // Unterer Grenzwert für die Abweichung der Höhe des Fahrauftrags zur gespeicherten Höhe im Positions-DB
      IN_oGrenzw_Hoehe : DInt;   // Oberer Grenzwert für die Abweichung der Höhe des Fahrauftrags zur gespeicherten Höhe im Positions-DB
   END_VAR

   VAR_OUTPUT 
      OUT_Auftrag_OK : Bool;   // Auftrag plausibel
      OUT_Auftrag_nOK : Bool;   // Auftrag nicht ausführbar
      OUT_Platz_belegt : Bool;   // Einlagern / Umlagern: Ziel belegt
      OUT_Platz_frei : Bool;   // Auslagern: Platz frei
   END_VAR

   VAR 
      STAT_nAusfuehrbar : Bool;   // Auftrag nicht ausführbar
      STAT_Platz_belegt : Bool;   // Einlagern / Umlagern: Ziel belegt
      STAT_Platz_frei : Bool;   // Auslagern: Platz frei
   END_VAR

   VAR_TEMP 
      TMP_Hoehe_Rest_Aus : DInt;   // Resthöhe Auslagern (Höhe Positions-DB - Höhe Fahrauftrag)
      TMP_Hoehe_Rest_Ein : DInt;   // Resthöhe Einlagern (Höhe Positions-DB - Höhe Fahrauftrag)
   END_VAR


BEGIN
    (*
    Prüfung ob erhaltener Fahrauftrag plausibel
    
    Sprung zwischen Lagerabbild-DB und Positions-DB ist möglich, da sie den gleichen Aufbau haben
    Aufbau Positions-DB:    Reihe[1..9].Tiefe[1..19]
    Aufbau Lagerabbild-DB:  Reihe[1..9].Tiefe[1..19].Ebene[1..9]
    *)
    //==========================================================================================================================================================================================
    //                      Prüfen ob Koordinaten des Fahrauftrags im Lagerabbild vorhanden sind
    //==========================================================================================================================================================================================
                                                                                                                                        // Kommentar zu den Codezeilen
                                                                                                                                        // =====================================================
    IF (#IN_Reihe_Ein > 9) OR (#IN_Reihe_Aus > 9) OR                                                                                    // Abfrage ob Reihe größer 9
        (#IN_Tiefe_Ein > 19) OR (#IN_Tiefe_Aus > 19) OR                                                                                 // Abfrage ob Tiefe größer 19
        (#IN_Ebene_Ein > 9) OR (#IN_Ebene_Aus > 9) THEN                                                                                 // Abfrage ob Ebene größer 10
        #STAT_nAusfuehrbar := TRUE;                                                                                                     // Setzen Merker Auftrag nicht ausführbar
    END_IF;                                                                                                                             //
    //==========================================================================================================================================================================================
    //                      Auftragsprüfung wenn Koordinaten im Lagerabbild vorhanden sind
    //==========================================================================================================================================================================================
                                                                                                                                        // Kommentar zu den Codezeilen
                                                                                                                                        // =====================================================
    IF NOT #STAT_nAusfuehrbar AND #IN_Einlagern AND NOT (#IN_Ziel = #IN_Abgabefoerd OR #IN_Ziel = #IN_Kantholzfoerd) THEN               // Abfrage ob Ausführbar und Einlagern und Ziel nicht Abgabe- oder Kantholzförderer
        #TMP_Hoehe_Rest_Ein := ("DB_Positionen".Reihe[#IN_Reihe_Ein].Tiefe[#IN_Tiefe_Ein].Z - #IN_Hoehe_Ein);                           // Resthöhe Positions-DB - Fahrauftrag berechnen
        IF ("DB_Lagerabbild".Reihe[#IN_Reihe_Ein].Tiefe[#IN_Tiefe_Ein].Nicht_vorhanden) OR                                              // Abfrage ob Ziel physikalisch vorhanden
            (NOT #IN_Kantholz AND ((#IN_Reihe_Ein <= 2 AND #IN_Tiefe_Ein <= 3) OR #IN_Ziel = #IN_Kantholzfoerd OR #IN_Quelle = #IN_Kantholzfoerd)) OR                     // Abfrage ob Holzstapel auf Kantholzplatz soll
            ([COLOR=#ff0000]#IN_Kantholz[/COLOR] AND ((#IN_Reihe_Ein <= 2 AND #IN_Tiefe_Ein > 3))) OR                                                          // Abfrage ob Kantholzbox auf Holzstapelplatz soll
            (NOT "DB_Lagerabbild".Reihe[#IN_Reihe_Ein].Tiefe[#IN_Tiefe_Ein].Ebene[#IN_Ebene_Ein - 1].Belegt AND #IN_Ebene_Ein >2) THEN  // Abfrage ob der darunter liegende Platz frei ist
            #STAT_nAusfuehrbar := TRUE;                                                                                                 // Setzen Merker Auftrag nicht ausführbar
        ELSIF NOT #STAT_nAusfuehrbar AND "DB_Lagerabbild".Reihe[#IN_Reihe_Ein].Tiefe[#IN_Tiefe_Ein].Ebene[#IN_Ebene_Ein].Belegt OR      // Abfrage ob vorgegebenes Ziel belegt ist
            (#TMP_Hoehe_Rest_Ein > #IN_oGrenzw_Hoehe) OR                                                                                // Abfrage ob Physikalische Höhe außerhalb der Grenze liegt
            (#TMP_Hoehe_Rest_Ein < #IN_uGrenzw_Hoehe) THEN                                                                              // Abfrage ob Physikalische Höhe außerhalb der Grenze liegt
            #STAT_Platz_belegt := TRUE;                                                                                                 // Setzen Merker Platz belegt (Einlagern)
        ELSE                                                                                                                            //
            #OUT_Auftrag_OK := TRUE;                                                                                                    // Setzen Ausgang Auftrag OK (Einlagern)
        END_IF;                                                                                                                         //
    ELSIF NOT #STAT_nAusfuehrbar AND #IN_Auslagern THEN                                                                                 // Abfrage ob Ausführbar und Auslagern
        #TMP_Hoehe_Rest_Aus := ("DB_Positionen".Reihe[#IN_Reihe_Aus].Tiefe[#IN_Tiefe_Aus].Z - #IN_Hoehe_Aus - #IN_TE_Hoehe);            // Resthöhe Positions-DB - Fahrauftrag berechnen
        IF ("DB_Lagerabbild".Reihe[#IN_Reihe_Aus].Tiefe[#IN_Tiefe_Aus].Nicht_vorhanden) OR                                              // Abfrage ob Quelle physikalisch vorhanden
            (NOT #IN_Kantholz AND ((#IN_Reihe_Aus <= 2 AND #IN_Tiefe_Aus <= 3) OR #IN_Ziel = #IN_Kantholzfoerd)) OR                     // Abfrage ob Holzstapel von Kantholzplatz geholt werden soll
            (#IN_Kantholz AND ((#IN_Reihe_Aus <= 2 AND #IN_Tiefe_Aus > 3))) OR                                                          // Abfrage ob Kantholzbox von Holzstapelplatz geholt werden soll
            "DB_Lagerabbild".Reihe[#IN_Reihe_Aus].Tiefe[#IN_Tiefe_Aus].Ebene[#IN_Ebene_Aus + 1].Belegt THEN                             // Abfrage ob der darüber liegende Platz belegt ist
            #STAT_nAusfuehrbar := TRUE;                                                                                                 // Setzen Merker Auftrag nicht ausführbar
        ELSIF NOT #STAT_nAusfuehrbar AND (NOT "DB_Lagerabbild".Reihe[#IN_Reihe_Aus].Tiefe[#IN_Tiefe_Aus].Ebene[#IN_Ebene_Aus].Belegt OR // Abfrage ob vorgegebenee Quelle frei ist
            (#TMP_Hoehe_Rest_Aus > #IN_oGrenzw_Hoehe) OR                                                                                // Abfrage ob Physikalische Höhe außerhalb der Grenze liegt
            (#TMP_Hoehe_Rest_Aus < #IN_uGrenzw_Hoehe)) THEN                                                                             // Abfrage ob Physikalische Höhe außerhalb der Grenze liegt
            #STAT_Platz_frei := TRUE;                                                                                                   // Setzen Merker Platz frei (Auslagern)
        ELSE                                                                                                                            //
            #OUT_Auftrag_OK := TRUE;                                                                                                    // Setzen Ausgang Auftrag OK (Auslagern)
        END_IF;                                                                                                                         //
    ELSIF NOT #STAT_nAusfuehrbar AND #IN_Umlagern THEN                                                                                  // Abfrage ob Ausführbar und Umlagern
        #TMP_Hoehe_Rest_Ein := ("DB_Positionen".Reihe[#IN_Reihe_Ein].Tiefe[#IN_Tiefe_Ein].Z - #IN_Hoehe_Ein);                           // Resthöhe Positions-DB - Fahrauftrag berechnen
        #TMP_Hoehe_Rest_Aus := ("DB_Positionen".Reihe[#IN_Reihe_Aus].Tiefe[#IN_Tiefe_Aus].Z - #IN_Hoehe_Aus - #IN_TE_Hoehe);            // Resthöhe Positions-DB - Fahrauftrag berechnen
        IF ("DB_Lagerabbild".Reihe[#IN_Reihe_Ein].Tiefe[#IN_Tiefe_Ein].Nicht_vorhanden) OR                                              // Abfrage ob Ziel physikalisch vorhanden
            ("DB_Lagerabbild".Reihe[#IN_Reihe_Aus].Tiefe[#IN_Tiefe_Aus].Nicht_vorhanden) OR                                             // Abfrage ob Quelle physikalisch vorhanden
            (NOT #IN_Kantholz AND ((#IN_Reihe_Ein <= 2 AND #IN_Tiefe_Ein <= 3) OR #IN_Ziel = #IN_Kantholzfoerd OR #IN_Quelle = #IN_Kantholzfoerd)) OR                     // Abfrage ob Holzstapel auf Kantholzplatz soll
            (#IN_Kantholz AND ((#IN_Reihe_Ein <= 2 AND #IN_Tiefe_Ein > 3))) OR                                                          // Abfrage ob Kantholzbox auf Holzstapelplatz soll
            (NOT #IN_Kantholz AND ((#IN_Reihe_Aus <= 2 AND #IN_Tiefe_Aus <= 3) OR #IN_Ziel = #IN_Kantholzfoerd)) OR                     // Abfrage ob Holzstapel von Kantholzplatz geholt werden soll
            (#IN_Kantholz AND ((#IN_Reihe_Aus <= 2 AND #IN_Tiefe_Aus > 3))) OR                                                          // Abfrage ob Kantholzbox von Holzstapelplatz geholt werden soll
            (NOT "DB_Lagerabbild".Reihe[#IN_Reihe_Ein].Tiefe[#IN_Tiefe_Ein].Ebene[#IN_Ebene_Ein - 1].Belegt AND #IN_Ebene_Ein >2) OR    // Abfrage ob der darunter liegende Platz frei ist
            "DB_Lagerabbild".Reihe[#IN_Reihe_Aus].Tiefe[#IN_Tiefe_Aus].Ebene[#IN_Ebene_Aus + 1].Belegt THEN                             // Abfrage ob der darüber liegende Platz belegt ist
            #STAT_nAusfuehrbar := TRUE;                                                                                                 // Setzen Merker Auftrag nicht ausführbar
        ELSIF NOT #STAT_nAusfuehrbar AND ("DB_Lagerabbild".Reihe[#IN_Reihe_Ein].Tiefe[#IN_Tiefe_Ein].Ebene[#IN_Ebene_Ein].Belegt OR     // Abfrage ob vorgegebenes Ziel belegt ist
            (#TMP_Hoehe_Rest_Ein > #IN_oGrenzw_Hoehe) OR                                                                                // Abfrage ob Physikalische Höhe außerhalb der Grenze liegt
            (#TMP_Hoehe_Rest_Ein < #IN_uGrenzw_Hoehe)) THEN                                                                             // Abfrage ob Physikalische Höhe außerhalb der Grenze liegt
            #STAT_Platz_belegt := TRUE;                                                                                                 // Setzen Merker Platz belegt (Umlagern)
        ELSIF NOT #STAT_nAusfuehrbar AND (NOT "DB_Lagerabbild".Reihe[#IN_Reihe_Aus].Tiefe[#IN_Tiefe_Aus].Ebene[#IN_Ebene_Aus].Belegt OR // Abfrage ob vorgegebenee Quelle frei ist
            (#TMP_Hoehe_Rest_Aus > #IN_oGrenzw_Hoehe) OR                                                                                // Abfrage ob Physikalische Höhe außerhalb der Grenze liegt
            (#TMP_Hoehe_Rest_Aus < #IN_uGrenzw_Hoehe)) THEN                                                                             // Abfrage ob Physikalische Höhe außerhalb der Grenze liegt
            #STAT_Platz_frei := TRUE;                                                                                                   // Setzen Merker Platz frei (Umlagern)
        ELSE                                                                                                                            //
            #OUT_Auftrag_OK := TRUE;                                                                                                    // Setzen Ausgang Auftrag OK (Umlagern)
        END_IF;                                                                                                                         //
    ELSIF NOT #STAT_nAusfuehrbar AND #IN_Einlagern AND (#IN_Ziel = #IN_Abgabefoerd OR #IN_Ziel = #IN_Kantholzfoerd) THEN                //                                                                                                                //
        #OUT_Auftrag_OK := True;                                                                                                        //
    END_IF;                                                                                                                             //
    //==========================================================================================================================================================================================
    //                          Setzen der Ausgänge
    //==========================================================================================================================================================================================
    #OUT_Auftrag_nOK := #STAT_nAusfuehrbar;                                                                                             // Setzen Ausgang Auftrag nicht ausführbar
    #OUT_Platz_belegt := #STAT_Platz_belegt;                                                                                            // Setzen Ausgang Platz belegt
    #OUT_Platz_frei := #STAT_Platz_frei;                                                                                                // Setzen Ausgang Platz frei
    //==========================================================================================================================================================================================
    //                          Rücksetzen der Merker und Ausgänge
    //==========================================================================================================================================================================================
    IF #IN_Reset THEN                                                                                                                   // Abfrage ob Reset
        #STAT_nAusfuehrbar := FALSE;                                                                                                    // Rücksetzen Merker nicht Ausführbar
        #STAT_Platz_frei := FALSE;                                                                                                      // Rücksetzen Merker Platz frei
        #STAT_Platz_belegt := FALSE;                                                                                                    // Rücksetzen Merker Platz belegt
        #OUT_Auftrag_OK := FALSE;                                                                                                       // Rücksetzen Ausgang Auftrag OK
    END_IF;                                                                                                                             //  
    
    
END_FUNCTION_BLOCK

#IN_Kantholz ist ein Bool und wird von außen auch mit einem Bool aus einem Global-DB beschaltet. Ich weiß, dass der Code nicht elegant ist, aber das waren meine ersten SCL Gehversuche also habt bitte etwas Rücksicht ;)

Achja verwendet wird TIA Portal V13 SP1, die CPU ist eine 1515F-2 PN. Ich hoffe das sind alle Infos die ihr braucht.

Gruß ThomasM
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Servus gravieren,

jetzt wo du es sagst, seh ich meinen Fehler... Ich frag mich echt gerade ob ich die letzten 2 Tage blind war...

(NOT "DB_Lagerabbild".Reihe[#IN_Reihe_Ein].Tiefe[#IN_Tiefe_Ein].Ebene[#IN_Ebene_Ein - 1].Belegt

Ich suche im Lagerabbild bei #In_Ebene_Ein = 1 die Ebene 0 und die gibt es nicht...

Könnte mich gerade selber schlagen :(

Gruß ThomasM
 
Zurück
Oben