Siemens S7 PLC: Convert Percentage to 4-20mA Analog Output

David Krause11 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

Overview

On a Siemens SIMATIC S7 PLC, every analog output is written to the process image as a 16-bit integer between 0 and +27648 (unipolar) or -27648 and +27648 (bipolar). A percentage entered on an HMI – for example 80 % – must therefore be converted into that raw integer before it is transferred to the peripheral output word PQW. Once the correct integer sits in PQW, the analog module (SM332, SM334, SM 6ES7532, ET 200SP AQ, etc.) converts the integer to a current on the field terminals:

Raw count (INT) Unipolar output (0–10 V, 1–5 V, 0/4–20 mA) 4–20 mA only (zero lifted)
0 0 % / 0 V / 0 mA 4 mA
6912 25 % 8 mA
13824 50 % 12 mA
20736 75 % 16 mA
27648 100 % / 10 V / 20 mA 20 mA

The 4 mA offset is a property of the analog output channel configuration (not a constant you subtract in code). Once the channel is configured for "4..20 mA" in HW Config / the device configuration, the value 0 in PQW automatically produces 4 mA on the terminals and 27648 produces 20 mA. Your only job in the PLC program is the percent-to-count conversion.

Prerequisites

  1. STEP 7 V5.x (for S7-300/400) or TIA Portal V15 or later (for S7-1200/1500) installed and licensed.
  2. An analog output module inserted in the hardware configuration. Common catalog numbers: 6ES7332-5HD01-0AB0 (SM 332, 8 AO, 12 bit), 6ES7332-8TF01-0AB0 (SM 332, 8 AO, 16 bit), 6ES7334-0CE01-0AA0 (SM 334), 6ES7532-5HF00-0AB0 (SM 532 for S7-1500), 6ES7135-6HD00-0BA1 (ET 200SP AQ).
  3. The analog output channel configured for the current range 4..20 mA (not 0..20 mA, unless you specifically want zero-lifted to start at 0 mA). Without this configuration, value 0 yields 0 mA regardless of code.
  4. An HMI tag of data type REAL (0.0 – 100.0) or INT (0 – 100) wired to the PLC.
  5. For S7-300/400: the FC106 "UNSCALE" block from the "Standard Library → TI-S7 Converting Blocks" palette, or a copy from the Siemens FAQ linked below.
  6. For S7-1200/1500: the system blocks NORM_X (FC in the "Scaling" folder) and SCALE_X – both are IEC 61131-3 native blocks, no library install required.

Analog Output Fundamentals on S7

Siemens analog output modules are essentially 12- to 16-bit DACs driving a current or voltage output stage. The full theory of digital-to-analog conversion is covered in Maxim/Analog Devices' primer "Digital-to-Analog Converters Are a 'Bit' Analog". What the PLC programmer must know is that:

  • The value placed in PQW nnn is the binary code the DAC converts to the output current.
  • The range 0…+27648 is fixed by Siemens firmware and corresponds exactly to the nominal range of the configured output. The number 27648 = 2^14 × 1.6875 reflects the 14-bit-plus-sign internal resolution that all standard S7 analog modules expose to the user program.
  • Out-of-range values (negative for unipolar, > 32511, overflow bit 32767) are clamped or flagged by the module – see the SIMATIC S7-300/400 Standard Software – Converting Blocks FC105/FC106 manual, section 5.

The Core Formula: Percentage to Raw Count

For a 0..100 % input and a 0..27648 unipolar output (configured for 4..20 mA):

RawCount = ROUND( Percentage × 27648 ÷ 100 )

For 80 %: 80 × 27648 / 100 = 22118. Writing 22118 to the configured PQW gives 4 + (22118/27648) × 16 mA = 16.8 mA, which is 80 % of the 16 mA span (4 → 20 mA).

