IF NOT AND question

2018-11-20
2018-11-26
  • PhilipLykov - 2018-11-20

    Could you please explain why the following statement is always FALSE:

    IF PLC^.xInitDone AND NOT PLC^.xError THEN
    

    It runs on RaspberryPi with the latest Codesys Runtime.
    PLC is a pointer to ModbusSlaveComPort.
    The xInitDone is TRUE, xError is FALSE.

    If I rewrite the code in such way it works as expected:

    IF PLC^.xInitDone THEN
       IF NOT PLC^.xError THEN
    
     
  • dFx

    dFx - 2018-11-20

    What is the result if you replace dereferenced pointers by only boolean variables ?

     
  • m.prestel - 2018-11-22

    Hello Sir,

    ST checks for all the conditions and does not stop early.

    AND_THEN does what you describe with nested ifs.

    Best regards,
    Marcel

     
  • PhilipLykov - 2018-11-22

    m.prestel hat geschrieben:
    Hello Sir,
    ST checks for all the conditions and does not stop early.
    AND_THEN does what you describe with nested ifs.
    Best regards,
    Marcel

    Sorry Marcel,
    I didn't understood your idea.

     
  • PhilipLykov - 2018-11-22

    dFx hat geschrieben:
    What is the result if you replace dereferenced pointers by only boolean variables ?

    It works as expected.

     
  • dFx

    dFx - 2018-11-23

    and if you try :

    IF PLC^.xInitDone AND NOT (PLC^.xError) THEN
    
     
  • m.prestel - 2018-11-23

    Sorry I misunderstood you...

    Can you provide a small example application to easyly reproduce?

    Best regards,
    Marcel

     
  • PhilipLykov - 2018-11-26

    dFx hat geschrieben:
    and if you try :

    IF PLC^.xInitDone AND NOT (PLC^.xError) THEN
    

    Unfortunately it doesn't help. Only nested IFs works fine.
    For those who want to reproduce it:

    FUNCTION write_value_bool : BOOL
    VAR_INPUT
       PLC         : POINTER TO ModbusSlaveComPort;
    END_VAR
    IF PLC^.xInitDone AND NOT PLC^.xError THEN
            write_value_bool:= TRUE;
    ELSE
            write_value_bool:= FALSE;
    END_IF
    

    And yes, you have to wait for xInitDone to become FALSE or xError TRUE. For this purpose you can do xReset:= TRUE (at ModbusSlaveComPort) for one cycle.

     
  • dFx

    dFx - 2018-11-26

    PhilipLykov hat geschrieben:
    … xInitDone to become FALSE or xError TRUE...

    This does not match written code. Written code says you have to wait xInitDone to TRUE AND xError to FALSE.

     
  • aliazzz

    aliazzz - 2018-11-26
    FUNCTION write_value_bool : BOOL
    VAR_INPUT
       PLC         : POINTER TO ModbusSlaveComPort;
    END_VAR
    IF PLC^.xInitDone AND NOT PLC^.xError THEN
            write_value_bool:= TRUE;
    ELSE
            write_value_bool:= FALSE;
    END_IF
    

    One should avoid the above IF THEN statements. A better solution could be;

    write_value_bool := PLC^.xInitDone AND NOT PLC^.xError;
    

    Which (better) readable is something like;

    FUNCTION xWrtRdy : BOOL
    VAR_INPUT
       pMbCom : POINTER TO ModbusSlaveComPort;
    END_VAR
    xWrtRdy := pMbCom^.xInitDone AND NOT pMbCom^.xError
    

    Now your code is more atomic in nature and "what's in a name". Also, this function can very easily be transformed to a method of some FB.

     

Log in to post a comment.