Siemens PIW PQW Symbols: WORD vs INT Data Type Selection

David Krause14 min read
S7-300SiemensTechnical 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: PIW/PQW Addressing in the S7 Memory Model

Process-input words (PIW) and process-output words (PQW) are the peripheral I/O image areas of the SIMATIC S7-300 and S7-400 CPU families. Unlike IW and QW (inputs/outputs image), the peripheral area is read or written directly to the I/O backplane on every bus cycle, bypassing the process-image update. PIW and PQW addresses are always 16-bit aligned, so PIW 128 occupies byte 128/129 of the peripheral input area (PII), while PQW 128 occupies byte 128/129 of the peripheral output area (PIQ).

Because the data unit the CPU reads or writes in a single cycle is 16 bits, the data type most engineers first associate with a PIW or PQW is INT (16-bit signed integer) or WORD (16-bit bit pattern, unsigned). In STEP 7 V5.x, however, the address remains a WORD-length cell regardless of the symbolic data type you assign. This causes the common confusion at the center of the original question: declaring a symbol as INT and tying it to a PIW works for math instructions, but declaring the same symbol as WORD blocks it from being passed to the SCALE block's INT input.

Address Area Width Update Common Use
PIW / PEW Peripheral inputs 16 bits Direct, every OB1 scan or PPO read Analog input raw value
PQW / PAW Peripheral outputs 16 bits Direct, every OB1 scan Analog output raw value
IW / EW Process-image input 16 bits At OB1 entry (or PIP) Digital and analog input snapshot
QW / AW Process-image output 16 bits At OB1 exit Digital and analog output snapshot
PID / PED Peripheral inputs 32 bits Direct Counter/encoder words
PQD / PAD Peripheral outputs 32 bits Direct 32-bit analog modules

Why a PIW/PQW Cell Is Always a WORD-Length Cell

The peripheral I/O area is mapped 1:1 onto the I/O modules in the rack. A 4-channel SM 334 analog input module, for example, occupies PIW 288..295 (four 16-bit words). A SM 332 8-channel analog output module occupies PQW 304..319. The cell size is fixed by the hardware and the slot configuration in HW Config; STEP 7 does not store a data type with the address itself, only with the symbol that references it.

When you read L PIW 128 in STL, the accumulator's low word is loaded with the 16-bit value. When you read L PID 288, the entire 32-bit accumulator is loaded. The CPU does not check whether the programmer treats the result as signed (INT) or as a bit string (WORD) — that decision is enforced only by the editor's type check and by the IEC 61131-3 data-type rules of the block being called.

Engineering rule of thumb: Treat the cell as a WORD container, and the symbol's data type as a view onto the container. The hardware does not know — and does not need to know — what the symbol is declared as in the symbol table.

INT vs WORD: Where the Type Check Fires

STEP 7's LAD/FBD editor enforces strict data-type compatibility at the parameter boundary of a block call. The default setting, controlled by Options > Customize > LAD/FBD > "Type Check of Address", is enabled. With the checkbox enabled:

  • A PIW symbol declared as INT is accepted at any block input declared as INT or WORD (INT is the more restrictive of the two).
  • A PIW symbol declared as WORD is rejected at an INT input (e.g., the IN of FC105 SCALE) but accepted at any WORD or DWORD input.
  • A PIW symbol declared as REAL is rejected outright — the cell is 16 bits wide, not 32.

The same rule applies in reverse to the double-word case: a PID/PQD symbol declared as DINT is accepted where a DINT parameter is expected, while a DWORD symbol is rejected at a DINT parameter. The underlying value is identical; only the editor's interpretation differs.

Unchecking Type Check of Address disables the warning. This is a quick escape hatch for legacy code, but it is not recommended because the compiler will then quietly accept an INT symbol where a WORD was intended, masking sign-extension bugs. For example, the value 16#8000 is +32768 as a UINT but -32768 as INT — the wrong sign can cause a SCALE block to drive the output negative when the input is at the upper rail of a unipolar 4–20 mA module.

Recommended Symbol Declarations for Analog I/O

For STEP 7 V5.5 / TIA Portal V13 and later, the recommended practice is to declare the symbol that points to a PIW or PQW as the data type that matches the block you are going to feed. The two dominant cases are:

Use Case Recommended Symbol Type Reason
Direct to FC105 SCALE / FC106 UNSCALE INT (signed 16-bit) FC105 IN and FC106 OUT are typed as INT
Pass to a bit-test instruction (e.g., A, AN, L with WXOR) WORD Word operations ignore sign and are bit-mask safe
Long-term storage of raw value in a data block INT (after type conversion) Matches scaled engineering value; easier to scale later
Hand-off to a non-Siemens field device over PROFINET or PROFIBUS DP using SFC14/15 WORD or array of WORD Consistent record framing; conversion to INT inside the FB

If the same PIW must be read in two contexts — once for scaling and once for a bit test on a fault-flag bit — declare two separate symbols pointing to the same address. STEP 7 allows multiple symbols to reference a single absolute address; the symbol is just a label, the address is the underlying cell. A common naming convention is AI_RAW_PIW128 (INT) for the scaled path and AI_RAW_WORD_PIW128 (WORD) for the bit-test path. The second symbol still compiles to the same address; you are not duplicating the I/O read.

Working with FC105 SCALE and FC106 UNSCALE

FC105 SCALE accepts a 16-bit integer at IN and produces a 32-bit REAL at OUT, scaled between LO_LIM and HI_LIM. FC106 UNSCALE performs the inverse. Both blocks are part of the Standard Library > TI-S7 Converting Blocks in STEP 7 V5.x. The full parameter set is shown below.

Parameter Type Range / Unit Description
IN (FC105) INT −27648 to +27648 (bipolar) or 0 to 27648 (unipolar) Raw input from PIW
HI_LIM REAL Engineering high (e.g., 100.0 bar) Value at IN = 27648
LO_LIM REAL Engineering low (e.g., 0.0 bar) Value at IN = 0 (or −27648 bipolar)
BIPOLAR BOOL 0 = unipolar, 1 = bipolar Selects scale type
OUT REAL LO_LIM ≤ OUT ≤ HI_LIM Engineering value
RET_VAL WORD 0 = OK, 80A0 = overflow, 80A1 = underflow Status output

Because the IN parameter is INT, the symbol passed to it must be INT (or a temporary variable of type INT in the calling block). Passing a WORD symbol directly is rejected when the type check is on. The cleanest fix is to either:

  1. Re-type the symbol to INT in the symbol table, or
  2. Insert a WORD_TO_INT conversion (FC33) on the rung in front of the SCALE block. This is the recommended approach when the same raw value is needed elsewhere as a WORD.

STL Snippet: WORD PIW -> INT -> SCALE

//  Raw PIW (declared WORD in the symbol table) is bit-tested
//  and the same value is fed to FC105 as INT
A   "AI_FAULT_BIT";   //  WORD symbol on PIW 128, bit 7
JC  FAU;              //  jump to fault handler
L   "PIW_RAW_W";      //  WORD symbol on PIW 128
ITD ;                 //  INT -> DINT (sign-extend)
DTR ;                 //  DINT -> REAL
//  ... or simply:
L   "PIW_RAW_W";      //  load WORD
T   #wRaw;            //  move to a static INT in the FB
CALL FC105
IN   := #wRaw
HI_LIM := 1.000000e+002
LO_LIM := 0.000000e+000
BIPOLAR := FALSE
RET_VAL := #wFC105Status
OUT  := #rEngValue
NOP 0;

Procedure: Changing the Type-Check Behavior

  1. Open the LAD/FBD/STL editor in STEP 7 V5.x.
  2. From the menu bar, choose Options > Customize.
  3. Select the LAD/FBD tab.
  4. Toggle the Type Check of Address checkbox. Default is enabled.
  5. Click OK and recompile the affected blocks.