Important: The 4 mA "live zero" is added by the analog module, not by your code. Do not pre-compensate the percentage; that would double-shift the output. The percentage should always be expressed relative to the 4..20 mA span (0 % = 4 mA, 100 % = 20 mA).

Implementation on S7-300/400 with FC106 UNSCALE

FC106 "UNSCALE" is the canonical block for converting a real engineering value (the percentage) into the integer the output module expects. It is the inverse of FC105 "SCALE", which is used on the input side. The block ships in the STEP 7 standard library; full documentation is in the official FAQ 14431100.

FC106 Pin Assignment

Parameter Type Description Typical value
IN REAL Engineering value (the percent or the physical unit, e.g. 0.0 – 100.0) MW100 (REAL from HMI)
HI_LIM REAL Upper engineering limit 100.0
LO_LIM REAL Lower engineering limit 0.0
BIPOLAR BOOL FALSE = unipolar 0..27648, TRUE = bipolar -27648..+27648 FALSE
OUT INT Scaled raw count – wire this to PQW PQW 288
RET_VAL WORD Error word – 0 = OK, 8000H = HI_LIM ≤ LO_LIM MW110

STL Snippet (matches the example in the original question)

// --- Percentage → raw count, then write to PQW 288 ---
      L     "HMI_Percentage"      // REAL, e.g. 80.0
      L     100.0
      /R                             // clamp/normalize: pct/100
      L     27648.0
      *R
      RND                             // round to DINT
      T     "RawCount_INT"

      L     "RawCount_INT"
      T     PQW 288                   // 4..20 mA channel of SM332

If you prefer the FC106 block path, call it once in OB1 / OB35:

CALL "UNSCALE"
     IN     := "HMI_Percentage"      // REAL 0.0..100.0
     HI_LIM := 100.0
     LO_LIM := 0.0
     BIPOLAR:= FALSE
     RET_VAL:= "fc106_err"
     OUT    := PQW 288

Implementation on S7-1200/1500 with NORM_X and SCALE_X

On S7-1200 and S7-1500, FC105/FC106 are deprecated. Siemens replaced them with two IEC blocks: NORM_X (normalizes an engineering value to a 0.0 – 1.0 REAL fraction) and SCALE_X (scales the normalized fraction to the integer output range). The official procedure is in the FAQ 39334504 – Scale integer values to real numbers and vice versa on S7-1200/1500 and the broader 77316903 – Standardize and destandardize analog values in TIA Portal.

NORM_X / SCALE_X Parameters

Block Parameter Purpose Wired to
NORM_X MIN / MAX Engineering input range 0.0 / 100.0
NORM_X VALUE The HMI percentage "HMI_Percentage"
NORM_X OUT Normalized 0.0..1.0 REAL "NormValue"
SCALE_X MIN / MAX Raw output range as REAL 0.0 / 27648.0
SCALE_X VALUE Connect to NORM_X.OUT "NormValue"
SCALE_X OUT Integer raw count (0..27648) %QW288 (or move to PQW)

SCL Implementation (S7-1500)

// "HMI_Percentage" : REAL;   // 0.0 .. 100.0
// "NormValue"      : REAL;
// "RawCount"       : INT;    // 0 .. 27648

IF "HMI_Percentage" < 0.0 THEN
    "HMI_Percentage" := 0.0;
ELSIF "HMI_Percentage" > 100.0 THEN
    "HMI_Percentage" := 100.0;
END_IF;

"NormValue" := NORM_X(MIN := 0.0,
                      MAX := 100.0,
                      VALUE := "HMI_Percentage");

"RawCount" := REAL_TO_INT(SCALE_X(MIN := 0.0,
                                   MAX := 27648.0,
                                   VALUE := "NormValue"));

%QW288 := "RawCount";          // SM 532 / 6ES7532 channel 0

Ladder / FBD Alternative

