TP900 Comfort Panel: Scale Modbus Tags While Preserving Decimals

David Krause16 min read
HMI ProgrammingSiemensTroubleshooting
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

TP900 Comfort Panel: Scale Modbus Tags While Preserving Decimals

1. Problem Description

When polling Modbus RTU energy analyzers (Siemens PAC2200, PAC3200, PAC4200, Sentron PAC, Schneider PM5000, ABB M2M, or third-party DIN-rail meters) through a Siemens TP900 Comfort Panel, raw holding register values are delivered as integers (typically 16-bit Word or Int). Engineers must then display these in engineering units with one or two decimal places:

  • Raw register: 1234
  • Engineering display: 123.4 A

The Comfort Panel's Linear Scaling property on the HMI tag appears to perform the division, but the I/O field shows 123 A instead of 123.4 A. The same value written to a CSV log, SQL database, or audit trail loses the fractional part, invalidating energy and power-quality post-event analysis.

The defect affects all 4th-generation Comfort Panels: TP700, TP900, TP1200, TP1500, TP1900, TP2200 and the KP400, KP700, KP900, KP1200 Key Panels running WinCC Comfort, WinCC Advanced, or TIA Portal V16 / V17 / V18 / V19 / V20 / V21 projects. The same scaling limitation exists in WinCC Professional for PC Runtime and the RT Advanced / RT Professional software controllers.

2. Root Cause: Data Type is Not Changed by Linear Scaling

TIA Portal's Linear Scaling only applies a mathematical mapping between two value ranges. It does not promote the underlying PLC or HMI tag data type. The TIA Portal help explicitly states:

"To apply linear scaling to a tag, you must specify one value range on the HMI device and one on the PLC. The value ranges will be mapped to each other linearly."

If the HMI tag is configured as Int (16-bit signed, range -32768 to 32767) or Word (16-bit unsigned, range 0 to 65535), the result of 1234 / 10 = 123.4 is truncated to 123 because the destination data type cannot store fractional values.

The runtime actually performs the following operation:

DisplayValue = INT( (RawValue - PLC_Low) * (HMI_High - HMI_Low) / (PLC_High - PLC_Low) + HMI_Low )

When the destination data type is integer, the implicit INT() cast truncates the fractional part. There is no automatic type promotion from Int to Real. This behavior is consistent across Comfort Panels, WinCC Runtime Advanced, and WinCC Runtime Professional.

Engineering caveat: Some users configure the Linear Scaling range as PLC 0–1 / HMI 0–0.1 believing this solves the problem. It does not — the same integer truncation occurs. Always confirm the target tag data type, not just the scaling ratio.

3. Solution 1: Display Formatting on the I/O Field

If the scaled value is needed only for on-screen visualization, change the I/O field's display format instead of the tag's scaling. This is the lowest-effort fix and does not require PLC code changes.

  1. Open the screen containing the I/O field bound to the integer tag.
  2. Select the I/O field, open Properties > General > Appearance / Display.
  3. Set Format Type = Decimal.
  4. Set Decimal Places = 1 (or as required).
  5. Optionally configure Format Pattern = 999.9 for zero-padded alignment.
  6. Compile the HMI project (Ctrl+B) and download.

This changes only what is rendered on the HMI screen. The tag value in the HMI runtime and the value written to logs remain as the original integer 1234. Therefore this approach is not suitable for CSV, SQL, or trend logging where the engineering-unit value is required.

Aspect Affected by Display Format
I/O field on screen Yes
Text field concatenation No (uses raw value)
CSV log No
SQL log No
Trend view No
Recipe / Set value No

4. Solution 2: Convert to Real in the PLC

The most reliable solution for permanent scaling with full decimal retention is to convert the raw integer into a Real (IEEE 754 single-precision, 32-bit) value on the PLC side before exposing it to the HMI. This also allows for scaling factors that are not pure powers of ten (for example, calibration offsets or CT-ratio corrections).

S7-1200 / S7-1500 SCL Example

