Welcome to our new forum
All users of the legacy CODESYS Forums, please create a new account at account.codesys.com. But make sure to use the same E-Mail address as in the old Forum. Then your posts will be matched. Close

Ethernet/IP xDone stuck on

blewl
2018-11-28
2018-11-28
  • blewl - 2018-11-28

    Hello

    I have a generic service running reading a parameter. It can read the parameter once, then it won't go again because the 'IF xDone then' runs which makes it finish the sub routine. I need to do a cold reset to get it to work again.

    I found a reset() function which seams to do nothing. The documentation says:

    Zitat:
    This function block is used for calling the reset service of a specific instance of a CIP object. The exact effect of this service depends on the CIP object (refer to the CIP specifications (Vol. 1 and 2). This instance call resets the DEVICE_123_ETHERNET device as soon as xExecute yields TRUE:

    Thanks

    Sub routine:

    IF Execute THEN
       Done                  :=FALSE;
       Read_Parameter_TxData[17]   :=DriveAddress;
       Read_Parameter_TxData[10]   :=WORD_TO_BYTE(ParameterNumber);
       Read_Parameter_TxData[11]   :=WORD_TO_BYTE(SHR(ParameterNumber,8));
       Read_Parameter(
          itfEtherNetIPDevice      :=EthernetAdapter,
          eClass               :=Read_Parameter_Class,
          dwInstance            :=Read_Parameter_Instance,
          wAttribute            :=Read_Parameter_Attribute,
          eService            :=Read_Parameter_Serv,
          pWriteData            :=ADR(Read_Parameter_TxData[0]),
          udiWriteDataSize      :=SIZEOF(Read_Parameter_TxData),
          pReadData            :=ADR(Read_Parameter_RxData[0]),
          udiReadDataSize         :=SIZEOF(Read_Parameter_RxData),
          xExecute            :=TRUE,
       );
       counter:=1;
    END_IF
    IF Read_Parameter.xDone THEN
       returnValue      :=   SHL(BYTE_TO_WORD(Read_Parameter_RxData[1]),8) + Read_Parameter_RxData[0];
       Execute         :=    FALSE;
       Done         :=   TRUE;
       counter         :=   0;
       Read_Parameter.xExecute := FALSE;
    END_IF
    IF counter = 2 THEN
       Execute:=TRUE;
       counter:=0;
    END_IF
    IF Read_Parameter.xError AND counter = 1 THEN
       ErrorEnum := Read_Parameter.eError;
       Execute   :=    FALSE;
       counter := 2;
       Read_Parameter.xExecute := FALSE;
    END_IF
    Error:=Read_Parameter.xError;
    

    Main:

    IF IDL_ReadBool THEN
             IF RParmEIP.Error THEN
                RParmEIP();
             ELSE
             RParmEIP(
                EthernetAdapter     :=OPC_2_ETHIG_IN,
                ParameterNumber  :=IDL_ReadP-1,
                Execute          :=TRUE,
             );
             END_IF
          END_IF
          IF RParmEIP.Done THEN
             IDL_ReadBool   :=FALSE;
             IDL_ReadVal      :=RParmEIP.returnValue;
             RParmEIP();
          END_IF
    
     

    Related

    Talk.ru: 1
    Talk.ru: 11

  • dFx

    dFx - 2018-11-28

    If you don't call your FB "Read_Parameter", how should xDone (FB output) come to false ?
    Your FB should be called at every cycle.

    exemple, slightly edited to auto cycle com requests

    Read_Parameter_TxData[17]   :=DriveAddress;
    Read_Parameter_TxData[10]   :=WORD_TO_BYTE(ParameterNumber);
    Read_Parameter_TxData[11]   :=WORD_TO_BYTE(SHR(ParameterNumber,8));
    Read_Parameter(
      itfEtherNetIPDevice      :=EthernetAdapter,
      eClass               :=Read_Parameter_Class,
      dwInstance            :=Read_Parameter_Instance,
      wAttribute            :=Read_Parameter_Attribute,
      eService            :=Read_Parameter_Serv,
      pWriteData            :=ADR(Read_Parameter_TxData[0]),
      udiWriteDataSize      :=SIZEOF(Read_Parameter_TxData),
      pReadData            :=ADR(Read_Parameter_RxData[0]),
      udiReadDataSize         :=SIZEOF(Read_Parameter_RxData),
      xExecute            :=NOT (Read_Parameter.xError OR Read_Parameter.xDone),
    );
    IF Read_Parameter.xDone THEN
       returnValue      :=   SHL(BYTE_TO_WORD(Read_Parameter_RxData[1]),8) + Read_Parameter_RxData[0];
    END_IF
    IF Read_Parameter.xError THEN
       ErrorEnum := Read_Parameter.eError;
    END_IF
    

    Regards,
    dFx

     

    Related

    Talk.ru: 1
    Talk.ru: 11

  • blewl - 2018-11-28

    Ah thanks, so glad it was that simple!

     

Log in to post a comment.