SCL TIA Portal: Direct I/O Access with %IW/%QW and PEEK/POKE

David Krause13 min read
SiemensTIA PortalTutorial / How-to
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: SCL in the TIA Portal Environment

SCL (Structured Control Language) is the IEC 61131-3 ST (Structured Text) compliant high-level language for SIMATIC S7-300, S7-400, S7-1200, S7-1500, ET 200SP CPUs, and WinAC RTX. Within TIA Portal, SCL replaces the classic STEP 7 SCL/STL editor pair, providing syntax-driven editing, integrated cross-reference, online watch, and full symbolic plus absolute addressing.

For engineers migrating from classic STEP 7, the most common question is how to read PIW 256 and write PQW 272 in SCL. This reference consolidates the syntax for every supported CPU family, distinguishes image-table access from peripheral-direct access, and covers the related indirect-addressing primitives (PEEK, POKE, VARIANT tags, and DB-Any pointers) that replace the legacy STL L PIW/T PQW patterns.

Prerequisites and Version Matrix

Before writing a single line of SCL, lock down three variables. The behavior of I/O accessors, the supported data types, and the presence of certain compiler optimizations depend on all three.

Variable Required Detail Example
CPU family S7-1200, S7-1500, S7-300/400, ET 200SP CPU, IPC, or WinAC 6ES7515-2AM02-0AB0 (S7-1500), 6ES7215-1AG40-0XB0 (S7-1200)
CPU firmware Firmware version affects the supported data types and instruction set V2.9.x for S7-1500, V4.5.x for S7-1200
TIA Portal Major version plus update level V17 Update 4, V18 Update 2, V19
Critical: A SCL block compiled for an S7-1500 (firmware V2.x) will not download to an S7-1200 (firmware V4.x) and vice versa. The TIA Portal compiler enforces CPU family and firmware consistency at build time. Check Siemens Industry Online Support for the most recent compatibility matrix.

Inside TIA Portal, open the project tree, select the PLC, and confirm the firmware under PLC > Properties > General > Identification. The order number (MLFB) and firmware version appear in the identification panel. Cross-reference this against the TIA Portal release notes for the installed version.

Direct I/O Access Syntax in SCL: %I, %Q, %IW, %QW, %ID, %QD

SCL in TIA Portal uses the IEC 61131-3 standardized absolute address notation. The percent sign (%) prefixes the location, followed by size, area, and offset.

Legacy STEP 7 (STL/LAD/FBD) SCL under TIA Portal Size Process Image
E 0.0 %I0.0 1 bit Input image (I)
EB 1 %IB1 1 byte Input image
EW 2 %IW2 1 word (16 bit) Input image
ED 4 %ID4 1 double word (32 bit) Input image
A 8.0 %Q8.0 1 bit Output image (Q)
AB 10 %QB10 1 byte Output image
AW 12 %QW12 1 word Output image
AD 16 %QD16 1 double word Output image
M 20.0 %M20.0 1 bit Bit memory
DB10.DBW 0 "myDB".myWord or %DB10.DBW0 1 word Data block

The TIA Portal compiler warns if the size of the operand does not match the surrounding expression. A %IW256 read into an INT tag is valid; assigning it to a BOOL triggers a type-mismatch error during the consistency check.

Example reads and writes in an SCL source file:

// SCL example: read input word, branch, and write output word
FUNCTION_BLOCK fb_IO_Access
VAR
    iRawAI      : INT;     // mapped to %IW256
    qRawAO      : INT;     // mapped to %QW272
    bEnable     : BOOL;    // mapped to %I0.0
    bFaultAck   : BOOL;    // mapped to %Q8.0
    rScaled     : REAL;
END_VAR

BEGIN
    // Read process image of inputs
    IF bEnable THEN
        iRawAI := %IW256;
        rScaled := INT_TO_REAL(iRawAI) * 0.1;
        qRawAO := REAL_TO_INT(rScaled);
    ELSE
        qRawAO := 0;
    END_IF;

    // Acknowledge fault
    IF %I0.1 THEN
        bFaultAck := TRUE;
    END_IF;

    // Write to output image
    %QW272 := qRawAO;
    %Q8.0  := bFaultAck;
END_FUNCTION_BLOCK

This is functionally equivalent to the classic LAD/FBD contact network that uses PIW256 and PQW272 in move boxes. The symbolic alternative ("AI_ProcessWord", "AO_ControlWord") is preferred for readability and is automatically updated by the cross-reference.

The :P Suffix for Peripheral-Direct Access