// Convert Current_L1_Raw (Int) to Current_L1_Scaled (Real)
#Current_L1_Scaled := INT_TO_REAL(#Current_L1_Raw) / 10.0;

// Alternative with explicit rounding for stable display
#Current_L1_Scaled := REAL(ROUND(#Current_L1_Raw / 10.0 * 10.0)) / 10.0;

// Three-phase average from PAC4200 (raw CT secondary in mA)
#Current_Avg_Scaled := (INT_TO_REAL(#I_L1_Raw) + INT_TO_REAL(#I_L2_Raw) + INT_TO_REAL(#I_L3_Raw)) / 30.0;

S7-300 / S7-400 STL Example

L     "Current_L1_Raw"        // INT
ITD                           // Convert INT to DINT
DTR                           // Convert DINT to REAL
L     1.000000e+001            // Load 10.0
/R                            // REAL division
T     "Current_L1_Scaled"     // Store to REAL tag

Configuration in TIA Portal

  1. Open the PLC data block (DB) containing the scaled value.
  2. Define Current_L1_Scaled as Real (32-bit floating point).
  3. Add the SCL or STL code to the cyclic OB (OB1 for S7-300/400, OB1 or OB35 for S7-1200/1500).
  4. Create an HMI tag pointing to %DB1.DBD0 with PLC data type Real.
  5. Do not configure Linear Scaling on the HMI tag — the scaling is already applied in the PLC.
  6. Bind the I/O field to the HMI tag and set Decimal Places = 1.
Real-to-Int round-trip: When the scaled Real value is written back to a Modbus register as an integer (for example, by the energy analyzer), use REAL_TO_INT(value * 10.0) to re-inject the decimal as a scaled integer. Always clip against the register range to avoid overflow on the analyzer side.

5. Solution 3: Use InverseLinearScaling in Events

If the PLC cannot be modified (for example, the energy analyzer is on a third-party network or the tag must remain an integer for diagnostic reasons), use the built-in system function InverseLinearScaling. This function is documented for inverting a previously applied scaling, but it is commonly repurposed on TP900 / TP1200 systems to multiply an integer by a factor and produce a Real output without PLC code.

Why InverseLinearScaling, not LinearScaling?

The standard LinearScaling function also accepts Real endpoints but, when bound to an Integer source tag, the runtime pre-truncates the input. InverseLinearScaling applied as a Change value event can be configured to fire on every tag update and to write into a separate Real target tag without intermediate integer storage.

Configuration in TIA Portal

  1. In the project tree, expand HMI Tags.
  2. Double-click the source integer tag (e.g., Current_L1).
  3. Open Properties > Events.
  4. Under the Change value event, click Add.
  5. Insert the system function InverseLinearScaling from the Calculation group.
  6. Configure the parameters:
Tag:                  Current_L1          (Int)
Lower point 1:        0
Upper point 1:        10
Lower point 2:        0.0
Upper point 2:        1.0
Output target tag:    Current_L1_Real     (Real, must exist)
  1. Create Current_L1_Real as a new HMI tag with data type Real. For internal-only scaling, point it at an internal HMI tag (no PLC address).
  2. Bind the I/O field on the screen to Current_L1_Real.
  3. Bind any logging, trend, or recipe operation to the same Real tag.
  4. Compile and download to the TP900.

The Change value event fires immediately on each Modbus poll cycle (default 1 s acquisition), which is significantly faster than the 1-minute minimum of a scheduled script.

6. Solution 4: Reduce Script Trigger Interval

The original poster reported that the VB script minimum trigger was 1 minute. This is controlled by the scheduler in the HMI runtime and is a deliberate design choice to limit CPU load. Approaches to shorten the trigger interval:

  • Use a Change value event bound to a system function (covered in Solution 3). The event fires on every tag update, typically 1 s, and does not require any script.
  • Reduce the Modbus Acquisition cycle: HMI Tags > Connection properties > Tag > Acquisition cycle. Set to 1 s for fast updates or 500 ms for higher refresh rates (firmware-dependent).
  • Use a C-script instead of a VB-script where supported. C-scripts allow lower trigger intervals on Comfort Panel firmware V16 and later. The minimum trigger cycle is 100 ms for C-scripts on TP1500 / TP1900 / TP2200 with sufficient CPU headroom.
  • Avoid scheduled scripts entirely for high-rate scaling; prefer the Change value event with a system function.
