Fehler bei Ausfürhung von MID in SCL

Tigerente1974

Level-3
Beiträge
1.826
Reaktionspunkte
293
Zuviel Werbung?
-> Hier kostenlos registrieren
Ich habe eine Anwendung in der ich einen Profibus-Scanner auslese.
Je nach Barcodelänge benötige ich unterschiedliche Teile aus dem Barcode. Ich lese also die Barcodelänge aus und nutze den MID-Befehl, um den relevanten Teil zu lesen.

Folgende Zeilen in SCL funktionieren:

Code:
IF SCAN_COMMDB.SCANNER[ScannerIndex].READ.HEADER.Barcodelaenge = 20 THEN
        tmpSendedaten:=MID(IN:=SCAN_COMMDB.Scanner[ScannerIndex].READ.Barcode,L:=9,P:=12);
    ELSIF SCAN_COMMDB.SCANNER[ScannerIndex].READ.HEADER.Barcodelaenge = 25 THEN
        tmpSendedaten:=MID(IN:=SCAN_COMMDB.Scanner[ScannerIndex].READ.Barcode,L:=9,P:=16);
    END_IF;
    SCAN_COMMDB.Scanner[ScannerIndex].Sendedaten:=tmpSendedaten;

-SCAN_COMMDB.Scanner[ScannerIndex].Sendedaten ist als STRING[9] in einem Global-DB deklariert.
-tmpSendedaten ist ebenfalls als STRING[9] deklariert und ist eine TEMP-Variable.

Wenn ich den Code ohne den "Umweg" über tmpSendedaten schreibe und direkt die Variable SCAN_COMMDB.Scanner[ScannerIndex].Sendedaten mit dem MID-Befehl verwende, geht die CPU auf STOP.
Warum? :confused:
 
OK ... und was war der Grund für den Stop (laut Diagnose) ?

Das ist das Dumme dabei. Ich habe den Versuchsaufbau schon wieder abgebaut und war zunächst zufrieden dass es funktioniert. Die Meldung der Diagnose kann ich jetzt leider nicht mehr wiedergeben.

Hier die Quelle für den DB:

Code:
DATA_BLOCK DB401
TITLE =
VERSION : 1.0

STRUCT
    SCANNER:ARRAY[1..4]OF STRUCT     
        READ:STRUCT         // Lesedaten 
            HEADER:STRUCT   // Headerinformation
                Lesetorstatus:BOOL:=FALSE;     //0: aus / 1: ein
                NeuesErgebnis:BOOL:=FALSE;     //0: nein / 1: ja
                ErgZustand:BOOL:=FALSE;   //0: Gutlesung / 1: NOREAD
                WeitereErg:BOOL:=FALSE; //weitere Ergebnisse im Puffer
                Pufferueberlauf:BOOL:=FALSE;   //0: nein / 1: ja
                NeuesErg:BOOL:=FALSE;    //0->1: neues Ergebenis / 1->0: neues Ergebnis
                ErgebnisToggle:BOOL:=FALSE;  //0->1: NOREAD / 1->0: NOREAD
                WartenAufQuit:BOOL:=FALSE;     //0: Grundszustand / 1: Quittierung erwartet
                Barcodelaenge:BYTE:=B#16#0;     
            END_STRUCT;
            Barcode:STRING[28]:='----------------------------';
        END_STRUCT; 
        Sendedaten:STRING[9]:='---------';
    END_STRUCT;   
END_STRUCT;

BEGIN

END_DATA_BLOCK

Und hier die Quelle für den FB:

Code:
FUNCTION SCAN_COMM:VOID
VAR_INPUT
    ScannerIndex:INT;
END_VAR
VAR_IN_OUT
    Start:BOOL;
    DataQuit:BOOL;
END_VAR
VAR_TEMP
    Status_SFC20:INT;
    tmpSendedaten:STRING[9];
END_VAR
VAR_OUTPUT
    Lesetor:BOOL;
    DataReset:BOOL;
END_VAR
     

BEGIN


// Daten von Scanner lesen
"SCAN_COMMDB".SCANNER[ScannerIndex].READ.Barcode:='----------------------------';
Lesetor := Start;

SCAN_READ(INDEX:=ScannerIndex);

IF SCAN_COMMDB.SCANNER[ScannerIndex].READ.HEADER.ErgZustand AND Start THEN
    Start:=FALSE;
    SCAN_COMMDB.Scanner[ScannerIndex].Sendedaten:='000000000';
END_IF;
DataReset:=SCAN_COMMDB.SCANNER[ScannerIndex].READ.HEADER.ErgZustand;

IF SCAN_COMMDB.SCANNER[ScannerIndex].READ.HEADER.NeuesErgebnis AND NOT SCAN_COMMDB.SCANNER[ScannerIndex].READ.HEADER.ErgZustand AND Start THEN
    Start := FALSE;
    DataQuit := NOT DataQuit; // Quittierung toggeln
    SCAN_COMMDB.Scanner[ScannerIndex].Sendedaten:='---------';
    tmpSendedaten:='---------';
    IF SCAN_COMMDB.SCANNER[ScannerIndex].READ.HEADER.Barcodelaenge = 20 THEN
        tmpSendedaten:=MID(IN:=SCAN_COMMDB.Scanner[ScannerIndex].READ.Barcode,L:=9,P:=12);
    ELSIF SCAN_COMMDB.SCANNER[ScannerIndex].READ.HEADER.Barcodelaenge = 25 THEN
        tmpSendedaten:=MID(IN:=SCAN_COMMDB.Scanner[ScannerIndex].READ.Barcode,L:=9,P:=16);
    END_IF;
    SCAN_COMMDB.Scanner[ScannerIndex].Sendedaten:=tmpSendedaten;
END_IF;

END_FUNCTION
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Bei der Version bei der deine CPU in Stop geht wird dir der Lokaldatenspeicher in der CPU ausgehen. Was hast du denn für eine CPU-Typ?

Aus welchen Gründen auch immer werden die String-Funktionen die SCL verwendet werden nicht direkt auf den DB-Daten ausgeführt, sondern diese erst auf lokale Strings kopiert und dann wieder zurückgeschrieben. Im ungünstigsten Fall kommen da zwei Temp-Strings mit der üblichen Stringlänge von 254 Zeichen zusammen, macht also mindestens 512 Bytes Lokaldatenverbrauch.
Aus dem Grund wird es bei dir auch in Plcsim oder einer anderen größeren CPU laufen, denn dort ist der Lokaldatenstack dann ausreichend groß.
 
Das war eine 313-2DP von Vipa. Wenn Du richtig liegst, ist mir nur nicht ganz klar warum es dann über den Umweg klappt. Allerdings habe ich mich bisher auch noch nicht so intensiv mit dem Speichermanagement befasst. Den Code brauche ich später in einer 317-2DP. Die dürfte auf jeden Fall mehr Lokaldatenspeicher haben. Werde das dann noch einmal testen.
 
Zurück
Oben