Bool to Word Conversion in TIA Portal S7-400: SCL AT Method

David Krause12 min read
S7-400SiemensTechnical 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

Overview: Bool/Word Bit Mapping on S7-400 in TIA Portal V11 SP2

Grouping 16 Boolean signals into a single 16-bit WORD and re-distributing them again is a recurring task when an S7-416F exchanges status with a Siemens DCM, a third-party PLC, or any device that only speaks 16-bit parallel or word-oriented protocols. The challenge on a classic S7-400 under TIA Portal V11 SP2 / Update 4 is that the convenient "LAD/FBD bit-splitter" boxes that exist in the S7-1200/1500 library are not always available, the STL editor still hides a number of protected conversion blocks, and the SCL AT overlay behaves differently inside an FC than inside a DB or an FB static area.

This reference consolidates the field-proven techniques for Word ↔ Bool, Word ↔ Byte, and Word ↔ INT/DINT conversion on an S7-400 CPU (41x series) running TIA Portal V11 SP2, including the formal-parameter pitfall that causes "You cannot overlay an array on that type" when the AT view is declared on a non-VAR_IN_OUT FC parameter.

Prerequisites

  • TIA Portal V11 SP2 with Update 4 (or V12/V13 for newer projects).
  • S7-400 CPU in the 41x family (e.g., CPU 416F-3 PN/DP, 416-3, 414-3). S7-300 (31x) follows the same rules; the example blocks compile unchanged on 31x/41x.
  • S7-PCT or the SIMATIC Manager importer only required if you migrate legacy STEP 7 V5.x STL sources.
  • Basic knowledge of SCL data types: BOOL, BYTE, WORD, INT, DINT, ARRAY, AT.

Data Type Mapping Reference

The S7-400 stores all tags in little-endian byte order. A WORD occupies two bytes; bit 0 is the LSB of the low byte, bit 15 is the MSB of the high byte. The following table is the contract every conversion FC must respect.