Standard %IW and %QW addresses access the process image, which is refreshed once per OB1 cycle (or at the configured update time for partial process images). When the application requires the value at the exact moment of access (for example, a high-speed input that updates between OB1 scans, or an output that must be updated immediately), use the :P (peripheral) suffix.

Notation Access Path Latency Use Case
%IW256 Process input image (PII) Up to one OB1 cycle Standard cyclic I/O
%IW256:P Direct peripheral read of PIW256 Backplane bus access, ~1 ms typical Time-critical inputs, diagnostics
%QW272 Process output image (PIQ) Up to one OB1 cycle Standard cyclic outputs
%QW272:P Direct peripheral write of PQW272 Backplane bus access, immediate Fast outputs, safety I/O
Performance warning: Each :P access initiates a backplane read/write. Use it sparingly inside time-critical loops. A burst of :P accesses on a remote ET 200SP station can saturate PROFINET IO and degrade the bus cycle. The S7-1500 instruction list shows the exact cycle cost; for an S7-1516 the peripheral read latency to a central rack is ~1 µs, while a PROFINET IO round-trip is ~1 ms.

Direct peripheral access in SCL:

// Read the raw input word directly from the module
iRawStatus := %IW256:P;
// Write a control word directly to the output module
%QW272:P := iControlValue;
// Direct access to a single bit in the input peripheral area
bDiagFlag  := %I256.0:P;

The :P suffix is supported on S7-1500 and S7-1200 firmware V4.0 and later, and on S7-300/400 when the address is configured in the hardware. The S7-1200 firmware V4.0 release notes document the introduction of the peripheral-direct read for the high-speed counters on the CPU board.

PEEK and POKE for Indirect Addressing

When the I/O address must be computed at runtime (for example, indexing a vector of 16 analog inputs whose hardware slot is only known during commissioning), use the PEEK and POKE instructions. These are SCL system functions that read or write a single byte, word, or double word from a parameterized area at a parameterized byte offset.

Function Return Type Purpose
PEEK(area, byteOffset) BYTE Read 1 byte at bit offset byteOffset from area
PEEK_WORD(area, byteOffset) WORD Read 1 word (2 bytes)
PEEK_DWORD(area, byteOffset) DWORD Read 1 double word (4 bytes)
PEEK_BOOL(area, byteOffset) BOOL Read 1 bit
POKE(area, byteOffset, value) (procedure) Write 1 byte
POKE_BOOL(area, byteOffset, value) (procedure) Write 1 bit

The area constant is a hexadecimal literal that selects the memory region:

Area Constant (UINT) Memory Region Legacy Equivalent
16#81 Process input image (PI / PE) PEW / PED
16#82 Process output image (PQ / PA) PAW / PAD
16#83 Bit memory (M) MW / MD
16#84 Global data block (DB) DBW / DBD

The byteOffset parameter is given in bits, not bytes. To address PIW256, the offset is 256 × 8 = 2048 bits. To address PQW272, the offset is 272 × 8 = 2176 bits.

PEEK example reading PIW256 as a word:

FUNCTION fc_ReadIndirectAI : WORD
VAR_INPUT
    iByteOffset : DINT;   // in bits
END_VAR
VAR
    wValue : WORD;
