S7-1200 SM 1232 Analog Output: Scaling with NORM_X and SCALE_X

David Krause14 min read
S7-1200SiemensTutorial / 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

This reference covers configuring an S7-1200 SM 1232 analog output module for a 0-10 V actuator and explains how the TIA Portal NORM_X and SCALE_X instructions convert an engineering value (percent, degrees, millimeters, or any other plant unit) into the raw integer that the module expects at its output process image. The two blocks confuse new users because their names give no clue about their input or output range; once you understand that each performs half of a "user units to normalized value" mapping, the pair becomes the standard pattern for every analog I/O on an S7-1200 and S7-1500 controller.

The article covers the SM 1232 catalog numbers, the hardware configuration in TIA Portal, the 0..10 V wiring, the NORM_X and SCALE_X block parameters, three programming patterns (engineering units to 0..10 V, raw integer to 0..10 V, and manual SCL scaling), and the watch-table procedure used to verify the output with a multimeter. Reference the Siemens Industry Online Support portal for the S7-1200 System Manual that matches the firmware you run, and use the built-in TIA Portal F1 help on each instruction block for the most current parameter map.

SM 1232 Family and Output Specifications

The SM 1232 is the analog-output signal module (and SB 1232 the matching signal-board variant) for the S7-1200 family. Common order numbers and their capabilities are summarized below; the exact output range you can pick in TIA Portal depends on the variant installed. Always cross-check the order number printed on the front of the module against the configuration in Devices & Networks so you do not select a range the hardware cannot source.

Order Number Outputs Resolution Voltage Ranges Current Ranges
6ES7232-4HA30-0XB0 2 AO 12-bit ±10 V, 0..10 V 0..20 mA, 4..20 mA
6ES7232-4HB30-0XB0 2 AO 14-bit ±10 V, 0..10 V 0..20 mA, 4..20 mA
6ES7232-4HD30-0XB0 4 AO 12-bit ±10 V, 0..10 V 0..20 mA, 4..20 mA
6ES7232-4HF30-0XB0 4 AO 16-bit ±10 V, 0..10 V 0..20 mA, 4..20 mA
SB 1232 AQ 1 x 12-bit 1 AO 12-bit ±10 V, 0..10 V 0..20 mA, 4..20 mA

For a "0..10 V to drive a damper actuator" use case, the configuration is straight-forward:

  • Voltage output (not current) for the channel that connects to the actuator.
  • Output range 0..10 V (unipolar, not ±10 V).
  • Enable short-circuit diagnostics. The SM 1232 will detect a sustained short on the V+ terminal and set the SF LED.
  • Leave wire-break diagnostics disabled unless the actuator draws measurable quiescent current; purely passive voltage-mode loads do not wire-break reliably.

Configuring the Module in TIA Portal

  1. Open the project, expand the S7-1200 station in Devices & Networks, and drag the SM 1232 from the hardware catalog on the right into the slot next to the CPU.
  2. Confirm the order number in the device view matches the physical module sticker.
  3. Select the module head and switch to Properties > Analog outputs.
  4. For the channel that drives the actuator, set:
    • Output type: Voltage
    • Output range: 0..10 V
    • Diagnostics: enable short-circuit of the output, leave wire-break disabled unless the actuator has a measurable series element.
  5. Compile and download to the CPU.
  6. Note the output address that appears in the device view (for example, %QW96 for the first AQ word of the SM 1232). This is the address the program writes.
If the SM 1232 is replaced with a different variant after deployment, TIA Portal issues a configuration mismatch error on download. Re-select the order number before you re-download to avoid either clamped or unsaturated outputs.

Field Wiring and How an Integer Becomes a Voltage

Voltage outputs on the SM 1232 are differential. The actuator is wired between the channel's V+ terminal and the corresponding ground terminal (M or MANA) on the same module. Do not tie the SM 1232 ground to the actuator's load-side ground unless both devices are referenced to the same panel ground; floating output references are normal with pneumatic damper actuators.

SM 1232 Terminal Function Connection
AQ0 V+ Channel 0 voltage output, positive Damper actuator + (signal high)
AQ0 M Channel 0 analog ground Damper actuator - (signal return)
AQ1 V+ Channel 1 voltage output, positive Not connected if unused
AQ1 M Channel 1 analog ground Not connected if unused
24 V / 24 M Module power supply External 24 VDC, fused at ≤ 2 A

Use shielded twisted pair cable for analog runs longer than a few metres, route away from VFD cables and contactor switching, and bond the shield at the cabinet end only.

The SM 1232 does not know what "5 V" or "10 V" means in your program. It expects an integer at the output process image and linearly converts that integer to a voltage according to the range you configured. For a 0..10 V unipolar range the conversion is:

Process Word Value (INT) Output Voltage Notes
0 0.000 V Zero scale
6912 2.500 V 25 % of full scale
13824 5.000 V 50 % of full scale
27648 10.000 V Full scale, nominal range end
-1 (0xFFFF) 0 V (clamped) Below zero, clamped to 0 V because the range is unipolar
32511 ~11.76 V Over-range ceiling; module clamps here

Note the asymmetry: bipolar outputs (e.g. ±10 V) use the integer range -27648..+27648 with sign, but the 0..10 V range is strictly non-negative. Writing a negative integer does not produce a negative voltage; the module clamps it to 0 V. Always pre-clamp or pre-scale your integer before the write.

NORM_X: The Normalization Block

NORM_X accepts an input VALUE whose natural range is [MIN, MAX] and rescales it into the normalized range [0.0, 1.0] for unipolar values, or [-1.0, 1.0] for bipolar values. The block returns a REAL value.

Pin Data Type Meaning
MIN REAL Low end of the input's natural range
VALUE REAL The actual value to normalize
MAX REAL High end of the input's natural range
ENO BOOL Status output (CPU-side error)
OUT REAL Normalized value in [0.0, 1.0] or [-1.0, 1.0]

The scaling math is:

OUT = (VALUE - MIN) / (MAX - MIN), then optionally remapped to ±1.0 if the range is bipolar.

If VALUE equals MIN, OUT = 0.0 (or -1.0 for bipolar). If VALUE equals MAX, OUT = 1.0 (or +1.0). NORM_X does not clamp: values outside the input range simply produce normalized values outside the [0.0, 1.0] envelope, which is normally undesirable; sanitize on the upstream side or add a LIMIT block.

Example with a percent input 0..100 %:

NORM_X(VALUE := "dbValve".rPercent,   //  0..100 REAL
       MIN   := 0.0,
       MAX   := 100.0
       )  =>  "dbValve".rNormalized;   // 0.0..1.0 REAL

SCALE_X: The Scaling Block

SCALE_X is the inverse: it accepts a normalized value (0.0..1.0 or ±1.0) and rescales it into a target range [MIN, MAX]. The output type is selected by the block instance and may be REAL, INT, or DINT depending on which variant is dropped into the program.

Pin Data Type Meaning
MIN Depends on instance Low end of the desired output range
VALUE REAL The normalized value from NORM_X (0.0..1.0)
MAX Depends on instance High end of the desired output range
OUT REAL, INT, or DINT Scaled value ready to move to the hardware

Math:

OUT = MIN + VALUE * (MAX - MIN)

Drop the variant that matches your downstream tag from Basic Instructions > Conversion Operations > SCALE_X. Using SCALE_X_INT lets you wire the OUT pin directly to the output process word and skip the manual REAL_TO_INT step.

Example for a 0..10 V output range expressed as 0..27648 integers:

SCALE_X(VALUE := "dbValve".rNormalized,   // 0.0..1.0 REAL
         MIN   := 0,
         MAX   := 27648
         )  =>  "dbValve".iAQ0;             // 0..27648 INT

Why NORM_X and SCALE_X Go Together

The reason the pair appears in nearly every Siemens sample is the asymmetry in the block definitions: NORM_X always returns 0.0..1.0 and SCALE_X always expects 0.0..1.0 (or ±1.0 for bipolar). Each block is half a conversion on its own. Together they form a complete linear mapping from any input range to any output range with a single pair of constants per stage:

User Units (a..b)  --NORM_X-->  0.0..1.0  --SCALE_X-->  Hardware Units (c..d)
User Units 0..100 % NORM_X MIN=0.0, MAX=100.0 Normalized 0.0..1.0 SCALE_X MIN=0, MAX=27648 AQ Word 0..27648 SM 1232 0..10 V at terminals Actuator 0..10 V

This pattern matters because:

  1. It localizes constants. The MIN/MAX values appear at one place each, not scattered in formulas.
  2. Changing ranges does not require rewriting the program. Move from 0..100 % to 0..50 °C and you only change MIN/MAX on NORM_X.
  3. Diagnostics read sensibly. A NORM_X output of 0.5 immediately tells you the input is at the midpoint of its physical range; a SCALE_X output of 13824 immediately tells you the hardware is at half scale.
  4. It maps cleanly onto SCL as two function calls and onto FBD/LAD as two block instances wired pin-to-pin.
NORM_X and SCALE_X are not the only way to scale; you can divide and multiply by hand in SCL. The pair is recommended because it is self-documenting in the program and because the same code transfers between S7-1200 and S7-1500 firmware without modification.

End-to-End Example: 0..100 % Demand to 0..10 V

