Scaling Siemens PIW Analog Input for WinCC Flexible I/O Fields

David Krause13 min read
HMI ProgrammingSiemensTutorial / 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

Scaling Siemens PIW Analog Input for WinCC Flexible I/O Fields

This technical reference covers the end-to-end procedure for converting a raw Siemens S7 analog input word (PIW) into an engineering-unit value (RPM, Nm, bar, °C) and presenting it on a WinCC Flexible 2008 I/O field and gauge. The scenarios addressed are direct from commissioning: a 10 kΩ potentiometer wired to PIW 388 producing raw counts that the HMI renders as 0x0666 (hex) or 3109 decimal rather than the expected 0–220 RPM, with torque on DB5.DBW108 reading 3109 against a 0–50 range.

The fix is not in the HMI configuration: it is on the PLC. The PLC must perform the linear conversion and write the scaled integer into a DB word that the HMI then displays. Doing the math in the HMI is fragile, breaks with tag-type mismatches, and produces the hex/decimal confusion seen in the original symptom.

1. Problem Statement

When a Siemens S7 analog input module is wired to a field transducer (potentiometer, 4–20 mA transmitter, 0–10 V sensor), the process image word it places in the PLC carries a raw integer count, not an engineering unit. The mapping is:

Field signal Raw value in PIW Engineering unit
0 V or 4 mA 0 Lower range (e.g. 0 RPM)
10 V or 20 mA 27648 (nominal) / 27168 (per module datasheet) Upper range (e.g. 220 RPM)
Over-range / fault 32767 or negative full-scale Diagnostic only

Three failure modes appear repeatedly when this scaling is missed:

  1. Hex display: The I/O field is bound to the raw PIW and configured for hexadecimal output, yielding 0x0666 for a 10 RPM setpoint. The decimal equivalent is 1638, which is meaningless to the operator.
  2. Out-of-range gauge: The gauge is bound to a raw DBW that already carries 3109 or 5248 counts. The needle pegs at the maximum because 3109 > 50 (torque full-scale).
  3. Hidden offset: A second, unrelated DBW (e.g. DB5.DBW140) is used as a test source. The HMI shows a consistent but wrong number because both raw and scaled DBWs are being monitored.

All three are resolved by performing the linear conversion in the PLC and writing the scaled integer into a dedicated DB location that the HMI then displays in decimal.