Place an NORM_X box with MIN=0.0, MAX=100.0, VALUE="HMI_Percentage". Connect its OUT to the VALUE input of a SCALE_X box with MIN=0.0, MAX=27648.0. Connect the SCALE_X OUT to a MOVE box that writes to %QW288. Add a LIMIT (0, 100, "HMI_Percentage") upstream so out-of-range HMI values are clamped, not just sign-flipped.

HMI Configuration Considerations

  • Tag data type: REAL (0.0 – 100.0) is the most flexible because both FC106 and NORM_X expect REAL inputs. Integer percentages (0 – 100) work but require a DINT-to-REAL conversion in the PLC.
  • IO field limits: configure the HMI input field with min=0.0, max=100.0, scaling 0.0–100.0. This prevents the operator from typing negative or out-of-range values.
  • Display formatting: if the operator enters "80 %", the HMI tag value is 80.0 (REAL) or 80 (INT). The conversion is identical, only the data type changes.
  • Bar graph / gauge on the HMI side: link to the same tag, configure min=0, max=100. The HMI never sees the raw count, so the operator cannot break the scaling by reading the PQW directly.

Verification and Commissioning Steps

  1. Open the hardware configuration and confirm the analog output channel is set to "4..20 mA" (not 0..20 mA). The channel's measuring range is selected via the "Output" drop-down in the module properties; the choice is stored in the SDD of the module, not in the program.
  2. Force the HMI tag to 0.0 %; measure the loop current with a calibrated multimeter in series with the load. Expected: 4.000 mA ± module accuracy.
  3. Force the HMI tag to 50.0 %; expect 12.000 mA.
  4. Force the HMI tag to 100.0 %; expect 20.000 mA.
  5. Force 25.0 % and 75.0 % to verify linearity: expect 8.000 mA and 16.000 mA respectively.
  6. Monitor PQW 288 in the watch table – the integer must equal ROUND(percentage × 276.48). 80 % should show 22118.
  7. Disconnect the field wire and verify the wire-break diagnostic (only available on modules that support it, e.g. SM 332 6ES7332-8TF01-0AB0).
Note on accuracy: A 12-bit SM 332 has an LSB of roughly 3.9 µA on a 0..20 mA range; a 16-bit module like the 6ES7332-8TF01 reaches 0.3 µA. The percent-to-integer math is exact; the analog tolerance is the module spec, not the program.

Troubleshooting Matrix

Symptom Likely cause Fix
Output stuck at 4 mA regardless of HMI input Channel configured 4..20 mA but PQW never updated, or value clamped to 0 Watch PQW; verify the HMI tag is wired, limit at 0,0 ok
Output stuck at 20 mA PQW = 27648 constantly, or FC106 LO_LIM and HI_LIM reversed Check FC106 LO_LIM = 0.0, HI_LIM = 100.0; watch PQW
Output 4 mA at 0 % but reads e.g. 17.6 mA at 80 % Channel configured 0..20 mA but math assumes 4..20 mA span Reconfigure channel to 4..20 mA OR adjust the formula to mA = (counts/27648) × 20
Output current is half what HMI shows Double-scaling: 4 mA live-zero added by the module and added in the program Do not pre-shift the percentage; trust the module's 4 mA offset
FC106 RET_VAL = W#16#8000 HI_LIM ≤ LO_LIM Ensure HI_LIM > LO_LIM; check for accidental swap
Counts written are correct but current is 0 mA Wrong PQW address – writing to a non-existent channel Cross-check HW config output address with the PQW in the program
SCALE_X OUT error / overflow bit set NORM_X VALUE outside MIN..MAX Clamp HMI input 0.0–100.0 with LIMIT block before NORM_X
Output jitters ±1 LSB Noise on HMI input or floating-point rounding Round to nearest integer; add 10 ms low-pass on the input

Specifications of Common Siemens Analog Output Modules

