admin管理员组

文章数量:1289425

What I'm after is: logging variables, to a text file or CSV, continuously, while my task (main PRG and some sub-FB's) is running, hopefully in a way which doesn't degrade the task performance. So feel free to suggest a different method entirely, or to troubleshoot the below.

I've looked into OSCAT Network but I couldn't get the libraries to load correctly and more recent Codesys Fe posts suggest CAA File is the more up-to-date, and generic, method for logging. I also tried CmpLog but it was very slow and didn't create an external file.

What I'm currently testing in:

  • Codesys V3.5 SP20+.
  • Target device is CODESYS_Control_for_Raspberry_Pi_MC_SL, version 4.11.0.0.
  • Testing in Simulation mode from a Windows PC, but the instance will eventually run on a Raspberry Pi.
  • Using CAA File version 3.5.19.0.
  • Single task, Priority 1, Cyclic @ 4 ms. Runs a single PRG.
  • The Codesys project is saved under C:\Users\___\Documents to avoid any weirdness with long file names.

The PRG is a (modified for correct function calls) version of CAA's default example:

PROGRAM PLC_PRG
VAR
    xFileStdInit: BOOL:=FALSE;
    uiFileStdState: UINT:=0;
    sFileName: FILE.CAA.FILENAME:= 'TestFile.txt';
    hFile: FILE.CAA.HANDLE;
    sFileTestString: STRING:='Hello caa library user';
    sFileString: STRING:='';
    szFileSize1: FILE.CAA.SIZE := 0;
    szFileSize2: FILE.CAA.SIZE := 0;
    filop: FILE.Open;
    filwr: FILE.Write;
    filrd: FILE.Read;
    filcl: FILE.Close;
END_VAR

IF NOT xFileStdInit THEN
    filop(xExecute:=FALSE);
    filcl(xExecute:=FALSE);
    filwr(xExecute:=FALSE);
    filrd(xExecute:=FALSE);
    xFileStdInit:=TRUE;
    uiFileStdState:=0;
ELSE
    CASE uiFileStdState OF
        0: (* create a new file *)
            filop.sFileName:=sFileName;
            filop.eFileMode:=FILE.MODE.MRDWR;
            filop.xExclusive:=TRUE;
            filop( xExecute:=TRUE);
            IF filop.xDone THEN
                hFile:=filop.hFile;
                uiFileStdState:=1;
            END_IF
            IF filop.xError THEN
                (* error handling*)
            ;
            END_IF
        1:(* write text in the file *)
            filwr.hFile:=hFile;
            filwr.pBuffer:=ADR(sFileTestString);
            szFileSize1:=SIZEOF(sFileTestString);
            filwr.szSize:=szFileSize1;
            filwr.udiTimeOut:=100000; (* 100ms Timeout *)
            filwr( xExecute:=TRUE);
            IF filwr.xDone THEN
                uiFileStdState:=2;
            END_IF
            IF filwr.xError THEN
                (* error handling*)
            ;
            END_IF
        2:(* read file - TestFile.txt*)
            filrd.hFile:=hFile;
            filrd.udiTimeOut:=100000; (* 100ms Timeout *)
            filrd.pBuffer:=ADR(sFileString);
            filrd.szBuffer:=255;
            filrd( xExecute:=TRUE);
            IF filrd.xDone THEN
                szFileSize2:=filrd.szSize;
            IF szFileSize2 = szFileSize1 THEN
                uiFileStdState:=3;
            ELSE
            (* error handling*)
            ;
            END_IF
            END_IF
            IF filrd.xError THEN
                (* error handling*)
            ;
            END_IF
        3: (* close file - TestFile.txt *)
            filcl.hFile:=hFile;
            filcl( xExecute:=TRUE);
            IF filcl.xDone THEN
                uiFileStdState:=4;
            END_IF
            IF filcl.xError THEN
                (* error handling*)
            ;
            END_IF
        4: (* end of example *)
            ;
    END_CASE
END_IF

When I run the above in simulation mode, uiFileStdState begins at 0 and filop xExecute is TRUE but filop.xDone is always False. It looks like filop.eError = ASM_CREATEJOB_FAILED but I can't figure out why. I tried an absolute location instead of a relative one but that didn't solve the issue.

What I'm after is: logging variables, to a text file or CSV, continuously, while my task (main PRG and some sub-FB's) is running, hopefully in a way which doesn't degrade the task performance. So feel free to suggest a different method entirely, or to troubleshoot the below.

I've looked into OSCAT Network but I couldn't get the libraries to load correctly and more recent Codesys Fe posts suggest CAA File is the more up-to-date, and generic, method for logging. I also tried CmpLog but it was very slow and didn't create an external file.