Approach Min Trigger Interval Decimal Preservation CPU Load
VB Scheduled Script 1 s (firmware-dependent) Yes (if Real) Medium
C Scheduled Script 100 ms (V16+) Yes (if Real) Medium-High
Change value event Tag update cycle (default 1 s) Yes (Real output) Low
InverseLinearScaling event Tag update cycle Yes Low
PLC-side Real conversion PLC OB1 cycle (typically 10–100 ms) Yes Negligible on HMI
TP900 firmware V18+ behavior: On firmware V18.0.0.0 and later, the Change value event reliably fires on every Modbus poll, including when the value has not changed. This is the recommended path for decimal-preserving scaling on Comfort Panels where PLC modification is undesirable.

7. Modbus RTU Tag Configuration on TP900

The TP900 Comfort Panel supports Modbus RTU master on the onboard RS422/485 port (X10) at up to 115200 bit/s. For typical energy analyzer applications, the recommended configuration is:

Parameter Recommended Value
Driver Modbus RTU (COMx)
Baud rate 9600 / 19200 (per analyzer)
Parity Even (most analyzers)
Stop bits 1
Data bits 8
Acquisition cycle 1000 ms
Timeout 1500 ms
Retries 2
Tag address example 40001 (function code 03, holding register)

For Siemens PAC2200, PAC3200, and PAC4200 energy analyzers communicating over Modbus RTU, the raw current registers return values in mA. To display in A, divide by 1000 (use scaling range PLC 0–1000 / HMI 0–1.0 and a Real tag). Voltage registers typically return values in V already, requiring no scaling.

Example Register Map for PAC4200

Register Function Unit in Register Scaling Factor
0001 Voltage L1-N V None
0003 Current L1 mA ÷ 1000
0005 Active Power L1 W None
0007 Power Factor L1 0.001 ÷ 1000
0009 Frequency 0.01 Hz ÷ 100

Always confirm the register map against the analyzer's manual (e.g., PAC4200 manual chapter "Modbus communication") before commissioning. Incorrect register addresses return 0 silently without raising an error on the Comfort Panel.

8. Tag Data Types and Precision Reference

The TP900 Comfort Panel supports the following numeric data types. Choose the type that matches the precision and range required.

Data Type Size (bits) Range Decimal Places Use Case
Bool 1 0 or 1 0 Status flags, digital inputs
Int 16 -32768 to 32767 0 Counters, raw Modbus registers
Word 16 0 to 65535 0 Unsigned raw registers
DInt 32 -2^31 to 2^31-1 0 Large counters, scaled mA values
DWord 32 0 to 2^32-1 0 Unsigned 32-bit values
Real 32 ±3.4e38 (~7 digits) ~7 Engineering units, scaling output
LReal 64 ±1.7e308 (~15 digits) ~15 High-precision calculation, energy totals
String n × 8 ASCII messages, log entries
WString n × 16 Unicode messages

For TP900 Comfort Panel system limits on tags, scripts, connections, and logging, refer to the official Comfort Panel Performance Features documentation. Typical limits for the TP900: 4096 HMI tags, 2048 PowerTags, 32 connections, 200 logs, 50 simultaneous scripts.

9. Comparison of Scaling Methods

Method Decimal Preservation Affects Logs PLC Code Required Implementation Effort
Linear Scaling on Int tag No (truncates) No effect (still raw) No Low (incorrect)
Display Format on I/O Field Visual only No No Lowest
Convert to Real in PLC Yes Yes Yes Medium
InverseLinearScaling event Yes Yes No Medium
Tag limits (low/high) No (clamping only) No No Low
External C-More Micro HMI Yes (native) Yes No High (HW swap)