The scenario: a SCADA sends a percent demand (0..100) to tag "dbValve".rPercent. The goal is to drive a damper actuator wired to channel 0 of an SM 1232 (output range 0..10 V) so that 0 % gives 0 V (damper closed) and 100 % gives 10 V (damper fully open). The output process word is, for example, %QW96.

  1. Create a data block with three tags:
    • rPercent — REAL, the user demand (0..100)
    • rNormalized — REAL, intermediate (0.0..1.0)
    • iAQ0 — INT, the value moved to the output
  2. Create an FB (or write the logic in OB1 — the layout is the same).
  3. Drop NORM_X (REAL variant) from the instruction tree. Wire:
    • MIN = 0.0
    • VALUE = "dbValve".rPercent
    • MAX = 100.0
  4. Wire NORM_X.OUT to tag "dbValve".rNormalized.
  5. Drop SCALE_X (INT variant). Wire:
    • VALUE = "dbValve".rNormalized
    • MIN = 0
    • MAX = 27648
  6. Wire SCALE_X.OUT to "dbValve".iAQ0 and add a MOVE box (or use a coil in ladder) to copy "dbValve".iAQ0 to the output word %QW96 declared in PLC tags with the address of the SM 1232 channel 0.

The same logic in SCL for an FB function block:

// Demand from SCADA, normalized internally, scaled to AQ integer.
"dbValve".rNormalized := NORM_X(
                            MIN   := 0.0,
                            VALUE := "dbValve".rPercent,
                            MAX   := 100.0);

"dbValve".iAQ0 := SCALE_X(
                     MIN   := 0,
                     VALUE := "dbValve".rNormalized,
                     MAX   := 27648);

// Output write to the SM 1232 process word
"PLC_Tags".AQ0 := "dbValve".iAQ0;

In ladder this is three rungs:

  1. Rung 1: NORM_X box with MIN=0.0, IN=tag value, MAX=100.0 → rNormalized
  2. Rung 2: SCALE_X_INT box with MIN=0, IN=rNormalized, MAX=27648 → iAQ0
  3. Rung 3: --[ MOVE ]-- EN=%I0.0 IN="dbValve".iAQ0 OUT=%QW96

Once downloaded, holding "dbValve".rPercent at 25.0 should give NORM_X = 0.25, SCALE_X = 6912, and a measured voltage of 2.5 V ± tolerance at the actuator terminals.

Alternative Scaling Patterns and SCL Manual Scaling

If the upstream logic already produces integers in the SM 1232's natural range (a PID block whose output you then multiply and write directly to the AO, or a faceplate percent display that already provides a 0..1.0 normalized value), SCALE_X alone is enough:

"dbValve".iAQ0 := SCALE_X_INT(
                     MIN   := 0,
                     VALUE := "dbValve".rNormalized,    // 0.0..1.0
                     MAX   := 27648);
"PLC_Tags".AQ0 := "dbValve".iAQ0;

The shortest possible program writes an integer directly to the output process word — useful for hard-coded commissioning values and module replacement tests, but not for production code where the demand is a percentage or a real-world measurement:

"PLC_Tags".AQ0 := INT#13824;   // 5.00 V
"PLC_Tags".AQ0 := INT#27648;   // 10.00 V
"PLC_Tags".AQ0 := INT#0;       // 0.00 V

When call overhead matters (tight cyclic interrupt OB, for example) you can scale by hand in SCL and avoid the two block instances entirely:

// Manual mapping of 0..100 percent to 0..27648
"dbValve".rRaw := 0.0
                 + ("dbValve".rPercent / 100.0)   // 0.0..1.0
                 * 27648.0;                         // 0..27648

"dbValve".iAQ0 := REAL_TO_INT("dbValve".rRaw);
"PLC_Tags".AQ0  := "dbValve".iAQ0;
Watch the conversion: REAL_TO_INT truncates. For round-to-nearest behaviour, add 0.5 before truncating, or use ROUND / REAL_TO_DINT with an explicit check on the integer range before writing the peripheral word.

Commissioning, Diagnostics, and Field Verification

Use a watch table for commissioning and keep it as the standard reference procedure across projects:

  1. Open Online > Watch Tables and create a new table with the tags in "dbValve" and the AO tag %QW96.
  2. Go online; the monitor column should now show rPercent, rNormalized, and iAQ0 updating each cycle.
  3. Set rPercent = 0.0 in the modify column. Expect rNormalized = 0.0, iAQ0 = 0, V_out = 0.0 V on the multimeter.
  4. Set rPercent = 50.0. Expect rNormalized = 0.5, iAQ0 = 13824, V_out ≈ 5.0 V.
  5. Set rPercent = 100.0. Expect rNormalized = 1.0, iAQ0 = 27648, V_out ≈ 10.0 V.
  6. Set rPercent = 110.0 to confirm the over-range path. iAQ0 will exceed 27648 (because SCALE_X does not clamp) and the SM 1232 will pin the output voltage just above 10 V; clamp at the SCADA side to avoid stacking over-range diagnostics.
