How Do You Link a TwinCAT 3 UNION Array to PROFINET?

James Nishida5 min read
BeckhoffIndustrial NetworkingTechnical Reference
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Before anything else, confirm the byte count. Each U_ByteReal occupies four bytes because its REAL and ARRAY[0..3] OF BYTE members overlay the same storage. The two PROFINET input blocks provide 200 bytes total, so they can populate 50—not 100—union elements.

Input Capacity and Immediate Decision

Item Calculation Result
Declared destination 100 elements × 4 bytes 400 bytes
PROFINET input 2 blocks × 100 bytes 200 bytes
Complete values available 200 bytes ÷ 4 bytes 50 elements
Values per input block 100 bytes ÷ 4 bytes 25 elements

Choose one of three outcomes before creating links: resize ricezione to ARRAY[0..49], keep 100 elements but mark indices 50 through 99 as unavailable, or expand the PROFINET process data to 400 bytes. Leaving the array at 100 elements without validity handling creates a stale-data fault: the final 50 values retain prior or initialized contents while appearing structurally valid.

The 100-byte block boundary is aligned to the four-byte union size. Block 0 ends after element 24, and block 1 starts at element 25; no REAL representation needs to cross the boundary.

Mapping Approach Comparison

Approach Links Byte-order handling Fit for this layout
Link individual bytes Up to 200 Explicit Works, but creates avoidable engineering effort and link-maintenance risk
Link directly into union storage Potentially two Implicit in memory layout Use only when the mapper exposes compatible contiguous destinations with matching sizes
Link two byte-array buffers, then unpack Two Explicit and testable Recommended

Use two process-image byte arrays as the mapping boundary. Link each 100-byte PROFINET block to one matching PLC array, then copy groups of four bytes into ricezione[].aBytes. This separates I/O configuration from application representation, makes byte order visible, and avoids maintaining hundreds of individual links.

The links remain static engineering-time mappings; the PLC does not discover or create them dynamically during execution. The automation comes from linking each contiguous block once and indexing the bytes in logic.

Recommended Bulk-Link Procedure

  1. Declare two 100-byte input-image buffers. Use AT %I* so TwinCAT exposes them as input symbols available for I/O linking. Resize ricezione to 50 elements unless another part of the program explicitly manages validity for the unused half.

    PROGRAM MAIN
    VAR
        aInputBlock0 AT %I* : ARRAY[0..99] OF BYTE;
        aInputBlock1 AT %I* : ARRAY[0..99] OF BYTE;
        ricezione : ARRAY[0..49] OF U_ByteReal;
        i : INT;
        j : INT;
    END_VAR

    Do not move on until the compiled PLC symbols show each input buffer as 100 contiguous bytes.

  2. In the TwinCAT I/O mapping, link the first 100-byte PROFINET input block to aInputBlock0 and the second block to aInputBlock1. Confirm that each source and destination reports the same byte length before activating the configuration.

  3. Copy four bytes per union element. Execute this logic before any application code reads ricezione[].rValue.

    
    

    This produces the boundary mappings aInputBlock0[0..3] to ricezione[0], aInputBlock0[96..99] to ricezione[24], aInputBlock1[0..3] to ricezione[25], and aInputBlock1[96..99] to ricezione[49].

  4. Keep the process-image buffers input-only and make the decoding loop the sole writer to ricezione. Multiple writers hide mapping or ordering faults and can produce values that change within one PLC cycle.

Byte Order and REAL Interpretation

A union changes how the same four memory bytes are viewed; it does not convert a wire representation. The resulting rValue is correct only when the sender’s four-byte floating-point representation and byte order match the order placed into aBytes[0..3].

Obtain the remote device’s process-data definition and identify whether each four-byte field is a floating-point value, an integer, or four unrelated status bytes. Then transmit one known nonzero value and compare its four raw input bytes with the device documentation. A zero test is inadequate because reversed zero bytes still produce zero.

If the documented order differs from PLC memory order, reverse or rearrange the indices during the copy. Apply the transformation at this single decoding boundary; do not alter the I/O links or scatter byte-swapping logic through downstream calculations.

Also confirm field alignment. This installation divides cleanly into 25 four-byte values per block. If a later module revision changes a block to a byte count not divisible by four, the remaining bytes must be carried into the next block or decoded according to the device’s field table.

Verification and Recurring Pitfalls

  1. Build the PLC project and check the reported symbol sizes: each input buffer must be 100 bytes, each U_ByteReal must be four bytes, and the 50-element destination must total 200 bytes.

  2. Activate the mapping and place the controller in the operating state required to exchange cyclic I/O. Confirm that the PROFINET node and both input blocks report valid cyclic data before judging the decoded values.

  3. Monitor the raw arrays first. Change a known field at the remote device and verify that exactly the expected four input bytes change in the expected block.

  4. Monitor ricezione[0], ricezione[24], ricezione[25], and ricezione[49]. These points test both ends of both mappings and catch off-by-one errors at the 100-byte boundary.

  5. Compare rValue with the known transmitted numeric value. If the raw bytes are correct but the numeric value is wrong, correct byte order or data-type interpretation rather than rebuilding the I/O links.

Symptom Likely cause Correction
Elements 50–99 never update Only 200 bytes exist for a 400-byte declaration Resize the array, add validity handling, or increase process data
Raw bytes change but rValue is implausible Wrong byte order or source field type Verify the device field definition and reorder bytes in the decoder
Element 25 repeats or skips data Second-block destination offset is wrong Start block 1 at ricezione[i + 25]
Values lag or change unpredictably Decode order or multiple writers Run the copy before consumers and retain one writer

FAQ

Can I link the full ricezione[0..99] array to two 100-byte blocks?

No. The array requires 400 bytes, while the two blocks supply 200 bytes. Only 50 four-byte U_ByteReal elements can be updated completely.

Can I map each PROFINET block with one TwinCAT 3 link?

Yes, when each PLC input symbol is a contiguous ARRAY[0..99] OF BYTE matching the corresponding 100-byte I/O object. Link the two buffers once, then decode 25 union elements from each block.

Does a UNION automatically correct PROFINET REAL byte order?

No. A union overlays bytes without converting them. The final verification step is to transmit a known nonzero numeric value, compare all four raw bytes, and confirm that rValue matches the transmitted value.

Back to blog