What I'm currently testing in:

  • Codesys V3.5 SP20+.
  • Target device is CODESYS_Control_for_Raspberry_Pi_MC_SL, version 4.11.0.0.
  • Testing in Simulation mode from a Windows PC, but the instance will eventually run on a Raspberry Pi.
  • Using CAA File version 3.5.19.0.
  • Single task, Priority 1, Cyclic @ 4 ms. Runs a single PRG.
  • The Codesys project is saved under C:\Users\___\Documents to avoid any weirdness with long file names.

The PRG is a (modified for correct function calls) version of CAA's default example:

PROGRAM PLC_PRG
VAR
    xFileStdInit: BOOL:=FALSE;
    uiFileStdState: UINT:=0;
    sFileName: FILE.CAA.FILENAME:= 'TestFile.txt';
    hFile: FILE.CAA.HANDLE;
    sFileTestString: STRING:='Hello caa library user';
    sFileString: STRING:='';
    szFileSize1: FILE.CAA.SIZE := 0;
    szFileSize2: FILE.CAA.SIZE := 0;
    filop: FILE.Open;
    filwr: FILE.Write;
    filrd: FILE.Read;
    filcl: FILE.Close;
END_VAR

IF NOT xFileStdInit THEN
    filop(xExecute:=FALSE);
    filcl(xExecute:=FALSE);
    filwr(xExecute:=FALSE);
    filrd(xExecute:=FALSE);
    xFileStdInit:=TRUE;
    uiFileStdState:=0;
ELSE
    CASE uiFileStdState OF
        0: (* create a new file *)
            filop.sFileName:=sFileName;
            filop.eFileMode:=FILE.MODE.MRDWR;
            filop.xExclusive:=TRUE;
            filop( xExecute:=TRUE);
            IF filop.xDone THEN
                hFile:=filop.hFile;
                uiFileStdState:=1;
            END_IF
            IF filop.xError THEN
                (* error handling*)
            ;
            END_IF
        1:(* write text in the file *)
            filwr.hFile:=hFile;
            filwr.pBuffer:=ADR(sFileTestString);
            szFileSize1:=SIZEOF(sFileTestString);
            filwr.szSize:=szFileSize1;
            filwr.udiTimeOut:=100000; (* 100ms Timeout *)
            filwr( xExecute:=TRUE);
            IF filwr.xDone THEN
                uiFileStdState:=2;
            END_IF
            IF filwr.xError THEN
                (* error handling*)
            ;
            END_IF
        2:(* read file - TestFile.txt*)
            filrd.hFile:=hFile;
            filrd.udiTimeOut:=100000; (* 100ms Timeout *)
            filrd.pBuffer:=ADR(sFileString);
            filrd.szBuffer:=255;
            filrd( xExecute:=TRUE);
            IF filrd.xDone THEN
                szFileSize2:=filrd.szSize;
            IF szFileSize2 = szFileSize1 THEN
                uiFileStdState:=3;
            ELSE
            (* error handling*)
            ;
            END_IF
            END_IF
            IF filrd.xError THEN
                (* error handling*)
            ;
            END_IF
        3: (* close file - TestFile.txt *)
            filcl.hFile:=hFile;
            filcl( xExecute:=TRUE);
            IF filcl.xDone THEN
                uiFileStdState:=4;
            END_IF
            IF filcl.xError THEN
                (* error handling*)
            ;
            END_IF
        4: (* end of example *)
            ;
    END_CASE
END_IF

When I run the above in simulation mode, uiFileStdState begins at 0 and filop xExecute is TRUE but filop.xDone is always False. It looks like filop.eError = ASM_CREATEJOB_FAILED but I can't figure out why. I tried an absolute location instead of a relative one but that didn't solve the issue.

Share Improve this question asked Feb 19 at 19:12 PoGaMiPoGaMi 334 bronze badges 1
  • This is off-topic, but here's a tip for the CASE statement, instead of using normal integers for cases and using comments to explain what the cases are, you may consider using implicit enums instead, or at the very least, defining local constant variables for each case. – Guiy Commented Feb 20 at 12:23
Add a comment  | 

1 Answer 1

Reset to default -1
Codesys inbuilt logger can be used with following settings.

In CodesysControl_User.cfg:

[CmpLog] 
Logger.0.Name=Plc.log --> generic logs of the components
Logger.1.Name=Logger.log --> user defined logs

In CodesysControl.cfg:

[CmpLog] 
Logger.0.Filter=0x0000000F
Logger.0.Enable=1
Logger.0.MaxEntries=100000
Logger.0.MaxFileSize=10000000 
Logger.0.MaxFiles=1
Logger.0.Backend.0.ClassId=0x00000104
Logger.0.Type=0x314

Logger.1.Filter=0xFFFFFFFF
Logger.1.Enable=1
Logger.1.MaxEntries=100000
Logger.1.MaxFileSize=10000000 
Logger.1.MaxFiles=1
Logger.1.Backend.0.ClassId=0x00000104
Logger.1.Type=0x314

本文标签: raspberry piLogging variables in Codesys using CAAFile (or similar)Stack Overflow