Retrieve number of elements in an array of function blocks

shane2977
2020-04-19
2020-04-19
  • shane2977 - 2020-04-19

    Hi all,

    I'm pretty new to ST programming. I've mainly used ladder (Allen Bradly) up till now. I've done some basic ST and FB programming. I'm seeing more and more ST in my area and I want to become fluent in it. To this end I'm working through a great course on Udemy called PLC Object Oriented Programming :Advanced Infrastructure. I'm working on Excercise 2 which is to program a sequenced startup of 5 motors. One of the objectives is to be able to easily add more motors to the program. I've created a Motor FB and a Motors class with separate input and output structures in my main program. My thought was to just increase the number of Motors array in the declaration section by editing the upper constant, then have the code detect the number of elements in the array so as to update any FOR loops using the Motors FB.

    I thought I could use the SIZEOF operator but that returns the size of the whole array in bytes (if I understand correctly). SIZEOF returned 192. I then thought I could divide the 192 by 3 (number of arrays) to get the size of 1 element, which gave me 64. I rearranged the math 192 / 64 to get 3 elements. This does work until I change the variables in the Motor FB.

    //Declare array of motor structures

    VAR
        Motors      :   ARRAY [1..3] OF Motor;          //Function block
        MotorIP     :   ARRAY [1..3] OF MotorInputs;   //Structure
        MotorOP     :   ARRAY [1..3] OF MotorOutputs;  //Structure
        MotorTotal := INT;
    END_VAR
    

    //find number of elements in Motors array

    MotorTotal := Do Something
    

    // Loop through Motors - do something

    Motors[1](IP:=MotorIP[1], OP=>MotorOP[1]);
    Motors[2](IP:=MotorIP[2], OP=>MotorOP[2]);
    Motors[3](IP:=MotorIP[3], OP=>MotorOP[3]);
    
    IF SystemStop OR OverloadTripped THEN   
        FOR i := 1 TO MotorTotal DO       
            MotorIP[i].Start:=FALSE;
            MotorIP[i].Stop:=TRUE;
        END_FOR
    END_IF
    

    Is there a way to retrieve the number of elements in an array of function blocks that will still be correct if the function block is changed?
    Is there a better way to do this?

    Thanks for reading, any help is greatly appreciated.
    Shane

     

    Last edit: shane2977 2020-04-19
  • i-campbell

    i-campbell - 2020-04-19

    LOWER_BOUND(Motors,1) and UPPER_BOUND(Motors,1) will get you the array dimensions.
    https://help.codesys.com/webapp/_cds_datatype_array;product=codesys;version=3.5.15.0

    It is also possible to make a constant (VAR_GLOBAL CONSTANT or VAR CONSTANT) and use that everywhere...

    VAR_GLOBAL CONSTANT
        MaxMotors := 3;
        MinMotors := 1;
    END_VAR
    VAR
        Motors      :   ARRAY [MinMotors..MaxMotors] OF Motor;
    END_VAR
    
     
    πŸ‘
    1

    Last edit: i-campbell 2020-04-19
  • shane2977 - 2020-04-19

    Thanks for getting me straightened out i-campbell.
    I came across the lower and upper bound operators while searching for my answer but it always seemed to have something to do with setting the size of an array dynamically so I just dismissed them.

    I really like the tip with the global constants. I will definitely incorporate that into my programs going forward.

    Thanks Again

     
    πŸ‘
    2

Log in to post a comment.