give a Name to array cell

freedumz
2017-05-05
2017-06-03
  • freedumz - 2017-05-05

    Hi Everyone
    I'm currently working on a project with a lot a data to send to a TouchScreen and as I'd like to optimize the communication speed, I have to use array
    But for example, I build an array with all the data for my motor so I obtain
    Motor1 array[1..10] of word;
    So if in my program I do:
    LD word1
    ST motor1[1]

    So I'd like if there is a way to give to this motor1 a name or a comment, so if I use my mouse on it, I could see the comment

    Many thanks in advance for your help

     

    Related

    Talk.ru: 1

  • Anonymous - 2017-05-05

    Originally created by: scott_cunningham

    Solution 1 (I recommend):

    Advantages:

    Disadvantages:

    Code Example:

    PROGRAM MapHmiData
    VAR
    END_VAR
    //copy drive1 data
    GVL_APP.HmiData[0] := INT_TO_WORD(GVL_APP.Drive1.ControlWord);
    GVL_APP.HmiData[1] := INT_TO_WORD(GVL_APP.Drive1.StatusWord);
    GVL_APP.HmiData[2] := REAL_TO_WORD(GVL_APP.Drive1.Temperature * 10); //0.1 deg C resolution
    GVL_APP.HmiData[3] := INT_TO_WORD(GVL_APP.Drive1.ActualCurrent);
    GVL_APP.HmiData[4] := DWORD_TO_WORD(SHR(GVL_APP.Drive1.HourCounter,16)); //high word
    GVL_APP.HmiData[5] := DWORD_TO_WORD(GVL_APP.Drive1.HourCounter); //low word
    //copy drive2 data
    GVL_APP.HmiData[6]  := INT_TO_WORD(GVL_APP.Drive2.ControlWord);
    GVL_APP.HmiData[7]  := INT_TO_WORD(GVL_APP.Drive2.StatusWord);
    GVL_APP.HmiData[8]  := REAL_TO_WORD(GVL_APP.Drive2.Temperature * 10); //0.1 deg resolution
    GVL_APP.HmiData[9]  := INT_TO_WORD(GVL_APP.Drive2.ActualCurrent);
    GVL_APP.HmiData[10] := DWORD_TO_WORD(SHR(GVL_APP.Drive2.HourCounter,16)); //high word
    GVL_APP.HmiData[11] := DWORD_TO_WORD(GVL_APP.Drive2.HourCounter); //low word
    //copy user data to controller
    GVL_APP.UserCtrl.AutoRun     := WORD_TO_BOOL(GVL_APP.HmiData[20]);
    GVL_APP.UserCtrl.CmdSpeed    := WORD_TO_INT(GVL_APP.HmiData[21]);
    GVL_APP.UserCtrl.CyclesToRun := GVL_APP.HmiData[22];
    

    Solution 2 (old school PLC programmer trick):

    Advantages:

    Disadvantages:

     
  • nothinrandom - 2017-06-01

    @scott_cunningham,

    You could definitely scale using:

    HmiData AT %IW101: ARRAY[1..10] OF WORD;

    This attaches array to memory : [%IW101, %IW102, %IW103, ...%IW110]

    Bad thing is all items must be of same data type.

     
  • jzhvymetal - 2017-06-02

    If you are using CoDeSys v3 which is assumed since this is posted in v3 section you could also use a reference to achieve this functionality. Reference is similar to a pointer but once you assign the reference you can use the variable just like any other variable.

    VAR
       arWord: ARRAY[0..10] OF WORD;
       rMyWord: REFERENCE TO WORD;
    END_VAR
    rMyWord REF= arWord[0];
    rMyWord:=777;  //arWord[0] will equal 777
    

    You could also use pointers but you need to deference the pointer with the ^ operand each time to use the value.

    VAR
       arWord: ARRAY[0..10] OF WORD;
       pMyWord1: POINTER TO WORD;
    END_VAR
    pMyWord1:=ADR(arWord[1]);
    pMyWord1^:=777;  //arWord[1] will equal 777
    
     

    Related

    Talk.ru: 1

  • Anonymous - 2017-06-02

    Originally created by: scott_cunningham

    I've been using references a lot lately - they are great when you don't need scaling or conversion. I would recommend to add an initializer to references when they are defined to at least avoid crashes (unreferenced reference written to usually writes into a really bad space).

    VAR
       SafeRef : WORD;
       MyRef1 : REFERENCE TO WORD := SafeRef;
       ...
    

    You can also use ```

    __IsValidRef()

    ``` to check - I will do that on FBs that have a state machine and I just define an init step.

    Of course, when there is scaling or conversion, I use my "solution 1"...

     
  • jzhvymetal - 2017-06-03

    scott_cunningham hat geschrieben:
    Of course, when there is scaling or conversion, I use my "solution 1"...

    Not sure what you mean by scaling but if you mean casting then there is trick that you can use by the combination of pointers and references to make it work. See below an example how to cast a part of a word array to a REAL reference. Just keep note of the data type size when using pointer and not to exceed the array bounds.

    VAR
       arWord: ARRAY[0..10] OF WORD;
       pMyREAL: POINTER TO REAL;
       rMyREAL: REFERENCE TO REAL;   
    END_VAR
    pMyREAL:=ADR(arWord[1]);
    rMyREAL REF= pMyREAL^;
    rMyReal:=777.777; // arWord[1] and arWord[2] would hold real value of 777.777
    
     

    Related

    Talk.ru: 1
    Talk.ru: 2

  • jzhvymetal - 2017-06-03

    nothinrandom hat geschrieben:
    @scott_cunningham,
    You could definitely scale using:
    HmiData AT %IW101: ARRAY[1..10] OF WORD;
    This attaches array to memory : [%IW101, %IW102, %IW103, ...%IW110]
    Bad thing is all items must be of same data type.

    Also if you mean casting the above is not true you would just define a second variable to cast it. All the example below would overlapp on memory thus automatically casting it

    myByte  AT %MB0   : BYTE; //Byte Type
    mySINT  AT %MB0   : SINT;
    myUSINT AT %MB0   : USINT;
    myByteArary AT %MB0 : ARRAY[0..10] OF BYTE; 
    myWORD  AT %MW0   : WORD; //16 bit types
    myINT   AT %MW0   : INT;
    myUINT  AT %MW0   : UINT;
    myWordArary AT %MW0 : ARRAY[0..10] OF WORD; 
    myDWORD AT %MD0   : DWORD; //32bit Types
    myDINT  AT %MD0   : DINT;
    myUDINT AT %MD0   : UDINT;
    myReal  AT %MD0   : REAL;
    myDwordArray AT %MD0 : ARRAY[0..10] OF DWORD;
    
     
  • Anonymous - 2017-06-03

    Originally created by: scott_cunningham

    I don't mean casting. Many times, data is a WORD but has a scaling. For example, temperature may have a resolution of 0.1 degrees on a device but may only use a WORD to store it. In that case, a raw value of 123 means 12.3 degrees. If I don't care about the fraction, I only want 12. Or a better example is a servo drive that has a speed resolution of 0.125 rpm (+/- 4000 rpm is +/- 32000 raw data). This is held in a WORD register in the servo. There is no reason in most cases to display 0.125 rom resolution - much easier to just adjust the raw to be +/- 1 rpm before sending it. In this case, a second variable and "scaling" is the solution.

    I just avoid at memory definitions - it obfuscates what's happening and requires someone to dig deeper to understand your code. I prefer to be explicit in my conversions at least, that's my style

     

Log in to post a comment.