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
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.
#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
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
(#IN_Kantholz 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
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