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

Wrong init of variables in for loop. With video

2018-11-02
2018-11-02
  • JeffreyThijssen - 2018-11-02

    Hello,

    I am having strange issues with the initialization of variables while using a for loop and [*] Array. I added a video for the explanation. Wrong initiations at 1.22min, 1.31min, and 1.37min.

    Codesys Version 3.5 SP9 Patch 5

    https://youtu.be/FAjKp9R6okQ

     Plt  : ARRAY[0..300] OF UDT_Plt;  
    
       VAR_INPUT 
          i_Record : DInt;   
          i_Position : DInt;  
          i_Info : Int;   /
          i_State : UDT_PltEntryState;  
       END_VAR
       VAR_OUTPUT 
          o_ReturnValue : INT;   // Status: Error/Job Action
       END_VAR
       VAR_IN_OUT 
          io_C : UDT_Constants;   // Constants: User constants
          io_PLT : ARRAY[*] OF UDT_Plt;  
       END_VAR
       VAR_STAT
          t_SearchStartPosition : DInt;   
          t_SearchEndPosition : DInt;  
          t_EntryId : Int;   // Entry index counter
          t_ReturnValue : Int;   // Status of Job Action
          t_State : UDT_PltEntryState;   // State struct
         Testpos : DINT := 0;
         Testinfo : DINT :=0;
       END_VAR
    
    IF (i_Record < LOWER_BOUND(io_PLT, 1))
           OR (i_Record > UPPER_BOUND(io_PLT, 1))
       THEN
           o_ReturnValue := io_C.ReturnValue.InvalidRecordId;
           RETURN; //Block end 
       END_IF;
       t_ReturnValue := io_C.ReturnValue.NoActionPresent;
       
       // Calculate start- and end-position of search-window
       t_SearchStartPosition := i_Position;
       IF io_PLT[i_Record].Header.Displacement > 0
       THEN
           t_SearchEndPosition := i_Position - io_PLT[i_Record].Header.Displacement + 1;
       ELSE
           t_SearchEndPosition := i_Position;
       END_IF;
       
       // Search for data in search-window & write State if data found.
       FOR t_EntryId := 1 TO io_PLT[i_Record].Header.EntriesUsed BY 1 DO
          Testpos := io_PLT[i_Record].Entry[t_EntryId].Position;
          Testinfo := io_PLT[i_Record].Entry[t_EntryId].Info;
          
           IF Testpos < t_SearchEndPosition
           THEN
               EXIT; // Exit the for loop data can no longer be found
           END_IF; 
           
           IF Testpos <= t_SearchStartPosition
               AND Testpos >= t_SearchEndPosition
               AND Testinfo = i_Info
           THEN
               t_State := io_PLT[i_Record].Entry[t_EntryId].State;
               
               // Make OR statement on all bits
               t_State.Claimed := t_State.Claimed OR i_State.Claimed;
               t_State.Owner := t_State.Owner OR i_State.Owner;
               t_State.OwnerDown := t_State.OwnerDown OR i_State.OwnerDown;
               t_State.OwnerHalted := t_State.OwnerHalted OR i_State.OwnerHalted;
               t_State.OwnerRequest := t_State.OwnerRequest OR i_State.OwnerRequest;
               t_State.OwnerUp := t_State.OwnerUp OR i_State.OwnerUp;
               t_State.Pec := t_State.Pec OR i_State.Pec;
               t_State.PecIo := t_State.PecIo OR i_State.PecIo;
               t_State.PecLatch := t_State.PecLatch OR i_State.PecLatch;
               t_State.PecRequest := t_State.PecRequest OR i_State.PecRequest;
               t_State.SparePecB03 := t_State.SparePecB03 OR i_State.SparePecB03;
               t_State.SpareW01 := t_State.SpareW01 OR i_State.SpareW01;
               t_State.SpareW02 := t_State.SpareW02 OR i_State.SpareW02;
               t_State.SpareW04 := t_State.SpareW04 OR i_State.SpareW04;
               t_State.SpareW08 := t_State.SpareW08 OR i_State.SpareW08;
               t_State.Virtual := t_State.Virtual OR i_State.Virtual;
               
               // Copy temp back to entry state
               io_PLT[i_Record].Entry[t_EntryId].State := t_State;
               
               // Update the return value
               t_ReturnValue := io_C.ReturnValue.DataWrite;
               EXIT; // Exit the for loop update is done
           END_IF;
       END_FOR;
       // Update the return value   
       o_ReturnValue := t_ReturnValue;
    
     
  • JeffreyThijssen - 2018-11-02

    @Update. I manage to find the solution. I need to reference to the [*] Array

    Unforituannly, I am not really satisfied with this solution. Does anyone have a better suggestion for a solution?
    For example, this might be solved with a singe line of code?

       TestPLT REF= io_PLT[i_Record];
          TestEntry  REF= TestPLT.Entry[t_EntryId];
          
          Testpos := TestEntry.Position;
          Testinfo := TestEntry.Info;
    
     

Log in to post a comment.