epinikion - 2020-10-23

Hi all,

I wrote a FB to read the content of specific text files. It chooses a text file depending of the input "bRfidNo", for instance: bRfidNo at 1 would open 1.txt and save the contents on a local array in the PLC. It uses the "File Access" library and its function Blocks.

Thing is, when I use my FB on PLC_PRG and choose manually bRfidNo it works fine. But I wanted too by Startup of the PLC have it read every text file and add all its contents on the local Array. I wrote a Startup subprogramm which is basically a loop of my Read-FB until he readed everything, but it remains stuck on Case 10 of the FB.

Here's the Code of the FB. The "fbRead(xRead) remains stuck on true, so I'm suspecting I'm starting the input wrong on my Startup-program maybe?
fopen.xDone doesn't seem to turn on when I call the FB inside another PRG either, despite that I get no fopen.xError.

FUNCTION_BLOCK FB_RackRead
///Dieser FB liest derzeitige Daten aus der Buffer-Textdatei.

VAR CONSTANT
END_VAR

VAR_INPUT
    xRead:                          BOOL;
    bRfidNo:                        BYTE;

END_VAR

VAR_OUTPUT
    xReadDone:                      BOOL;
    xBusy:                          BOOL;
    xError:                         BOOL;
    eError:                         File.ERROR; 

END_VAR

VAR_IN_OUT

END_VAR

VAR
    sFilePath:                      STRING;// Pfad bzw. Dateiname

    //Schritt des Ablaufs
    uiStep:                         UDINT:=0;

    //Backup Data processing
    iCounter1:                      INT:=1;

    //File Access
    hFile:                          CAA.HANDLE;
    szFileSize1:                    CAA.SIZE := 0;
    szFileSize2:                    CAA.SIZE := 0;
    fopen:                          FILE.Open;
    fread:                          FILE.Read;
    fclose:                         FILE.Close;
    sFileName:                      CAA.FILENAME;

    sStringToRead:                  STRING(9999);
    sStringToWork:                  STRING(9999);
    iStringFIND:                    INT;
    sStringMID:                     STRING:='';
    uReadIndex:                     UINT:=1;


    //Control characters    
    CRLF:                           STRING(5):=';$R$N'; //Line-Break

END_VAR

VAR_IN_OUT
    saaList:                ARRAY[1..16] OF ARRAY [1..36] OF STRING;    
END_VAR
CASE uiStep OF

        (*warte auf Trigger*)
    0:  IF xRead AND bRfidNo >= 1 AND bRfidNo <= 16 THEN
            xRead:=FALSE;
            xBusy:=TRUE;
            xReadDone:=FALSE;
            uiStep:=10;
            iCounter1:=1;
            sFilePath:=CONCAT('Local_Buffer\',INT_TO_STRING(bRfidNo));      //Open the buffer.txt of the selected Rack
            sFilePath:=CONCAT(sFilePath,'.txt');

        END_IF

    10: (* create or open my log-file for the HEADER*)
        fopen.sFileName:=sFilePath;
        fopen.eFileMode:=File.MODE.MREAD;
        fopen.xExclusive:=TRUE;
        fopen( xExecute:=TRUE);
        IF fopen.xDone THEN
            hFile:=fopen.hFile;
            uReadIndex:=0;
            uiStep:=20;

        END_IF

        IF fopen.xError THEN
            (* error handling*)
            xError:=TRUE;
            eError:=fopen.eError;
        END_IF



    20: (* read log data to file*)
        fread.hFile:=hFile;
        fread.pBuffer:=ADR(sStringToRead);
        fread.szBuffer:=SIZEOF(sStringToRead);
        fread.udiTimeOut:=100000;   //Timeout
        fread( xExecute:=TRUE);
        IF fread.xDone THEN
            fread(xExecute := FALSE);
            sStringToWork:=sStringToRead;
            szFileSize2:=fread.szSize;

            uiStep:=30;
        END_IF

        IF fread.xError THEN
                //Error
                xBusy:=FALSE;
                xRead:=FALSE;
                uiStep:=40;
            END_IF

    30:  (* adapt text data to arrays *)


        FOR iCounter1 := 1 TO 36 BY 1 DO

            iStringFIND := stu.StrFindA(ADR(sStringToRead),ADR(CRLF),1);                            //Find the first line break (;$R$N)
            StrMidA(                                                                                //Extract the first Panel-String from the whole readed text
                pst:= ADR(sStringToRead), 
                uiInputBufferSize:= SIZEOF(sStringToRead), 
                iLength:= iStringFIND - 1, 
                iPosition:= 1, 
                pstResult:= ADR(sStringMID), 
                uiResultBufferSize:= SIZEOF(sStringMID));

            saaList[bRfidNo][iCounter1] := sStringMID;                                              //Add the Panel to the local Rack Array

            StrDeleteA(pby:= ADR(sStringToRead), iLength:= (iStringFIND + 2), iPosition:= 1);


        END_FOR
        uiStep:= 40;


    40:  (* close log file *)
        fclose.hFile:=hFile;
        fclose( xExecute:=TRUE);
        IF fclose.xDone THEN
            fopen( xExecute:=FALSE);
            fread( xExecute:=FALSE);
            fclose( xExecute:=FALSE);
            xReadDone:=TRUE;
//          xRead:=TRUE;
            xBusy:=FALSE;
            //uiStep:=50;
            iCounter1:=1;
        //  uiStep:=0;
        END_IF

        IF fclose.xError THEN
            //Error
            xBusy:=FALSE;
            xRead:=FALSE;
            uiStep:=0;


        END_IF


END_CASE

And here the Startup-program (I tried too with FORs, Ifs etc, no difference)

IF xStart THEN
    xBusy:=TRUE;
    xStart:=FALSE;
    WHILE bRackNo<=16 DO

        fbRead(xRead:=TRUE,bRfidNo:=bRackNo,saaList:=saaList);

        IF FbRead.xReadDone THEN
        bRackNo:=bRackNo+1;
        END_IF



    END_WHILE
    saaRack:=saaList;
    xBusy:=FALSE;
    xDone:=TRUE;

END_IF
 

Last edit: epinikion 2020-10-23