For projects where scaling and tag management dominate the application, third-party HMIs such as the AutomationDirect C-More Micro use a separate TAG Database structure that supports scaling natively without the integer-truncation limitation. See the C-more Micro HMI TAG Database reference for tag management on that platform. This option requires swapping HMI hardware and is only relevant for new installations.

The TIA Portal help on Linear Scaling of a Tag covers the parameter mapping in detail and should be referenced for verification when commissioning.

10. Step-by-Step: Configuring InverseLinearScaling on TP900

  1. Open the TIA Portal project (V16 / V17 / V18 / V19 / V20 / V21).
  2. In the project tree, expand HMI Tags under the TP900 device.
  3. Double-click the source tag (e.g., Current_L1) and verify its data type is Int or Word with address %DB1.DBW0.
  4. Click Properties > Events.
  5. Under the Change value event row, click the empty cell and select Add function.
  6. From the function list, choose InverseLinearScaling under Calculation.
  7. Click the function to open its properties panel and enter:
Source tag:           Current_L1
Lower point 1:        0
Upper point 1:        10
Lower point 2:        0.0
Upper point 2:        1.0
Output (target) tag:  Current_L1_Real
  1. If Current_L1_Real does not yet exist, create it: HMI Tags > Add new tag > Name = Current_L1_Real > Data type = Real > Connection = internal (no PLC address) for HMI-only scaling, or point to a PLC DB address for cross-device visibility.
  2. Open the screen containing the I/O field and rebind it to Current_L1_Real.
  3. Configure I/O field Properties > General > Display: Format Type = Decimal, Decimal Places = 1.
  4. Update any logging, trend, or recipe reference to use Current_L1_Real.
  5. Compile > HMI > Download to device > Restart Runtime.

After the runtime restarts, the I/O field shows the scaled value within one acquisition cycle (default 1 s).

11. Verification Procedure

After applying any solution, perform the following checks before handing the system over to operations:

  1. Tag Simulation: Open HMI > Tools > Tag Simulation. Enter 1234 on the source tag. Confirm the I/O field shows 123.4 A (or equivalent).
  2. Logging Spot-Check: Trigger an event that writes the tag to a CSV or SQL log. Open the log and confirm the recorded value contains the decimal place, e.g., 123.4 not 123.
  3. Trend Display: Add a trend view bound to the scaled Real tag. Confirm the curve displays fractional values without step quantization.
  4. Performance Check: Monitor the CPU load via the HMI's system diagnostics (Control Panel > System > Performance) or via WinCC Runtime's task overview. CPU usage should remain below 70% during sustained Modbus traffic.
  5. Cross-Verification: Compare the HMI display with the energy analyzer's local display (or a calibrated reference meter such as a Fluke 173x or Hioki PW3198). Both must agree within the analyzer's measurement tolerance, typically ±0.5% for current and ±0.2% for voltage.
  6. Edge-Case Test: Apply zero input (0) and confirm the I/O field shows 0.0 A, not 0 or blank.
  7. Range Limit Test: Apply the analyzer's maximum value (e.g., 5000) and confirm the I/O field shows 500.0 A without overflow or "###" overflow markers. Configure Tag limits as documented in the Defining Limits for a Tag Siemens Support article to prevent invalid displays.

12. Troubleshooting Matrix

