File reading/writing works great in simulation mode, but not in soft-PLC (RTE) mode

2017-05-11
2017-05-12
  • luigisvideos - 2017-05-11

    Hi all.

    My MAIN_PROG code consists of an initialization part, in which some files are read from txt files and stored in arrays, and an operative part in which values are used.
    It should run on the RTE module and should receive and send data through my CIFX card on a profiBUS. I've coded and tested it in simulation mode (card is installed at my university laboratory) a Function Block that reads a txt file in which there is a matrix; so if the file is in the form:

    1 2 3
    4 5 6
    7 8 9

    it produces a bidimensional array containing those values. The program is executed in a standard cyclic task and it is the only one executing.
    Well, in simulation mode everything works; while passing to the real run on RTE, files never get read, so returned arrays are always zero.
    By using a step by step debugging, I discovered that the instruction:

    FileHandle := SysFileOpen(szFile:= FileName, am:=SysFile.AM_READ, pResult:=pResult);

    always produces the result: RTS_INVALID_HANDLE, even if in simulation mode this doesn't happen.

    How can be this problem solved? Here is the code of the function block:

    FUNCTION_BLOCK MATRIX_READER
    VAR_IN_OUT
       M: ARRAY[*,*] OF INT;
    END_VAR
    VAR CONSTANT
       MAX_BUFFER : __XWORD := 64*1024;
    END_VAR
    VAR_INPUT
       FileName : STRING(255) ;
    END_VAR
    VAR_OUTPUT
       nRows : INT:=0;
       nCols: INT:=0;
    END_VAR
    VAR
       ErrCode : SysFile.SYS_FILE_STATUS := SysFile.SYS_FILE_STATUS.FS_NO_FILE;
       BytesRead : __XWORD := 0;
       Data : ARRAY[0..MAX_BUFFER] OF BYTE;
       pResult : POINTER TO SysFile.RTS_IEC_RESULT;
       FileHandle : SysFile.RTS_IEC_HANDLE;
       pFileData : POINTER TO BYTE := ADR(Data);
       actualValue:INT;
       values : ARRAY[1..10] OF INT;
       i: __XWORD;
       r_index: INT;
       c_index:INT;
       char: STRING;
       numEnd: BOOL;
       accString: STRING;
       minus:bool:=false;
       rowEnd: BOOL;
    END_VAR
    FOR i:=1 TO MAX_BUFFER BY 1 DO
       Data[i]:=0;
    END_FOR
    //try to open file
    FileHandle := SysFileOpen(szFile:= FileName, am:=SysFile.AM_READ, pResult:=pResult);
    //verify found a file
    IF FileHandle = SysFile.RTS_INVALID_HANDLE THEN
       //no file found
       ErrCode := SysFile.SYS_FILE_STATUS.FS_NO_FILE;
    ELSE
       //try to read file out
       
       BytesRead := SysFileRead(hFile:=FileHandle, pbyBuffer:=pFileData, ulSize:=MAX_BUFFER, pResult:=pResult);
       
       //check if actually read any bytes
       IF BytesRead > 0 THEN
          ErrCode := SysFile.SYS_FILE_STATUS.FS_OK;
       ELSE
          ErrCode := SysFile.SYS_FILE_STATUS.FS_NO_FILE;
       END_IF
    END_IF
    //close file!!!!
    SysFileClose(hFile:=FileHandle);
    r_index := 1;
    c_index := 1;
    accString:='';
    minus:=FALSE;
    i:=0;
    WHILE i<=BytesRead DO
       IF numEnd AND BYTE_TO_INT(Data[i]) = 45 THEN
          minus:=TRUE;
          i:=i+1;
       END_IF
       numEnd:=FALSE;
       //new line or space
       IF BYTE_TO_INT(Data[i]) = 10 OR BYTE_TO_INT(Data[i]) = 32 THEN
          IF NOT(accString='') THEN
             M[r_index,c_index] := STRING_TO_INT(accString);
             IF minus THEN
                M[r_index,c_index] :=-M[r_index,c_index];
             END_IF
             minus:=FALSE;
             numEnd:=TRUE;
             accString:='';
             c_index:=c_index+1;
          END_IF
          IF BYTE_TO_INT(Data[i]) = 10 THEN
             r_index:=r_index+1;
             rowEnd:=TRUE;
             nCols:=c_index-1;
             c_index:=1;
          END_IF
       ELSE
          IF NOT(Data[i]=9) AND NOT(Data[i]=10) AND NOT(Data[i]=13) AND NOT(Data[i]=32) THEN
             accString := CONCAT(accString,WORD_AS_STRING(Data[i],0));
          END_IF
       END_IF      
       i:=i+1;
       IF i>BytesRead THEN
          IF r_index=1 THEN 
             nRows:=1;
          ELSE
             nRows:=r_index-1;
          END_IF
          IF nRows=1 THEN
             nCols:=c_index-1;
          END_IF   
          RETURN;
       END_IF
    END_WHILE
       
    

    Please, since i'm relatively new to Codesys, try to answer in a complete manner. Examples are rare to find and documentation is not sufficient.

    Thanks,
    Luigi Ferrara.

     
  • josepmariarams - 2017-05-12

    Hi.

    Reading seems correct.

    I had some similars troubles on raspberry. The problem was in files permisions.

    Another problem that I had was in C300 from Lenze with rte. The problem was in file path. Use the same file path as you can see in your ide in plc part you can see your plc files.

     
  • luigisvideos - 2017-05-12

    Hi!
    First of all thanks very much.

    Secondly, I don't think my problem is about permissions; in fact I am using windows with everything in run as admin. Maybe the second one you cited could be it.
    So please, could you tell me more precisely what do you mean by files in the ide's plc? I'd like to have some more indications on the effective steps to do in Codesys.

    Thanks,
    Luigi Ferrara

     
  • josepmariarams - 2017-05-12

    Hi.

    In right tree go to device (plc). Wher the communications settings be.

    Down to communications settings you can see files.

    In files right window refresh. You can see tree folders. Go to your files folder and use the path ad you can see in location.

     
  • josepmariarams - 2017-05-12

    Sorry, left tree devices

     
  • josepmariarams - 2017-05-12

    Another thing. In some plcs you only can write on sdcard.

     
  • luigisvideos - 2017-05-12

    Thank you so much.

    I've solved the problem using your tip and enabling all the permissions of the folder; running Codesys and RTE as ADMIN can be helpful.

    Thanks again.

     

Log in to post a comment.