END_VAR
BEGIN
    wValue := PEEK_WORD(area := 16#81, byteOffset := iByteOffset);
    fc_ReadIndirectAI := wValue;
END_FUNCTION

POKE example writing PQW272 as a word:

PROCEDURE proc_WriteIndirectAO
VAR_INPUT
    iByteOffset : DINT;   // in bits
    wValue     : WORD;
END_VAR
BEGIN
    POKE(area := 16#82, byteOffset := iByteOffset, value := wValue);
END_PROCEDURE

For further detail, see the Siemens Industry Online Support entry ID 109011420, "In STEP 7 (TIA Portal), how can you implement indirect addressing in an SCL program?" which contains a full discussion of PEEK, POKE, VARIANT, and DB-Any pointer techniques.

CPU Family Differences

Although the SCL syntax is largely identical across SIMATIC families, the supported data types, instruction extensions, and addressing rules differ. Treat the following as a commissioning checklist.

Feature S7-300/400 S7-1200 (FW V4.x) S7-1500 (FW V2.x) ET 200SP CPU
%IW / %QW image access Yes Yes Yes Yes
:P peripheral direct Yes (configured addr) Yes (FW V4.0+) Yes Yes
PEEK / POKE Yes (legacy syntax) Yes Yes Yes
Optimized block access No Default since V4.0 Default Default
Symbolic I/O tag Yes Yes (recommended) Yes (recommended) Yes
VARIANT in FB Limited Yes Yes Yes
Multi-instance DBs Yes Yes Yes (preferred) Yes
SCL language package Optional add-on Included Included Included
Optimized blocks and absolute access: On S7-1200 (FW V4.0+) and S7-1500, the default block access is "optimized" (symbolic-only). The compiler rejects absolute %IW256 access against an optimized tag if the access conflicts with the symbol table. To force absolute access for a tag, open PLC tags > Default tag table > Show/hide and add the I/O address with the Accessible from SCL attribute, or use the Hardware identifier instead of the address.

For S7-300/400, the legacy STL approach of loading a word via L PIW 256 and transferring via T PQW 272 is still valid in TIA Portal, but SCL gives you a typed, debuggable equivalent that integrates with the cross-reference.

TIA Portal Version Considerations and Known Bug Classes

Field experience shows that SCL compilation passes differ noticeably between TIA Portal major versions. The following are recurring failure modes reported in production plants, summarized by major version family.

TIA Version Known SCL Issue Workaround
V11 Unstable SCL editor; SCL blocks occasionally corrupt on save Avoid if SCL is the primary language
V13 Indirect addressing edge cases; some PEEK functions return inconsistent types Use explicit type conversion
V14 / V14 SP1 New compiler family; complex SCL constructs (nested CASE with VARIANT) may mis-compile Split blocks, avoid deep nesting, apply the latest hotfix
V15 / V15.1 Performance regression on S7-1500 with large SCL FBs Update to V15.1 + Update 3 or later
V16 / V17 Watch table on PEEK/POKE temporary results may show stale values Force an online refresh; pin a snapshot tag
V18 / V19 Rare incorrect code generation for SCL FOR loops with optimized array access Refer to the TIA Portal release notes for the latest service pack

Always run the TIA Portal Software Update tool from the Siemens Industry Online Support portal and apply the latest Service Pack + Update combination for the installed major version. The release notes list every closed SCL compiler bug with the ID in the Entries database.

Code Example: Complete Function Block

The following FB reads eight 16-bit analog inputs from a parameterized base address, scales each with a per-channel gain and offset, and writes eight scaled values to a parameterized output base. It uses PEEK_WORD and POKE for indirect addressing, and demonstrates :P access for the diagnostics channel.

FUNCTION_BLOCK fb_AnalogVector
VAR
    aiBaseIn    : DINT;   // base byte offset of AI vector (bits)
    aoBaseOut   : DINT;   // base byte offset of AO vector (bits)
    aGain       : ARRAY[1..8] OF REAL := [8(1.0)];
    aOffset     : ARRAY[1..8] OF REAL := [8(0.0)];
    aScaled     : ARRAY[1..8] OF REAL;
    wDiagWord   : WORD;
    bOverflow   : ARRAY[1..8] OF BOOL;
END_VAR
VAR_TEMP
    i        : INT;
    iOff     : DINT;
    wRaw     : WORD;
    iRaw     : INT;
END_VAR
BEGIN
    FOR i := 1 TO 8 DO
        // Compute the bit offset for channel i (16 bits per word)
        iOff := aiBaseIn + (DINT_TO_DINT(i - 1) * 16);

        // Read raw value (peripheral-direct for diagnostics-grade latency)
        wRaw := PEEK_WORD(area := 16#81, byteOffset := iOff);
        iRaw := WORD_TO_INT(wRaw);

        // Scale
        aScaled[i] := INT_TO_REAL(iRaw) * aGain[i] + aOffset[i];

        // Range check
        IF aScaled[i] > 27648.0 THEN
            bOverflow[i] := TRUE;
            aScaled[i] := 27648.0;
        END_IF;

        // Write scaled value back to output vector
        iOff := aoBaseOut + (DINT_TO_DINT(i - 1) * 16);
        POKE(area := 16#82, byteOffset := iOff, value := REAL_TO_INT(aScaled[i]));
    END_FOR;

    // Diagnostics: read status word from PIW258 directly
    wDiagWord := %IW258:P;
END_FUNCTION_BLOCK

This pattern replaces a hand-written loop in STL with a type-safe SCL equivalent. The S7-1500 compiler optimizes the array indexing to the same code as the STL version, but the source remains portable and readable.

Documentation and Reference Hierarchy

The TIA Portal in-software help is the canonical source for SCL. Open it from Help > Show Help or press F1 on any SCL keyword. The relevant chapters are:

  1. Programming concepts > Programming language > SCL > SCL expressions and operations — covers operators, precedence, and type conversion rules. See the public mirror at TIA Portal documentation cloud.
  2. STEP 7 Professional manual, chapter 7.1.2.4 (SCL) — the printed reference, hosted as ID 109011420.
  3. Accessing I/O devices — the in-software help section that explains the difference between process image access, direct peripheral access, and PROFINET IO slot addressing.
  4. SITRAIN course TIA-SCL1 — instructor-led online training on SCL programming in TIA Portal, indexed at Siemens SITRAIN.
  5. Programming and Operating Manual for the target CPU — the device manual lists the firmware-version-specific instruction set and any restrictions on indirect addressing.

For a first SCL block, the "Writing your first SCL code in TIA Portal" walkthrough provides a step-by-step procedure for project setup, FB/FC creation, interface definition, and the first compile/download cycle.

Commissioning and Verification Procedure

After the SCL block is written, validate it in five steps before releasing to production.

  1. Compile the program in TIA Portal (Project > Compile > All or Ctrl+B). Resolve every warning, especially the ones that flag optimized-block access conflicts.
  2. Download the block to the target PLC. The download dialog displays the firmware compatibility check; if the firmware does not match, the download is rejected.
  3. Monitor online the block. Right-click the SCL block in the project tree, choose Open in SCL editor, then click Monitor on/off to attach the SCL debugger. Set breakpoints on the %IW/%QW lines and step through the cycle.
  4. Force / overwrite an output to validate the write path. Use a watch table on the tag mapped to %QW272 and set the value. The output module should respond within one OB1 cycle for image access, or within the backplane latency for :P access.
  5. Document the access pattern in the function specification. Record the hardware slot, the I/O address, the symbol name, the scaling, and the SCL block number. This information is required for the as-built documentation and for any subsequent maintenance work.
Safety note: :P direct peripheral writes bypass the process image and are not subject to the standard output-disable mechanism that the safety program uses. In a safety-related application, the safety output must be driven through the safety program, not through an SCL :P write.

Troubleshooting Matrix

Symptom Likely Cause Fix
Compiler error: "Absolute address not allowed in optimized block" Symbolic-only optimized block access is enabled and a %IW read crosses the optimization boundary Add the address to the PLC tag table with the Accessible from SCL attribute, or change the block to non-optimized
Read value is always zero Hardware module not inserted; PROFINET IO station not configured; address offset wrong Verify the device configuration in Devices & Networks; check the slot and I/O range against the tag table
Watch table shows stale value for PEEK result TIA Portal V16/V17 watch-table caching of PEEK temporaries Force a re-read of the watch table; pin a snapshot tag; update to V17 Update 4 or later
Download rejected: "Firmware not supported" Block was compiled for a newer CPU firmware than the target PLC has Match the CPU firmware, or recompile against the actual firmware
Runtime error 16#FFFF (illegal PEEK area) Area constant outside the supported set (only 16#81-16#84 are valid for user code) Check the area parameter; use the symbolic tag instead
SCL editor locks up on save Known TIA Portal V11 / V13 issue with large SCL blocks Split the block, or upgrade to a current TIA Portal major version

FAQ

How do I read PIW 256 in SCL on TIA Portal?

Use %IW256 for process-image access, or %IW256:P for direct peripheral read. The S7-1500 and S7-1200 (FW V4.0+) support both notations. Symbolic tags mapped to the same address are preferred for readability.

How do I write PQW 272 in SCL?

Assign the value with %QW272 := value; (process image) or %QW272:P := value; (peripheral-direct). The SCL compiler enforces the data-type match between the value and the I/O size.

What is the difference between PEEK and %IW:P?

%IW256:P requires a fixed, known address. PEEK_WORD(area := 16#81, byteOffset := ...) takes a runtime-computed bit offset and lets you index into a vector of I/O words. Use PEEK for arrays of analog channels with parameterized base address.

Can I use SCL to program an S7-300 or S7-400 in TIA Portal?

Yes. TIA Portal supports SCL on S7-300/400 with the same syntax. The legacy STL approach of L PIW/T PQW is still valid; SCL is the typed, debuggable replacement that integrates with the cross-reference.

Which TIA Portal version should I use for a new SCL project?

Use the latest supported major version for the target CPU firmware. Confirm in Siemens Industry Online Support by checking the TIA Portal compatibility list and applying the latest Service Pack + Update. Avoid V11-V13 for new SCL development.

Back to blog