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

STRUCT to BYTES

fabian
2022-06-28
2022-07-15
  • fabian - 2022-06-28

    Hello,

    I need to divide a STRUCT into 8-Byte portions (ULINT) in order to send them via CAN.
    Any suggestions and experience how this could be done? The size of the Structures is known (e.g. 256 Bytes).

    Many thanks and regards,
    Fabian

     
  • nothinrandom - 2022-07-12

    You could:
    1. use SIZEOF to get the total size of the STRUCT in bytes.
    2. use memcpy to copy chunks of 8 bytes at a time: https://help.codesys.com/webapp/ZidVRTnfzfI0LAYUwLYCsY_W-O4%2FMemCpy;product=MemoryUtils;version=3.5.17.0
    3. Increment index offset using while/for loop until you're at the end.

    don't have codesys open, but something like the below should work.

    // VAR
    uliData : ULINT;
    uiOffset : UINT := 0;
    pbStruct : POINTER TO BYTE;
    uiTotalSize : UINT := 0;
    uiDataBlock : UINT := 8;


    pbStruct := ADR(myStruct);
    uiTotalSize := SIZEOF(myStruct);

    WHILE uiOffset < uiTotalSize DO
    // check to see if divisible by 8 (e.g. STRUCT is 249 bytes instead of 256).
    // could use MOD, but costly
    IF (uiTotalSize - uiOffset < uiDataBlock) THEN
    uiDataBlock := uiTotalSize - uiOffset;
    END_IF
    uliData := 0; // reset to be sure
    // copy data from struct to ULINT
    MemCpy(pbyDest:=ADR(uliData), pbySrc:=pbStruct+uiOffset, dwSize:=uiDataBlock);
    // send data via CAN here
    // if success increment by uiDataBlock, else retry logic
    uiOffset := uiOffset + uiDataBlock;
    END_WHILE

     
  • fabian - 2022-07-12

    Hi nothingrandom,

    Many thanks for your answer, it works like it should!
    I was struggling yesterday with memcpy as it was not clear to me that only 1 byte at a time can be copied.

    Now I only have the problem, that my STRUCT contains BOOLEANS and they unfortunately occupy 1 Byte instead of 1 Bit only which then extends the length of the structure unintended. (The BOOL should only occupy 1 bit on the CAN as the receiver side is given)
    I already noticed that this is a known topic and I will do some more research on that - unless you have a solution in your pocket? :-)

    A typical structure for 32-Bytes could look like this:

    TYPE MyStruct :
    STRUCT
        UINT1:      UINT;    //Offset 0
        BOOL1:      BOOL;    //Offset 16
        BOOL2:      BOOL;    //Offset 17
        BOOL3:      BOOL;    //Offset 18
        BOOL4:      BOOL;    //Offset 19
        BOOL5:      BOOL;    //Offset 20
        BOOL6:      BOOL;    //Offset 21
        BOOL7:      BOOL;    //Offset 22
        BOOL8:      BOOL;    //Offset 23
        BOOL9:      BOOL;    //Offset 24
        BOOL10:     BOOL;    //Offset 25
        BOOL11:     BOOL;    //Offset 26
        BOOL12:     BOOL;    //Offset 27
        BOOL13:     BOOL;    //Offset 28
        BOOL14:     BOOL;    //Offset 29
        BOOL15:     BOOL;    //Offset 30
        BOOL16:     BOOL;    //Offset 31
        BOOL17:     BOOL;    //Offset 32
        BOOL18:     BOOL;    //Offset 33
        BOOL19:     BOOL;    //Offset 34
        BOOL20:     BOOL;    //Offset 35
        BOOL21:     BOOL;    //Offset 36
        BOOL22:     BOOL;    //Offset 37
        BOOL23:     BOOL;    //Offset 38
        BOOL24:     BOOL;    //Offset 39
        BOOL25:     BOOL;    //Offset 40
        BOOL26:     BOOL;    //Offset 41
        BOOL27:     BOOL;    //Offset 42
        BOOL28:     BOOL;    //Offset 43
        BOOL29:     BOOL;    //Offset 44
        BOOL30:     BOOL;    //Offset 45
        BOOL31:     BOOL;    //Offset 46
        BOOL32:     BOOL;    //Offset 47
        INT1:       INT;    //Offset 48
        INT2:       INT;    //Offset 64
        INT3:       INT;    //Offset 80
        INT4:       INT;    //Offset 96
        INT5:       INT;    //Offset 112
        INT6:       INT;    //Offset 128
        INT7:       INT;    //Offset 144
        INT8:       INT;    //Offset 192
        UINT2:      UINT;    //Offset 208
        UINT3:      UINT;    //Offset 224
        UINT4:      UINT;    //Offset 240
    END_STRUCT
    END_TYPE
    

    Many thanks and best regards,
    Fabian

     
  • fabian - 2022-07-12

    Hi,

    I have solved the problem by packing the bits into bytes (and changing the STRUCT accordingly).

    Thanks and regards,
    Fab

     
  • nothinrandom - 2022-07-13

    You could also just use bits of a UDINT since it also has 32 bits. For example:

    udiTest : UDINT;

    udiTest.0 = TRUE; // same as BOOL1
    udiTest.1 = False; // same as BOOL2

     

Log in to post a comment.