S7 Data Type Length (bits) Range Bit-0 Position Signed?
BOOL 1 0 / 1 No
BYTE 8 0 .. 255 (B#16#FF) Lowest of byte No
WORD 16 W#16#0000 .. W#16#FFFF Lowest of low byte No
INT 16 -32768 .. +32767 Lowest of low byte Yes (two's complement)
DINT 32 -2147483648 .. +2147483647 Lowest of byte 0 Yes
DWORD 32 DW#16#0000_0000 .. DW#16#FFFF_FFFF Lowest of byte 0 No
REAL 32 IEEE-754 single Lowest of byte 0 Yes (sign/mantissa/exponent)
Bit numbering convention: Siemens counts bit 0 as the LSB. When you read documentation from third-party PLCs that label bit 0 as the MSB (Allen-Bradley, Modicon), you must mirror the mapping. The S7 AT overlay always follows the Siemens convention.

Method 1 — SCL AT Overlay (Fastest, Recommended)

The AT construct lets you view the same memory location with a different data type. On an S7-400 with TIA Portal V11 SP2, AT works inside FB static, DB, and FC/FB VAR_IN_OUT sections. It does not work on plain VAR_INPUT or VAR_OUTPUT parameters of an FC — that is the source of the "cannot overlay an array on that type" compile error.

Working FC Pattern: WORD → 16 BOOL (VAR_IN_OUT)

FUNCTION FC100 : VOID
VAR_IN_OUT
    wSource  : WORD;       // pass by reference, AT is allowed here
END_VAR
VAR_TEMP
    aBits : ARRAY[0..15] OF BOOL;  // AT overlay declared on a TEMP
    i     : INT;
END_VAR
BEGIN
    aBits AT wSource;      // valid: TEMP ATs an IN_OUT parameter
    // ... consumer logic that reads aBits[0]..aBits[15]
END_FUNCTION

Working FC Pattern: 16 BOOL → WORD (VAR_IN_OUT + return)

FUNCTION FC101 : VOID
VAR_IN_OUT
    wTarget : WORD;
END_VAR
VAR_INPUT
    bBit00  : BOOL;
    bBit01  : BOOL;
    bBit02  : BOOL;
    bBit03  : BOOL;
    bBit04  : BOOL;
    bBit05  : BOOL;
    bBit06  : BOOL;
    bBit07  : BOOL;
    bBit08  : BOOL;
    bBit09  : BOOL;
    bBit10  : BOOL;
    bBit11  : BOOL;
    bBit12  : BOOL;
    bBit13  : BOOL;
    bBit14  : BOOL;
    bBit15  : BOOL;
END_VAR
VAR_TEMP
    aBits : ARRAY[0..15] OF BOOL;
END_VAR
BEGIN
    aBits[0]  := bBit00;
    aBits[1]  := bBit01;
    aBits[2]  := bBit02;
    aBits[3]  := bBit03;
    aBits[4]  := bBit04;
    aBits[5]  := bBit05;
    aBits[6]  := bBit06;
    aBits[7]  := bBit07;
    aBits[8]  := bBit08;
    aBits[9]  := bBit09;
    aBits[10] := bBit10;
    aBits[11] := bBit11;
    aBits[12] := bBit12;
    aBits[13] := bBit13;
    aBits[14] := bBit14;
    aBits[15] := bBit15;
    aBits AT wTarget;       // write back through the overlay
END_FUNCTION

Each call moves a full 16-bit word in microseconds because the compiler reduces the array assignment to a single L W / T W pair in the generated STL. No loop, no shift, no BTI/ITB conversion is needed.

Method 2 — DB-Based AT Overlay (Useful for Multi-Word Buses)

When the conversion has to work on a contiguous range of words (for example, 64 words of Profibus PII on a Siemens DCM), define the AT overlay directly in a global DB. This avoids passing 64 VAR_IN_OUT parameters.

DATA_BLOCK DB200
STRUCT
    wRaw      : ARRAY[0..63] OF WORD;
    aRawBits  AT wRaw : ARRAY[0..63, 0..15] OF BOOL;
END_STRUCT
END_DATA_BLOCK

To extract bit 7 of word 12: aRawBits[12, 7]. To set bit 3 of word 40: aRawBits[40, 3] := TRUE;. The compiler emits a single bit-access instruction. Memory cost is zero beyond the words themselves; the AT view is purely symbolic.

Method 3 — Shift & Mask (Works Without AT)

On older STEP 7 V5.x projects or whenever AT cannot be used, the shift-and-mask pattern still works. It is the approach the protected Siemens STL conversion block uses internally, except you implement it in SCL where one line replaces a paragraph of STL.

WORD → 16 BOOL via SHR

FUNCTION FC110 : VOID
VAR_IN_OUT
    wSource : WORD;
END_VAR
VAR_OUTPUT
    aBits   : ARRAY[0..15] OF BOOL;
END_VAR
VAR_TEMP
    wWork : WORD;
    i     : INT;
END_VAR
BEGIN
    wWork := wSource;
    FOR i := 0 TO 15 DO
        aBits[i] := (wWork AND W#16#0001) <> W#16#0000;
        wWork := SHR(IN := wWork, N := 1);
    END_FOR;
END_FUNCTION

16 BOOL → WORD via SHL

FUNCTION FC111 : WORD
VAR_INPUT
    aBits : ARRAY[0..15] OF BOOL;
END_VAR
VAR_TEMP
    wWork : WORD;
    i     : INT;
END_VAR
BEGIN
    wWork := W#16#0000;
    FOR i := 0 TO 15 DO
        IF aBits[i] THEN
            wWork := wWork OR SHL(IN := W#16#1, N := i);
        END_IF;
    END_FOR;
    FC111 := wWork;
END_FUNCTION

Run-time cost: 16 loop iterations × (mask + shift) ≈ 20 µs typical on a CPU 416-3. For a one-off conversion in OB1 this is irrelevant; for tight cyclic tasks (< 1 ms) prefer the AT overlay of Method 1.

Method 4 — Word ↔ INT Conversion and the 32767 Boundary

The S7-400 uses 16-bit two's-complement for INT. Converting WORD to INT with a value above 32767 produces a negative result; converting a negative INT to WORD gives the corresponding unsigned bit pattern. The Siemens example block for the S7-1200 detects this by comparing the intermediate INT against 32756 and then OR-ing in bit 15 if the value is negative — that is why the AT view of a WORD directly as a 16-bit ARRAY OF BOOL is the cleaner solution on S7-400.

WORD (hex) WORD (dec) INT (dec) Bit 15 Bit 14..0
W#16#0000 0 0 0 0
W#16#7FFF 32767 32767 0 all 1
W#16#8000 32768 -32768 1 0
W#16#8001 32769 -32767 1 1
W#16#C000 49152 -16384 1 10..0 = 0
W#16#FFFF 65535 -1 1 all 1

One-line SCL conversions:

iSigned   := WORD_TO_INT(wSource);   // signed -32768..32767
iUnsigned := INT_TO_WORD(iSigned);   // bit-pattern preserved
dwPattern := WORD_TO_DWORD(wSource); // zero-extend to 32 bits
wLowByte  := wSource AND W#16#00FF;  // low byte
wHighByte := SHR(IN := wSource AND W#16#FF00, N := 8); // high byte
wReassembled := wLowByte OR wHighByte; // rebuild word

Diagnosing the "Cannot Overlay an Array on That Type" Error

The most common error reported when porting an SCL conversion FC to TIA Portal V11 SP2 on an S7-400 is:

Compile error: You cannot overlay an array on that type.
FC100, line 14:   aBits AT wSource;

Root cause and fix table:

Symptom Likely Root Cause Fix
AT declared on VAR_INPUT Inputs are by value, not addressable Change to VAR_IN_OUT
AT declared on VAR_OUTPUT Same as above; AT on a temp of the output is allowed Use a VAR_TEMP AT and write back manually
AT on a constant Constants live in a read-only load memory area Copy to a temporary first
AT on a multi-element ARRAY AT target must match the source length exactly Declare same element count and type
AT on a STRING/WSTRING Length prefix differs from the array Use AT on a BYTE array of declared length
AT inside a library-derived type Versioned type does not allow overlay Derive a new UDT and AT to that UDT
Workaround when the calling site cannot supply a VAR_IN_OUT: read the input into a VAR_TEMP, perform the conversion there, and write the result back to the output. The temp-and-copy pattern costs 1 extra load and 1 extra store per call but works on every CPU 41x firmware.

STL Alternative for STEP 7 V5.x and TIA Portal STL

For users who prefer STL (or must maintain a legacy STL source file), the pattern is two instructions per bit plus a final pack. The block can be exported from a STEP 7 V5.5 STL source and re-imported into TIA Portal V11 SP2 as an external source.

// STL: WORD <- 16 BOOLs (bBit00..bBit15) packed into ACC1
      L   W#16#0
      L   bBit15
      SLW 1
      OW
      L   bBit14
      SLW 1
      OW
      ...
      T   wTarget

If TIA rejects the imported STL, open the external source file, save it as .scl instead of .awl, and re-import. The SCL compiler accepts the same logical operations with full visibility into the generated code. STL remains officially unsupported for S7-1200, but it is fully supported on S7-300/400 in TIA Portal V11 SP2 — the editor enables it under Options > Settings > PLC programming > STL.

Sample Project: 16-Bit Status from Siemens DCM

A typical use case: a Siemens DCM (DC MASTER / SINAMICS DCM) returns 16 bits of status word 1 in PZD2. The application must split it into 16 individual BOOL tags for an HMI tag list.

  1. Create a global DB DB_DCM_Status with a single WORD tag wStatus1.
  2. Add an AT overlay aStatus1Bits AT wStatus1 : ARRAY[0..15] OF BOOL; in the same DB.
  3. In OB1, copy the received PZD2 word into DB_DCM_Status.wStatus1 using MOVE_BLK or a direct assignment.
  4. Wire the HMI tags to DB_DCM_Status.aStatus1Bits[0]..[15]. The HMI tag list shows them as 16 individual Boolean points.
  5. For the reverse direction (HMI commands back to DCM), define a second DB with a 16-BOOL array AT'd to a WORD, and let the HMI write the bits.

No FC, no loop, no shift, no protected library block. The runtime cost is one MOVE per cycle.

Verification Checklist

  1. Compile the SCL source — no warnings on AT overlays.
  2. Download to the S7-416F in STOP mode, then RUN.
  3. Force wSource = W#16#AAAA (binary 1010_1010_1010_1010). The bits should read 0,1,0,1,... LSB-first.
  4. Force wSource = W#16#5555 (binary 0101_0101_0101_0101). Confirm the inverse pattern.
  5. Force wSource = W#16#0001; confirm only aBits[0] is TRUE.
  6. Force wSource = W#16#8000; confirm only aBits[15] is TRUE and the INT view reads -32768.
  7. Force wSource = W#16#FFFF; confirm the INT view reads -1, not 65535.
  8. Watch the OB1 cycle time with RUNTIME; conversion should add < 5 µs per call.

Troubleshooting Matrix

Symptom Likely Cause Remedy
Compile error "cannot overlay an array on that type" AT declared on VAR_INPUT or VAR_OUTPUT Move AT to VAR_IN_OUT or to a VAR_TEMP
All 16 bits read FALSE despite a non-zero word Byte swap in Profibus/Profinet word Apply WORD_TO_BLOCK_DB swap or swap bytes manually
Bit 7..0 mirror bit 15..8 Third-party PLC uses big-endian Swap high and low bytes before AT
INT conversion returns negative number unexpectedly Word value > 32767 Use WORD_TO_DINT and mask with 16#FFFF
STL import fails in TIA Portal Source file extension wrong Rename to .scl and re-import
SFC / SFB protected block gives wrong bit order Library block is for S7-1200 Replace with SCL AT overlay as in Method 1
Online value of aBits differs from wSource Watch table shows symbolic AT only Watch the underlying WORD; the AT is a view, not a copy
Conversion runs only in OB1, not in OB35 FB instance DB has its own AT scope Pass the word via VAR_IN_OUT of the FB

Performance & Memory Footprint

Method Code Size (bytes, FC) Work Memory (bytes) Run-time @ CPU 416-3
AT overlay (Method 1) ~80 0 (view only) < 1 µs
DB AT overlay (Method 2) 0 (no FC) 0 (view only) < 1 µs per bit
Shift & mask (Method 3) ~250 4 (temp word) ~20 µs
STL pack/unpack ~400 2 (ACC1) ~10 µs
Protected Siemens block (S7-1200 library) ~600 12 ~35 µs

For most S7-416F applications driving an HMI or Profibus peer, Method 1 or 2 is the correct choice. Use Method 3 only when AT is genuinely unavailable (for example, when the formal parameter comes from a function block whose interface you cannot change).

Migration Notes from STEP 7 V5.x

If you are importing the conversion FC from an existing STEP 7 V5.5 project, the .awl source will load into TIA Portal V11 SP2 via Project > External source files > Import. If the import reports "STL is not permitted in this CPU family", the S7-1200/1500 STL restriction has been mis-applied; verify the active device is still the S7-400. If the imported source still uses the V5.x symbol table syntax (for example, DB100.DBW0), regenerate the symbols under the new TIA Portal tag naming. The AT overlay itself is unchanged.

Frequently Asked Questions

Why does the SCL compiler reject "AT" on a WORD input parameter of my FC on an S7-400?

AT overlays require an addressable memory area. VAR_INPUT and VAR_OUTPUT parameters of an FC are passed by value, not by reference, so the compiler cannot bind an AT view to them. Change the parameter to VAR_IN_OUT (pass-by-reference) or copy the input into a VAR_TEMP and AT the temp.

How do I split a WORD into 16 individual BOOL tags for the HMI on TIA Portal V11 SP2?

Create a global DB with a WORD tag and an ARRAY[0..15] OF BOOL AT view of the same tag. Wire the 16 array elements to your HMI tags. No conversion FC is required, and the HMI reads each bit directly through the symbol.

What is the difference between WORD and INT when bit 15 is set?

A WORD treats bit 15 as the value 32768 (unsigned 0..65535). An INT treats the same bit pattern as -32768 (signed two's-complement -32768..32767). The bit pattern is identical; only the interpretation changes. Convert with WORD_TO_INT or INT_TO_WORD explicitly when crossing the 32767 boundary.

Can I use the S7-1200 Siemens conversion library block on an S7-416F?

No. The S7-1200 example blocks rely on protected library FCs and the 1200/1500 STL restriction rules; they either fail to import or generate wrong results on a 41x CPU. Use the SCL AT overlay technique described in Method 1 instead — it compiles on S7-300, S7-400, and WinAC.

How do I import a legacy STEP 7 V5.x STL conversion block into TIA Portal V11 SP2?

Right-click External source files in the project tree, choose Import, and select the .awl file. If the import fails, rename the file to .scl and re-import; the SCL compiler accepts the same logical operations and shows the generated STL. STL is fully supported on S7-300/400 in TIA Portal; ensure your active device is the S7-400 and not an S7-1200.

Back to blog