Symptom Likely Cause Fix
Output stuck at 0 V Module not configured for voltage, only current Change output type in Properties > Analog outputs
Output stuck at 0 V Power supply missing on the SM 1232 (L+ / M not powered) Power the module's power terminals independently of the CPU backplane
Output full scale and CPU in stop STOP output behaviour set to "Last value" with a stale value Use a defined substitute value under channel configuration
Voltage measures 0 V at all demands but tag updates Output range set to 4..20 mA by mistake Re-select 0..10 V
Voltage saturates around 7 V at iAQ0 = 27648 Actuator load is too high impedance, or polarity reversed Verify load ≥ 1 kΩ in voltage mode; check V+ / M terminals
Output value flickers or jitters Cable in same conduit as VFD, broken shield ground Re-route, ground shield at cabinet end only
SF LED amber on the SM 1232 Short-circuit or wire-break diagnostic triggered Disable the diagnostic that does not match the wiring, or fix the wiring
SCALE_X output around 13824 yet V_out measures 2.5 V Expectation error, not a fault; 13824 / 27648 = 50 % Confirm math: 50 % of 10 V is 5 V, not 2.5 V. iAQ0 = 6912 produces 2.5 V

If PROFIBUS or PROFINET diagnostics are enabled, the diagnostic interrupt places a record into the diagnostic buffer that you can inspect with Online > Diagnostics > Diagnostics Buffer. The buffer event references the channel, direction ("Output channel 0 short-circuit"), and the order number of the SM 1232.

The final verification matrix on the cabinet door should read:

  • Module order number in TIA Portal matches the installed hardware.
  • Channel configured for "Voltage" output type with "0..10 V" range.
  • 24 V DC on the SM 1232 power terminals, fused at ≤ 2 A.
  • Shielded pair from the module to the actuator, terminated at the cabinet end.
  • Watch table shows the correct normalized (0..1.0) and scaled (0..27648) intermediates.
  • Multimeter at the actuator terminals: 0 % → ≈ 0 V; 50 % → ≈ 5 V ± 0.05 V; 100 % → ≈ 10 V ± 0.05 V.
  • SF LED off, BF LED off, RUN LED steady green on the SM 1232.
  • No diagnostic interrupt entries in the buffer for the commissioning period.
  • Actuator response confirmed by position feedback (3-point damper indicator or bus feedback from a smart actuator).

FAQ

Do I really need both NORM_X and SCALE_X to drive an SM 1232 0..10 V output?

No. They are the standard Siemens pattern because the pair maps symmetrically (0..1.0 normalized value), but you can use SCALE_X alone if your upstream value is already 0..1.0, or skip both blocks and write the raw integer 0..27648 directly to %QW. Pick the variant that matches what the upstream tag already contains.

What is the maximum integer I can write to the SM 1232 for a 0..10 V output?

The nominal full-scale value is 27648. The module accepts higher values up to about 32511 and clamps the output to roughly 11.76 V; values in this region produce diagnostic warnings if over-range monitoring is enabled. Stay within 0..27648 for normal operation.

Why does SCALE_X output a REAL even though the AO process word is INT?

SCALE_X is overloaded by instance: drop the SCALE_X_INT variant from the instruction tree to get an INT output. If you drop the REAL variant, wire a REAL_TO_INT or ROUND block between SCALE_X and the output word. Using the INT variant eliminates that conversion step.

My actuator wants 0..10 V but reads only 0 V even though iAQ0 shows the right value in the watch table.

The classic cause is the SM 1232 being configured for current output (0..20 mA or 4..20 mA) instead of voltage. Open the device configuration of the SM 1232 and change the channel output type to "Voltage" with range "0..10 V". A second common cause is missing 24 V supply on the module's power terminals; the SM 1232 logic runs off the backplane but the analog output stage requires external L+ and M.

Can I use NORM_X and SCALE_X on an S7-1500 with the same tags?

Yes. Both blocks are present in TIA Portal for the S7-1200 and S7-1500 instruction trees with identical pins and identical behavior. Code that uses NORM_X plus SCALE_X transfers cleanly between the two controller families without modification.

How do I prevent the damper from slamming when SCADA sets a demand above 100 %?

Clamp on the SCADA side or in the SCALE_X feed. A common pattern is to insert a LIMIT block that forces the integer to stay within 0..27648 before the MOVE to %QW. The same approach in reverse (LIMIT 0..27648 lower bound) protects the AO if a value comes in negative and avoids hitting the unipolar clamp on the SM 1232.

Back to blog