2. Prerequisites

  • Siemens S7-300 or S7-400 PLC with STEP 7 V5.4 / V5.5 (or compatible TIA Portal V13+ project), online to the CPU.
  • WinCC Flexible 2008 SP2/SP3 with a configured connection to the PLC (MPI, PROFIBUS, or PROFINET) verified in the connection table.
  • Analog input module occupying PIW 388 in slot/patch of the rack (SM 331 / SM 431 family typical; verify the module's hardware identifier in HW Config).
  • A free DB for scaled values, e.g. DB8 (the convention used in the field is to copy DB5 to DB8 to avoid touching the running tag map).
  • A free FB (e.g. FB10) called in OB1, or unused network in an existing FB.
  • Operator panel: SIMATIC Panel (OP 177B, TP 177B, MP 277, or PC Runtime on a SIMATIC PC 627).
Note: Always confirm the module's nominal range from its data sheet before scaling. Siemens 6ES7331 modules use 0–27648 for unipolar and –27648–+27648 for bipolar inputs. The 27168 figure cited in the field corresponds to certain 4–20 mA ranges after the 4 mA live-zero subtraction; use the value from the module's hardware configuration, not a generic assumption.

3. Scaling Formula Derivation

Linear scaling between two ranges has the form:

Scaled = ((Raw – Raw_min) × (EU_max – EU_min)) / (Raw_max – Raw_min) + EU_min

For a unipolar 0–10 V or 0/4–20 mA input with Raw_min = 0 and EU_min = 0, this collapses to:

Scaled = (Raw × EU_max) / Raw_max

Concretely for the potentiometer case:

Variable Value Description
Raw (PIW 388) 0–27168 (verify against module) Process image word from analog input
EU_max 220 (RPM) or 50 (Nm) Full-scale engineering unit
Raw_max 27168 (Siemens default) or 27648 Module full-scale count
Scaled 0–220 RPM or 0–50 Nm integer Value written to DB for HMI

Two implementation rules keep the result correct:

  1. Cast Raw to DINT (32-bit signed) before the multiplication. A 16-bit INT multiply of 220 × 27168 overflows INT and yields garbage (e.g. 3109).
  2. Perform the divide last. Integer division truncates; doing it before the multiply loses resolution.

The result is an integer RPM or Nm value suitable for direct display in an I/O field and a gauge with no further transformation.

4. PLC-Side Implementation in STEP 7

Add the following network to FB10 (or any cyclic OB). The example scales PIW 388 to 0–220 RPM and writes the result into DB8.DBW108:

STL version (preferred for clarity):

NETWORK 1  // Scale throttle setpoint PIW 388 to 0..220 RPM in DB8.DBW108
  L     PIW 388              // raw analog input, INT
  ITD                       // INT -> DINT, sign-extend
  L     L#220                // engineering unit full scale (RPM)
  *D                        // DINT multiply, no overflow up to ~134 M
  L     L#27168              // module full-scale count (verify in HW Config)
  /D                        // DINT divide, integer result
  T     DB8.DBW 108          // scaled RPM, INT, for HMI I/O field & gauge

NETWORK 2  // Optional: scale torque DB5.DBW108 (raw) to 0..50 Nm in DB8.DBW110
  L     DB5.DBW 108
  ITD
  L     L#50
  *D
  L     L#27168
  /D
  T     DB8.DBW 110

LAD/FBD version (for graphical editors):

  1. Insert a MOVE block: IN = PIW388, OUT = MW200 (intermediate INT).
  2. Insert a CONVERT block: IN = MW200 (INT) → OUT = MD202 (DINT). This is the ITD step.
  3. Insert a MUL_DI (DINT multiply): IN1 = MD202, IN2 = 220OUT = MD206.
  4. Insert a DIV_DI (DINT divide): IN1 = MD206, IN2 = 27168OUT = MD210.
  5. Insert a final MOVE: IN = MW210 (low word of result) → OUT = DB8.DBW108.
Critical: Never use the raw PIW directly in the HMI tag. The HMI's integer formatting cannot recover the engineering-unit value from a raw count without a connection-side linear-scaling property, which WinCC Flexible 2008 supports but is fragile when the tag crosses connection boundaries or is re-imported.

For the second scaling path (torque from DB5.DBW108), repeat the same sequence with the EU_max constant set to 50 instead of 220. The intermediate DINT prevents the 50 × 5248 overflow that produces the 5248 reading observed on the HMI when the network is implemented with INT math.

5. WinCC Flexible I/O Field Configuration

After the PLC writes the scaled integer into DB8.DBW108, bind the I/O field to that tag:

  1. Open the screen in WinCC Flexible 2008 and insert an I/O Field from the toolbox.
  2. In Properties → General:
    • Mode: Output (display only, no operator write).
    • Process tag: Click the tag selector and choose DB8.DBW 108. If the DB is not visible, run PLC → Tags → Import or hand-create it as a 16-bit unsigned tag, address DB8 DBW 108, connection = the configured PLC connection.
  3. In Properties → Appearance:
    • Format type: Decimal (never Hexadecimal for operator displays; hex 0x0666 was the original symptom).
    • Decimal places: 0 for RPM and Nm if integer resolution is sufficient, or 1 if the scaled value is then divided by 10 elsewhere.
    • Field length: 5 characters minimum to accommodate 3-digit full-scale (e.g. "220") plus sign headroom.
  4. For operator entry of a setpoint, use a second I/O field in Mode: Input/Output bound to DB8.DBW108. Enter the limits 0 and 220 in the Limits property to clamp the value at the panel.
Tip: The Limits property on the I/O field is a panel-side clamp. It does not replace PLC-side validation. If the operator enters 250, the PLC will receive 250. Add a compare instruction in the PLC that ignores or limits out-of-range writes.

6. WinCC Flexible Gauge Configuration

Bind the gauge to the same scaled DBW used by the I/O field. The 0–50 and 0–220 displays work without any linear-scaling property on the HMI side once the PLC has done the conversion:

  1. Insert a Gauge object.
  2. Properties → General:
    • Process tag: DB8.DBW 110 for torque (0–50 Nm) or DB8.DBW 108 for RPM (0–220).
  3. Properties → Scale:
    • Minimum value: 0
    • Maximum value: 50 (torque) or 220 (RPM)
    • Enable Labeling of the scale with major ticks at 0, 25, 50 (or 0, 110, 220).
  4. Properties → Appearance:
    • Set Number of main scale divisions to 5 or 10.
    • Disable Display of additional scale unless a secondary axis is required (typical machine panels use a single 0–220 RPM scale).

With the PLC writing the scaled integer, the gauge needle position is computed directly from the tag value divided by the full-scale count, eliminating the "3109 pegged at 50" symptom. The displayed engineering unit and the PLC variable no longer disagree.

7. SVG Flow Diagram: PLC Scaling to HMI Display

Potentiometer 0–10 V / 0–220 RPM SM 331 AI PIW 388 (INT) S7-300 CPU ITD → *220 → /27168 FB10 / OB1 DB8.DBW108 Scaled INT WinCC Flexible RT I/O Field + Gauge Potentiometer → PIW → FB10 Scaling → DB8 → HMI Tag values: 0x0666 (raw, 1638 dec) → Scaled 10 RPM after divide

8. Verification Procedure

  1. With the PLC in STOP, download the modified FB10 and DB8. Restart in RUN.
  2. Open a watch table in STEP 7 online, force PIW 388 to 0, then 13584, then 27168 (or use the live potentiometer at minimum, midpoint, maximum).
  3. Observe DB8.DBW108:
    • PIW = 0 → DBW108 = 0
    • PIW = 13584 (50 %) → DBW108 = 110 (RPM)
    • PIW = 27168 (100 %) → DBW108 = 220 (RPM)
  4. Start WinCC Flexible Runtime. The I/O field should display the same three numbers; the gauge needle should sit at 0 %, 50 %, 100 %.
  5. Disconnect the field wiring (simulate broken cable) and verify the I/O field freezes at the last good value, or pegs to full-scale if Substitute value is configured on the tag — both behaviors confirm the tag is live, not a stale cache.

9. Troubleshooting Matrix

Observed symptom Probable root cause Corrective action
I/O field shows 0x0666 in hex I/O field bound to raw PIW with hex format Bind to scaled DB8.DBW108, set format to Decimal
Gauge pegs above 50 / 220 Gauge bound to raw DBW (e.g. 3109, 5248) that already overflows the gauge scale Re-bind to scaled DB8.DBW; do not scale on the HMI
Scaled value reads 0 for all inputs FB10 not called, or DB8 download order wrong (initial values overwritten) Confirm CALL FB10, DB10 in OB1; re-download DB8 with initial values
Value jitters / steps in 4-unit increments Divide done in INT (truncates 4–5 increments) or PIW bit-noise Use DINT divide (DIV_DI); add 1 % hysteresis in the application code
WinCC ASIA and WinCC Flexible show different values for the same tag WinCC ASIA reads a different DB instance or an unscaled DB5; Flexible reads DB8 after scaling Standardize on a single scaled tag (DB8) and migrate ASIA references to it
Scaled RPM = 3109 for a 10 RPM setpoint Math executed in INT: 1638 × 220 / 27168 ≈ 13 (correct), but with bad truncation overflow gives 3109 Force ITD before multiply; verify STL network sequence
Runtime shows "####" Field length too short for the value, or connection lost Increase field length to 5–6; check Connections in WinCC Flexible project

10. Edge Cases and Field Notes

Live-zero inputs (4–20 mA): When the transducer is 4–20 mA, the raw count is offset: 4 mA → raw ≠ 0. The general formula must be used:

Scaled = ((Raw – 0) × EU_max) / Raw_max   for 0–10 V
Scaled = ((Raw – Raw_4mA) × EU_max) / (Raw_20mA – Raw_4mA)   for 4–20 mA

For Siemens 6ES7331 modules configured for 4–20 mA in HW Config, the live-zero subtraction is automatic and PIW still reads 0 at 4 mA. Confirm this in the module's diagnostic view before applying the formula.

Bipolar inputs (±10 V, ±20 mA): The raw range is –27648–+27648 and the cast must use ITD (sign-extending) rather than BTD. The division in DINT produces a signed result; ensure the HMI tag is declared as signed INT or it will display 0 for negative scaled values.

Resolution: With EU_max = 220 and Raw_max = 27168, the LSB is approximately 0.008 RPM. After integer truncation, the smallest representable step is 1 RPM. If sub-RPM resolution is required, scale by 10 in the PLC (write 0–2200) and configure the I/O field with 1 decimal place, or scale by 100 and display 0–220.00.

Placing the scaling in FB10 vs. FC: An FB carries a static DB (instance DB) and retains intermediate values across calls. A function (FC) recomputes from scratch each cycle. For a one-shot linear conversion called every OB1 cycle, both are valid. Use FB if the scaled value is to be latched or if the same scaling block must service multiple channels with different parameters.

Why copy DB5 to DB8: DB5 in the running machine is the live torque map consumed by the WinCC ASIA project. Modifying DB5 risks disturbing the running SCADA. The convention of duplicating to DB8 keeps the original tag map intact while the new scaled tags are commissioned in parallel, allowing a tag-by-tag cutover once verified.

WinCC Flexible 2008 specifics: SP2 and SP3 both ship with the same I/O field and gauge object model. Linear scaling on the HMI tag is available in the Properties → Linear Scaling dialog of the tag, with input/output range pairs. It is functional but does not handle signed DINT conversions cleanly and is bypassed here in favor of the PLC approach for portability to TIA Portal WinCC (Comfort/Advanced) where the property has been removed in later versions.

11. Migration Path to TIA Portal

If the project is later migrated to TIA Portal V13+ with WinCC Comfort/Advanced, the same algorithm applies but the syntax differs:

// SCL (Structured Control Language) for TIA Portal
// Scale PIW 388 (0..27168) to 0..220 RPM, store in DB8."Scale_RPM"
"Scale_RPM" := INT_TO_DINT("PIW_388") * 220 / 27168;

The HMI tag binding uses the same DB8 word, but the tag is now created in the PLC data types and is automatically visible in the HMI tag selector when the HMI connection is configured. The I/O field and gauge configuration dialogs are nearly identical to WinCC Flexible 2008.

12. Frequently Asked Questions

Why does my I/O field show 0x0666 instead of 10 RPM when the potentiometer is at 10 RPM?

The I/O field is bound directly to the raw PIW and configured for hexadecimal output. A 10 RPM setpoint at a 0–220 RPM range produces approximately 1638 decimal, which is 0x0666. Bind the I/O field to a scaled DBW (e.g. DB8.DBW108) and switch the format to Decimal.

What divisor should I use: 27168 or 27648?

Use the value configured in HW Config for the specific module and range. 27648 is the unipolar nominal full-scale for most Siemens SM 331 / SM 431 modules. 27168 corresponds to 4–20 mA ranges with live-zero handling. Read the module's online diagnostics in STEP 7 to confirm before scaling.

My scaled value is 3109 instead of 10 RPM. What went wrong?

The arithmetic was done in 16-bit INT. The intermediate result 27168 × 220 = 5,976,960 overflows INT (max 32,767) and produces a truncated/wrapped value. Cast PIW to DINT with ITD before the multiply, and use *D / /D in STL or MUL_DI / DIV_DI in LAD/FBD.

Can I do the scaling on the HMI side with WinCC Flexible linear-scaling properties?

Yes, in WinCC Flexible 2008 the tag has a Linear Scaling dialog with input/output range pairs. It is fragile, does not survive project migration well, and was removed in later TIA Portal WinCC versions. Performing the conversion in the PLC is portable across all Siemens HMI generations.

Why does WinCC ASIA show correct values while WinCC Flexible does not, on the same PLC?

WinCC ASIA is reading the raw DB5 tags and applying its own conversion downstream, or is bound to a different scaling block. WinCC Flexible is reading the same DB5 tags without conversion. The fix is to publish a single scaled tag set (DB8) and bind both HMI projects to it, removing duplicate or missing conversion logic.

Should I put the scaling in an FB or an FC?

Use an FB if multiple channels share the block with different parameters and you need instance-data retention. Use an FC for a single-channel, single-call conversion. Both produce identical results when called once per OB1 cycle; the FB approach is preferred for documentation and reuse.

Back to blog