Warning: Disabling the type check is a project-wide change that affects every block in the S7 program. Use it only as a temporary migration aid, and re-enable it before final commissioning. Bypassing the check can mask negative-value bugs on bipolar inputs and can cause FC105 to return overflow (RET_VAL = W#16#80A0) at legitimate inputs.

Procedure: Wiring a Symbol to FC105 via the Symbol Table

  1. In the symbol table, ensure the row for the analog input symbol is declared as INT (not WORD). Use a name like AI_RAW_PIW128 with the address PIW 128.
  2. Open the FC or FB that calls FC105. From the library tree on the right, drag FC105 onto a network.
  3. At the IN input, type the symbolic name AI_RAW_PIW128. With the type check on, this passes because the symbol is INT.
  4. Wire HI_LIM, LO_LIM, BIPOLAR, and RET_VAL to local variables (e.g., #rEngValue, #wFC105Status).
  5. Save the block and download to the CPU.

Address Layout Examples for Common Analog Modules

Module Order Number Slot Address Range Resolution
SM 331 AI 8x12 bit 6ES7 331-7KF02-0AB0 4 PIW 288..303 (4 used, 4 reserved) 0…27648 unipolar / ±27648 bipolar
SM 331 AI 2x14 bit 6ES7 331-7NB00-0AB0 4 PIW 288..291 ±27648 bipolar only
SM 332 AO 4x12 bit 6ES7 332-5HD01-0AB0 5 PQW 304..311 0…27648 or ±27648
SM 334 AI 4/AO 2 x12 bit 6ES7 334-0CE01-0AA0 4 PIW 288..295 / PQW 304..307 Mixed
SM 335 AI 4/AO 4 x14 bit 6ES7 335-7HG01-0AB0 4 PIW 288..295 / PQW 304..311 ±27648, configurable

Always confirm the actual addressing in HW Config > Module Properties > Addresses because slot numbers, slot-priority, and the start address assigned by STEP 7 are user-configurable. Mismatched addresses are a far more common commissioning fault than data-type mismatches.

FC105 and FC106 Status Words (RET_VAL)

Always wire the RET_VAL output to a WORD variable and check it in the calling block. A non-zero value indicates the input is outside the scaled window. A non-zero RET_VAL does not mean the block has failed — the OUT value is still written; it is clamped to LO_LIM or HI_LIM.

RET_VAL Meaning Field Action
W#16#0000 OK None
W#16#80A0 IN > 27648 (over-range) or bipolar > 27648 Alarm to HMI; check sensor scaling; verify input channel is not open-circuit on a 4–20 mA loop
W#16#80A1 IN < 0 (unipolar) or IN < −27648 (bipolar) Alarm to HMI; check wiring polarity and 24 V supply

Why Not Use a TEMP Variable Instead of the Symbol?

The cleanest engineering approach is to read the PIW once at the top of the calling block into a TEMP or STAT variable, then use that local variable for every subsequent operation. This decouples the rest of the program from the absolute address and makes the data type explicit at the variable declaration:

//  FB "AI_Scaling" — declaration section
VAR
  iRaw     : INT;        //  raw count from PIW
  wRaw     : WORD;       //  alternative for bit tests
  rEng     : REAL;       //  engineering value
  wStatus  : WORD;       //  FC105 RET_VAL
  bFault   : BOOL;       //  latched alarm
END_VAR

//  Implementation
L   "AI_RAW_PIW128";   //  symbol declared INT, no conflict
T   #iRaw;
CALL FC105
IN   := #iRaw
HI_LIM := 1.0e2
LO_LIM := 0.0e0
BIPOLAR := FALSE
RET_VAL := #wStatus
OUT  := #rEng;
A   L 0;          //  test the sign of RET_VAL
JC  Fault;
//  ... rEng is now safe to use downstream

This pattern eliminates the INT/WORD symbol choice from the calling site entirely: the symbol on the PIW is declared as INT, the value is moved to a local INT, and all scaling, alarming, and HMI hand-off logic operates on locals. The only place the data type matters is in the symbol table and the local declaration, and both are explicit.

DINT vs DWORD: The 32-Bit Extension of the Same Problem

The discussion thread explicitly notes that the same INT/WORD type-check issue exists for 32-bit peripherals (PID/PQD). A PID symbol declared as DWORD cannot be passed directly to a block input of type DINT when the type check is on. The fix is identical:

  • Declare the symbol as DINT if it feeds signed arithmetic, or
  • Insert a DWORD_TO_DINT (FC30) conversion at the boundary, or
  • Read the PID into a DINT local first.

32-bit peripherals are common on the ET 200S 4AI/HS counter modules and on PROFIBUS DP slaves configured with 32-bit consistency. The behavior is identical to the 16-bit case and the same type-check checkbox controls it.

Verification After a Symbol Type Change

  1. In the symbol table, confirm the new data type and recompile the entire S7 program (Program > Compile All in STEP 7 V5.x).
  2. Use PLC > Download to push the rebuilt program. Hardware configuration does not change.
  3. Go online with the CPU (PLC > Monitor/Modify). Open the FC/FB that calls FC105 and watch the IN value. Verify it tracks the HMI raw count.
  4. Force a known input (e.g., a 4 mA loop or a precision 24 V source on a voltage channel). Confirm rEng equals the calculated LO_LIM and that wStatus remains W#16#0000.
  5. Sweep the input to the upper rail and verify the wStatus stays zero until the input exceeds 27648 counts (unipolar) or 27648 in absolute value (bipolar).

Troubleshooting Matrix

Symptom Likely Cause Resolution
FC105: "Type incompatibility of input IN" PIW symbol declared WORD, IN expects INT Re-declare as INT or add WORD_TO_INT
FC105: RET_VAL = 80A0 at any input above 4 mA Unipolar mode with bipolar input; or sign error Set BIPOLAR = FALSE; check INT vs WORD interpretation
Symbol name shows in the editor but value = 0 Symbol table change not propagated to block Close and reopen the calling block; recompile
SCALE output is negative on a 4–20 mA loop PIW symbol declared WORD interpreted as INT bit pattern Force type check on, declare symbol as INT, recompile
Symbol table "Address already in use" on save Two symbols pointing to the same PIW with different data types Use unique symbol names; only the address needs to be unique, not the symbol itself
FC105 instance shows red X after download Type check disabled in project settings but enabled on the block Re-enable type check, re-download, reset CPU

Best-Practices Summary

  • Declare the symbol that points to a PIW or PQW as INT when the value is going to be scaled, compared, or otherwise treated as a signed number.
  • Declare a second symbol as WORD on the same address if a bit test is also needed. Multiple symbols on one address are legal in STEP 7.
  • Never disable Type Check of Address for production code. Use it as a temporary migration tool only.
  • Always wire RET_VAL of FC105/FC106 to a WORD variable and alarm on W#16#80A0 / 80A1.
  • Where possible, copy the raw value to a local INT or DINT at the top of the calling block and operate on the local thereafter. This decouples the rest of the program from the absolute address.
  • Confirm module addressing in HW Config before assuming PIW 128 is the first analog input. Slot order and start address are user-configurable.

Should I declare a PIW or PQW symbol as WORD or INT?

Declare the symbol as INT when the value will be scaled, compared, or treated as a signed number (for example, the IN input of FC105 SCALE). Declare a second symbol as WORD on the same address if a bit test is also required. The peripheral cell is always 16 bits wide regardless of the symbol type, so the choice is purely about which editor check the symbol should satisfy.

Why does the SCALE block reject my PIW symbol even though the address is correct?

FC105 SCALE declares its IN parameter as INT. When the symbol table entry is typed as WORD, the LAD/FBD editor's type check blocks the connection with a "type incompatibility" message. Either change the symbol's data type to INT, or insert a WORD_TO_INT (FC33) conversion in front of the SCALE call.

Does disabling the Type Check of Address fix the FC105 problem?

Yes, it removes the compiler error, but it is not recommended for production code. Disabling the check also masks genuine type errors, such as passing a WORD to a BCD input, and can cause SCALE blocks to misbehave when a value of 0x8000 is interpreted as either 32768 (WORD) or -32768 (INT). Re-enable the check and fix the symbol type at the source instead.

Can two symbols point to the same PIW with different data types?

Yes. STEP 7 allows multiple symbol-table entries to reference one absolute address. A common convention is AI_RAW_PIW128 (INT) for the scaled path and AI_RAW_W_PIW128 (WORD) for bit-test paths. The address is what the CPU reads, and the symbol is just a label and a type hint at the call site.

Does the same INT/WORD issue apply to 32-bit peripherals like PID and PQD?

Yes, the editor enforces the same rule at the wider width. A PID symbol declared as DWORD cannot be passed directly to a DINT input when the type check is on, and the fix is the same: re-declare as DINT, use DWORD_TO_DINT (FC30), or copy the PID value into a DINT local at the top of the calling block.

Back to blog