1

I need create certain amount of struct type pairs which will be further used as const parameters and has essentially the same set of values, but scaled in half, something like this (given a n constant):

TYPE ADDR_1 :
    STRUCT  
        PARAMETER_A:    INT :=0;
        PARAMETER_B:    INT :=2;
        PARAMETER_C:    INT :=4;
        - - - 
        PARAMETER_n:    INT :=n; (* being n any number *)
    END_STRUCT
END_TYPE

And the correlate pair:

TYPE ADDR_2 :
    STRUCT  
        PARAMETER_X:    INT :=0/2;
        PARAMETER_Y:    INT :=2/2;
        PARAMETER_Z:    INT :=4/2;
        - - - 
        PARAMETER_n/2:  INT :=n/2;  (* being n any number *)
    END_STRUCT
END_TYPE

By creating both structs sepparately it works pretty well, I use them to create a CONST array to be used at the SWITCH...CASE statement - which as we know well, only accepts constants at their indexes, not variables.

However every change made in one structure has to be refactored in another structure, indeed not a safe approach in therms of 'best practices' designing.

The problem which I'm facing now, is that if I create CONST values at the Global Variable List (GVL), it has not precedence in compilation timeline, I mean, structs are evaluated first.

Another option were by using Pragmas, but it works only within a specific scope, which mean it would not act as 'global parameters'.

I just wanted define each above parameter before compilation in such a way I could define just once, by dividing one by other by 2.

aluis.rcastro
  • 46
  • 1
  • 7
  • > However every change made in one structure has to be refactored in another structure, indeed not a safe approach in terms of 'best practices' designing. How those are constants then if you make changes there? – Sergey Romanov Mar 09 '20 at 07:38
  • Are you using Codesys 2 or 3? – Filippo Boido Mar 09 '20 at 13:11
  • I tested your setup with Twincat 3 (which uses the Codesys 3 compiler) and a constant from a GVL and had no compilation errors. – Filippo Boido Mar 09 '20 at 13:20
  • Hi @Filippo, I`m using Codesys 3 – aluis.rcastro Mar 09 '20 at 22:25
  • Hi @Sergey, I referred to "changes" in the context of the programming phase, not in runtime. I wanted to say that, if for example I add parameters in one structure, I need to add in another structure aswell, having the same (x2) scale, If I made mistake in this calculation, this will represent a weakeness on the current approach. – aluis.rcastro Mar 09 '20 at 22:31
  • Hi @Filippo, I used TwinCAT3 some time ago, and once it is based on the "Visual Studio IDE" there are lot of resources available there. Anyway, I was not referring to the above structure pair as the issue, but rather the lack of a way to create a 'global' preprocessor directive parameter (similar to ***#define***) which would be used in both structures above. – aluis.rcastro Mar 09 '20 at 22:36
  • So you are not having an issue with "n" and "n" being a constant global variable? – Filippo Boido Mar 10 '20 at 06:38
  • You said "The problem which I'm facing now, is that if I create CONST values at the Global Variable List (GVL), it has not precedence in compilation timeline, I mean, structs are evaluated first." But that is not correct, you can build your Struct with a predifined global constant and the value will be assigned at compile time.. – Filippo Boido Mar 10 '20 at 06:43
  • You can define first structure in CONSTANT scope and other in global vars only using constant as a base for the division. – Sergey Romanov Mar 10 '20 at 08:50
  • I would say that the solution would be something using both features both you recommended; The **EXTENDS** in particular is something that did not came to mind until now, it seems promising. As per the use of Global Variable it could not be done this way; note that as said, this structure will be used as the index of a **switch...case** arrangement, and only consts are allowed as indexes. (I will update this thread as long I make progress on this regard) – aluis.rcastro Mar 11 '20 at 01:41

2 Answers2

0

If you don't want to use constant global variables, but just "defines" as in C, then use Pragmas.

If you want your Pragma to have a global scope you can either put it in a global variable list or use inheritance instead. Here an inheritance example:

TYPE ST_Root :
STRUCT
    {IF defined (test) }
        n : INT := 1;
    {ELSE}
        n : INT := 2;
    {END_IF}
END_STRUCT
END_TYPE


TYPE ST_Derived EXTENDS ST_Root :
STRUCT
    x : INT := n + 1;
END_STRUCT
END_TYPE
Filippo Boido
  • 1,136
  • 7
  • 11
0

You will need only one structure.

TYPE ADDR :
    STRUCT  
        PARAMETER_A:    INT :=0;
        PARAMETER_B:    INT :=2;
        PARAMETER_C:    INT :=4;
    END_STRUCT
END_TYPE

First, define base as constant. That will create it first.

VAR_GLOBAL CONSTANT
    MyADR: ADDR := (PARAMETER_A := 0, PARAMETER_B := 2, ...);
END_VAR

Then create other global variables.

VAR_GLOBAL
    MyADRBy2: ADDR := (
        PARAMETER_A := MyADR.PARAMETER_A / 2, 
        PARAMETER_B := MyADR.PARAMETER_A / 2,
    ...);
END_VAR
Sergey Romanov
  • 2,949
  • 4
  • 23
  • 38