Symptom Likely Cause Resolution
Displayed value is integer despite scaling HMI tag data type is Int or Word Convert to Real in PLC or use InverseLinearScaling with a Real target tag
Script not triggering more than once per minute Scheduler minimum interval of 1 min Use Change value event instead of scheduled script
I/O field shows "###" Value exceeds configured format width Increase Format Pattern width or reduce decimal places
Value flickers or shows "-" Tag out of range or connection lost Check limits in Properties > Limits; verify Modbus connection state
Displayed value jumps between two stable readings Polling cycle too slow Reduce Acquisition cycle to 1 s or 500 ms
CSV log shows unscaled integer Logging is bound to raw Integer tag Re-bind logging to scaled Real tag
InverseLinearScaling event returns error 400001 Target Real tag does not exist Create the Real tag first, then assign the function
TP900 shows connection timeout on COM1 Wrong COM port parameters or wrong wiring (A/B polarity) Verify baud rate, parity, stop bits; swap A+ and B- on RS485 bus
Scaled value drifts over time Floating point accumulation in scaled Real tag Reset the Real tag on power-up or use INT_TO_REAL only at the conversion point
Trend shows steps instead of curve Trend bound to Int tag, not Real Re-bind trend to scaled Real tag
I/O field shows NaN after PLC restart PLC DB not initialized with Real value Set Real tag to 0.0 in PLC startup OB100 / OB Startup

Field-Proven Caveats

  • Logging across power cycles: If the HMI loses power between Modbus polls, the last scaled Real value is lost unless bound to a retentive PLC tag. Use a retentive DB area on the PLC for long-term energy accumulation.
  • Endian mismatch: Some Modbus energy analyzers (notably Schneider PM5000 series) return 32-bit floating-point values across two 16-bit registers in little-endian order. The Comfort Panel's Modbus driver supports this via the "Word swap" option in the connection properties.
  • Script CPU load on TP900: On TP900 firmware V17 and earlier, scheduled C-scripts with sub-second intervals can starve the Modbus driver. Always verify Modbus communication remains responsive after enabling C-scripts.
  • Recipe handling: If the scaled value is part of a recipe, ensure the recipe element uses the Real tag, not the Int tag. Otherwise the recipe stores the integer and the decimal is lost on recipe load.
  • Audit trail: For GMP / FDA 21 CFR Part 11 audit trails on pharmaceutical systems, bind the audit log to the Real tag, not the Int tag, to preserve the engineering-unit value in the signed audit record.

Why does Linear Scaling on the TP900 Comfort Panel drop decimal places?

Linear Scaling does not change the underlying tag data type. An Int or Word tag divided by 10 returns 123 (truncated) rather than 123.4 because the destination data type cannot store fractional values. Convert the value to Real in the PLC using INT_TO_REAL and division by a Real divisor, or use the InverseLinearScaling system function on a Change value event to produce a Real output.

Can I set a script trigger below 1 minute on a TP900 Comfort Panel?

Yes. Use a Change value event bound to a system function such as InverseLinearScaling. The event fires on every tag update (default 1 s acquisition cycle), which is significantly faster than a 1-minute scheduled script. C-scripts on firmware V16 and later allow trigger intervals down to 100 ms, but this increases HMI CPU load.

Does the display format on the I/O field affect logged values?

No. Display formatting only affects the rendered I/O field on the screen. The underlying tag value remains as the raw integer, so CSV logs, SQL logs, trend views, and recipe values continue to record the unscaled value. For logs that need engineering-unit values, bind them to a Real tag and convert in the PLC or HMI.

What is the recommended Modbus RTU acquisition cycle for energy analyzer data on the TP900?

Set the acquisition cycle to 1 s for typical 50/60 Hz measurements. Faster cycles (e.g., 500 ms) are possible but increase HMI CPU load and may exceed the analyzer's response time. Confirm the energy analyzer's Modbus response time in its manual — most support 100–500 ms turnaround at 9600 baud.

Where do I find the InverseLinearScaling function in TIA Portal?

Navigate to HMI Tags > select tag > Properties > Events > Change value > Add function. The InverseLinearScaling system function is in the "Calculation" group. Configure the function with the source tag, two value ranges, and the target Real tag. Compile and download to apply the configuration.

Can I keep the integer tag intact and still display decimals on the TP900?

Yes, using the InverseLinearScaling approach. The integer source tag is preserved at its original PLC address, and a separate Real HMI tag holds the scaled value. Bind the I/O field, logging, and trends to the Real tag. This pattern is preferred for diagnostics where the raw register value must remain visible alongside the engineering-unit display.

Back to blog