Catalog number Channels Resolution Current ranges Typical use
6ES7332-5HD01-0AB0 (SM 332) 8 AO 12 bit + sign ±20 mA, 0/4..20 mA, 4..20 mA HART S7-300 standard
6ES7332-8TF01-0AB0 (SM 332) 8 AO 16 bit ±20 mA, 0/4..20 mA High-precision S7-300
6ES7334-0CE01-0AA0 (SM 334) 4 AO + 4 AI 12 bit 0..20 mA, ±10 V Cost-optimized S7-300
6ES7532-5HF00-0AB0 (SM 532) 8 AO 16 bit ±20 mA, 0/4..20 mA S7-1500 standard
6ES7135-6HD00-0BA1 (ET 200SP AQ) 4 AO 16 bit ±20 mA, 0/4..20 mA Distributed I/O on PROFINET

All modules above use the same user-side scaling 0..27648, regardless of internal resolution. The extra bits inside the module are used for diagnostics and noise-shaping, not for the user-program interface.

Edge Cases and Field Tips

  • Bipolar 0–100 % with offset: If the field device expects -100 %…+100 % and the HMI is 0–100 %, scale the HMI tag to -100…+100 in the PLC, then call FC106 with HI_LIM=100.0, LO_LIM=-100.0, BIPOLAR=TRUE. The result fills -27648…+27648.
  • Reversed output (valve close at 100 %): Subtract from 27648: PQW := 27648 - RawCount; or set NORM_X MIN/MAX to 100.0/0.0 so the mapping flips natively.
  • Cascaded loops: If the percent input is itself the output of a PID block (e.g. a valve position controller), use the PID's LMN output directly as the engineering value – it is already 0..100 % REAL on S7-300/400 and -100..+100 % on S7-1500 PID_Compact.
  • Cold-junction / channel diagnostics: On 16-bit modules, use SFC51 "SSL_PARTIAL_LIST" to read the channel diagnostic bytes if the output does not match the expected current – the module may have raised an "overload" or "wire break" diagnostic that the controller does not propagate automatically.
  • Watchdog / CPU STOP behavior: Configure the module's substitute value behavior in the device configuration. If you set "Keep last value", the PQW retains the last integer when the CPU goes to STOP; with "Substitute value" you can pre-define a safe current (e.g. 4 mA).

Frequently Asked Questions

Should I use SCALE or UNSCALE for a 4–20 mA output?

Use UNSCALE (FC106 on S7-300/400) or the combination NORM_X → SCALE_X (S7-1200/1500). SCALE / NORM_X→UNSCALE is for analog inputs (integer → real), not outputs. The naming is from the perspective of the field: UNSCALE = "destandardize the engineering value into raw counts for the output".

Why is the range 0–27648 and not 0–65535?

Siemens standardizes on 14-bit-plus-sign (27648 = 0x6C00) for all analog I/O modules, which simplifies firmware and diagnostic handling across the entire S7 family. Modules with higher internal resolution (16-bit) simply use the extra bits for noise shaping; the user program always sees 0–27648.

Do I have to subtract 4 mA in the program when the channel is configured for 4..20 mA?

No. The 4 mA live zero is generated by the output module itself. A PQW value of 0 already produces 4 mA on a 4..20 mA-configured channel. Subtracting it again would shift the output to 0–16 mA instead of 4–20 mA.

What formula converts a raw count in PQW back to a percent?

Percent = (RawCount / 27648) × 100 on a 4..20 mA channel, where 0 counts corresponds to 0 % (4 mA) and 27648 counts corresponds to 100 % (20 mA). For diagnostics you can use FC105 SCALE (S7-300/400) or SCALE_X + NORM_X (S7-1200/1500) in reverse order.

My HMI shows 80 % but the actuator only reaches 70 % of stroke. Where is the conversion wrong?

The percent-to-current scaling is correct; the issue is the actuator's stroke calibration. Verify the field device's zero (4 mA = fully retracted) and span (20 mA = fully extended) with a manual current source, then adjust the actuator's mechanical zero/span pots per the manufacturer manual. The PLC scaling does not need to be touched.

Back to blog