S7-1200 Profibus DP Hex Conversion Using CONV Instruction

David Krause19 min read
S7-1200SiemensTroubleshooting
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

Problem Overview

An S7-1200 PLC is configured as a Profibus DP master to a Bosch Rexroth HACD-2 servo drive. The drive expects each parameter word to arrive on the Profibus wire as a 16-bit hexadecimal pattern; the controller does not decode ASCII, it decodes bits. The original symptom was a clean mismatch between the HMI setpoint and the drive's reported engineering value: entering 327670 decimal into the source tag produced a nonsensical value on the drive, while entering 0x0004FFF6 directly produced the correct engineering value of 1000. The formula used by the application was:

(desired_value - offset) * scale = raw_value
(1000 - 0) * 327.67 = 327670 = 0x0004FFF6

The fundamental rule that resolves the issue is that the bit pattern transmitted on Profibus DP is what the drive interprets. Whether the PLC engineer writes the value as 327670 decimal or as 0x0004FFF6 hex is irrelevant from the wire's perspective; both produce identical bytes. The bug was located upstream of the wire, in the MOVE block where a WORD source was feeding an INT destination. This article documents the root cause, the Siemens CONV and HTA/ATH instructions used to fix it, the data-type sizing rules that prevent recurrence, and the commissioning workflow that confirms the fix on a live Profibus DP segment.

Root Cause: MOVE Block Data Type Width and Signedness Mismatch

The Siemens TIA Portal compiler accepts a MOVE block where the input is a WORD (16-bit unsigned) and the output is an INT (16-bit signed). The compiler does not flag the mismatch because both operands occupy 16 bits; both pass the IEC 61131-3 width check. At runtime, bit 15 of the WORD value is interpreted as the sign bit of the INT. A value such as 0xFFF6 (65526 decimal) becomes -10 when cast as INT, which is exactly the "obscure number" reported in the original problem. The pattern repeats for any value where bit 15 is set: 0x8000..0xFFFF appears as -32768..-1.

The fix is to keep bit width and signedness consistent across the entire MOVE chain. Three legal combinations are shown below.

Source Tag Source Type Width Target Tag Target Type Width Status
Scale_Result INT 16-bit Output_Word WORD 16-bit Compile passes, runtime sign-flip on bit 15
Scale_Result DINT 32-bit Output_DWord DWORD 32-bit Compile passes, runtime correct
Scale_Result REAL 32-bit Output_DWord DWORD 32-bit Compile passes after explicit CONV, runtime correct
Scale_Result WORD 16-bit Output_DWord DWORD 32-bit Compile passes, runtime zero-extended
Enable IEC check on every block. Turn on "IEC check" in the block properties → Attributes tab of the OB, FB, and FC in TIA Portal. With IEC check on, the compiler rejects implicit conversions between WORD and INT, between WORD and UINT, and between INT and WORD. Production code should always leave IEC check on; this is the single most effective setting for preventing the WORD-to-INT sign-flip bug.

S7-1200 Data Types Relevant to Profibus DP Hex Payloads

Selecting the right data type is the foundation of correct hex payload transmission. The S7-1200 supports the IEC 61131-3 elementary types listed below; only a subset are commonly used in Profibus DP payload mapping.

thead>
Type Width (Bits) Range Signed Typical Use Case
BOOL 1 0..1 No Discrete I/O bit, Profibus DP status word bit
BYTE 8 0..255 No Byte-level Profibus slot, single ASCII character
WORD 16 0..65535 No Unsigned 16-bit Profibus parameter word
INT 16 -32768..32767 Yes Signed 16-bit scaled parameter
DINT 32 -2147483648..2147483647 Yes Large scaled value, 32-bit Profibus parameter
DWORD 32 0..4294967295 No Unsigned 32-bit hex payload, bit pattern container
REAL 32 ~±3.4E38 (7 decimal digits) Yes Intermediate scaling math, HMI input
LREAL 64 ~±1.7E308 (15 decimal digits) Yes High-precision scaling on S7-1500; not available on S7-1200
CHAR 8 ASCII 0..255 N/A Single ASCII character inside STRING
STRING[n] n*8 + overhead ASCII string of length n N/A Hex string for HMI display via HTA

The example value 327670 decimal equals 0x0004FFF6, a 20-bit unsigned pattern. It cannot fit in INT or WORD (both 16-bit, max 65535) and requires DINT or DWORD. If the Profibus DP parameter slot is 16 bits wide per the GSD file, the upper 4 bits of 0x0004FFF6 are either discarded, packed into the adjacent slot, or the scale factor must be reduced so the maximum scaled value fits in 16 bits. If the slot is 32 bits wide, the full DWORD transmits intact. Always verify the slot width in the GSD file before sizing the variable.

The CONV (Convert Value) Instruction

The CONV instruction in the S7-1200 basic instructions set converts any elementary data type to any other elementary data type. In LAD/FBD the source operand IN appears at the top of the block and the destination OUT at the bottom; a dropdown selector picks the target type explicitly. In SCL the equivalent form is out := _TO_(in);.

Source (IN) Destination (OUT) Result Behaviour Notes
INT DINT -32768..32767 sign-extended to 32 bits Default path for scaled math that may exceed 16 bits
DINT WORD Lower 16 bits only; upper 16 bits discarded Risk of silent truncation if value > 65535
DINT DWORD Bit pattern preserved, sign bit becomes data bit Correct hex payload for unsigned Profibus slot
REAL DINT Truncates fractional part toward zero Use TRUNC for explicit semantics; ROUND for nearest
REAL INT Truncates; may overflow if out of range Route through DINT instead to detect overflow
BYTE INT 0..255 zero-extended to 16 bits Useful for parsing single hex character nibbles
WORD INT Bit pattern preserved when bit 15 = 0; negative when bit 15 = 1 The exact conversion that triggered the original bug
DWORD REAL Bit-cast reinterpretation of IEEE 754 Use only for actual float bit patterns
BOOL BYTE 0 -> 16#00, 1 -> 16#01 For byte-packed boolean arrays on Profibus

Reference: CONV (Convert value) instruction — SIMATIC S7-1200 manual collection.

Implicit vs explicit conversion. A bare MOVE block performs an implicit conversion. The CONV block performs an explicit conversion that the compiler validates. Always prefer CONV for cross-width or cross-signedness transfers, even when both blocks produce the same bits at runtime.

The HTA and ATH Instructions for Hex String I/O

When the Profibus DP slave accepts or returns hex characters through a STRING port (common on Rexroth IndraDrive parameter channels and on third-party SCADA bridges), the HTA and ATH extended instructions convert between ASCII hex strings and numeric values.

  • HTA (Hexadecimal to ASCII): Reads a numeric input (BYTE, WORD, DWORD) and writes a STRING where each nibble is represented by a hex character ('0'..'9', 'A'..'F'). For example, input DWORD 16#0004FFF6 with N = 5 emits the string "4FFF6".
  • ATH (ASCII to Hexadecimal): Reads an input STRING of hex characters and writes the numeric value to a WORD or DWORD. For example, input STRING '4FFF6' with N = 5 writes DWORD 16#0004FFF6.

The N input pin defines how many hex digits (1..8) are processed. For a 16-bit Profibus parameter (4 hex digits), set N = 4. For the 20-bit value 0x04FFF6, set N = 5 and route through a DWORD. For a full 32-bit hex payload, set N = 8.

Reference: ATH and HTA — SIMATIC S7-1200 manual collection.

STRING length sizing. Declare the output STRING with at least N + 1 characters. A STRING[4] cannot hold "4FFF6"; declare STRING[6] or larger. The +1 covers the implicit length byte managed by the STRING type.

Applying the Rexroth HACD-2 Scaling Formula

The communication formula supplied by Rexroth for the HACD-2 parameter channel is:

(desired_value - offset) * scale = raw_value

Worked example with desired_value = 1000, offset = 0, scale = 327.67:

(1000 - 0) * 327.67 = 327670
327670 decimal = 0x0004FFF6

The raw value 327670 is the bit pattern that the drive interprets as engineering value 1000. Writing 327670 directly into a 16-bit INT tag causes overflow (327670 > 32767); the high bits are clipped and the drive sees garbage. Writing 0x0004FFF6 into a 32-bit DWORD tag is the correct approach because the bit pattern matches what the drive expects on the wire. Both are equivalent in terms of the bytes transmitted; only the storage type differs.

The reverse conversion, performed inside the drive, divides the raw value by scale and adds the offset to recover the engineering value: 327670 / 327.67 = 1000. If the scale factor and offset are not symmetric between the PLC and the drive, the value at the drive will not match the value at the HMI. Confirm both ends of the formula against the parameter manual before commissioning.

Step-by-Step: Hex Conversion in TIA Portal for an S7-1200 to Profibus DP Slave

Prerequisites

  • TIA Portal V15.1 or later (V18 or V19 recommended for full S7-1200 firmware 4.5+ support).
  • S7-1200 CPU firmware V4.2 or higher (V4.4 or higher recommended for full HTA/ATH reliability on long STRING operands).
  • Bosch Rexroth HACD-2 GSD file installed in the TIA Portal device catalog under "Other field devices → Profibus DP → Drives".
  • CM 1243-5 Profibus DP master module (6GK7243-5DX30-0XE0) or a CPU 1214C / 1215C / 1217C with the integrated DP master port.
  • IEC check enabled on every OB / FB / FC.
  • Rexroth IndraWorks commissioning tool with parameter-channel access to the HACD-2.

Step 1 — Declare the Working Tags

In the PLC tag table or in the static section of the FB, declare the following tags. Using a dedicated FB (for example FB1200 "HACD2_Scale") isolates the conversion logic from the rest of the program and makes IEC check errors easier to diagnose.

VAR
    rSetpoint     : REAL    := 0.0;     // HMI input, e.g. 1000.0
    rOffset       : REAL    := 0.0;     // Engineering offset
    rScale        : REAL    := 327.67;  // Raw-units per engineering-unit
    rScaled       : REAL    := 0.0;     // (rSetpoint - rOffset) * rScale
    diScaled      : DINT    := 0;       // Truncated integer, e.g. 327670
    dwHexPayload  : DWORD   := 16#0;    // Bit pattern to Profibus slot
    wLowWord      : WORD    := 16#0;    // Low 16 bits of dwHexPayload
    wHighWord     : WORD    := 16#0;    // High 16 bits if 32-bit slot
    sHexDisplay   : STRING[6];          // '4FFF6' for HMI diagnostics
    bOverflow     : BOOL    := FALSE;   // Set when diScaled > 65535
END_VAR

Step 2 — Compute in REAL to Preserve Resolution

In the FB body, written in SCL, perform the scaling and the conversion. Use REAL arithmetic for the multiplication to avoid integer rounding during the scale step; only convert to integer at the end.

// Section 1 - Scaling
"rScaled" := ("rSetpoint" - "rOffset") * "rScale";

// Section 2 - Truncate to DINT (round toward zero, IEC 61131-3 standard)
"diScaled" := REAL_TO_DINT("rScaled");

// Section 3 - Overflow guard for 16-bit slots
IF ("diScaled" > 65535) OR ("diScaled" < 0) THEN
    "bOverflow" := TRUE;
ELSE
    "bOverflow" := FALSE;
END_IF;

// Section 4 - Convert to unsigned bit pattern
"dwHexPayload" := DINT_TO_DWORD("diScaled");

// Section 5 - Slice into 16-bit words (Profibus DP slots)
"wLowWord"  := DWORD_TO_WORD("dwHexPayload");
"wHighWord" := DWORD_TO_WORD(SHR(IN := "dwHexPayload", N := 16));

The REAL intermediate ensures floating-point precision is preserved through the scaling (REAL on the S7-1200 has approximately 7 decimal digits of precision, sufficient for the 327.67 example). Converting directly from REAL to INT or WORD can lose precision due to rounding direction; routing through DINT first matches the IEC 61131-3 standard conversion semantics. The SHR (Shift Right) call extracts the upper 16 bits when the slave expects a 32-bit parameter spread across two 16-bit slots.

Step 3 — Map the Payload to the Profibus DP Process Image

In the device configuration, open the HACD-2 slot for the parameter channel. Right-click the output word slot and assign "wLowWord". If the parameter is defined as 16 bits in the GSD, the upper 4 bits of "dwHexPayload" are discarded; if the slave expects 32 bits, assign a DWORD slot with "dwHexPayload" instead, or assign "wLowWord" to the first slot and "wHighWord" to the second slot. Compile and download the hardware configuration.

Step 4 — Add an HTA Block for HMI Diagnostics

Drop an HTA instance on the same FB and wire it to the hex display string. This step is optional but extremely useful during commissioning.

// HTA block call
"HTA_DB"(
    EN  := TRUE,
    IN  := "dwHexPayload",
    N   := 5,                  // 5 hex digits for 0x4FFF6
    OUT => "sHexDisplay"
);

The HMI can now display the actual bit pattern being transmitted. If the drive shows 1000 but the HMI shows '4FFF6', the wiring is correct. If the HMI shows '7FFE' while the drive shows -1, the sign-flip bug has reappeared somewhere.

Step 5 — Verify with the Drive Parameter Monitor

Place the drive in its parameter monitor mode (typically P-0-0085 on the HACD-2, accessed via IndraWorks). The drive should report the engineering value of 1000.0, not the raw 327670. The Profibus DP diagnostic buffer should show no "Slave not ready" or "Invalid parameter" entries.

Verification Checklist

Item Expected Result Pass Criteria
TIA Portal compile No warnings Zero errors and zero warnings with IEC check on
Online watch — "diScaled" 327670 for setpoint 1000 Decimal value matches the formula
Online watch — "dwHexPayload" 16#0004FFF6 Hex literal matches the expected bit pattern
Online watch — "wLowWord" 16#4FFF6 Low 16 bits only
Online watch — "wHighWord" 16#0000 Upper 16 bits zero for a 20-bit value
Drive parameter monitor Engineering value 1000 Matches the HMI input
HMI hex display '4FFF6' 5-character string with uppercase hex
Profibus DP diagnostic buffer No fault entries Clean buffer, slave in "Data Exchange" state
Profibus DP trace tool Bytes F6 FF 04 00 on the wire (LE) Matches the configured byte order
Overflow flag FALSE for setpoint 1000 Only TRUE if scaled value exceeds 16-bit range

Profibus DP Byte Order and Endianness

If the HACD-2 GSD defines a 32-bit parameter slot starting at byte offset 4, the S7-1200 transmits the DWORD "dwHexPayload" = 16#0004FFF6 in little-endian order (low byte first). The bytes on the wire are:

Byte Offset Byte Value (Hex) Binary
4 (low byte) F6 11110110
5 FF 11111111
6 04 00000100
7 (high byte) 00 00000000

If the drive expects big-endian (high byte first), use the SWAP_DWORD block or assemble manually with POKE_BLK. The Rexroth IndraDrive default is little-endian for Profibus DP process data, but parameter channels and serial-over-Profibus bridges may differ. Always consult the drive parameter manual for the exact mapping. A quick field check: write 16#12345678 to the slot, then read back the raw bytes from a Profibus DP trace. If the bytes appear as 78 56 34 12, the bus is little-endian; if they appear as 12 34 56 78, the bus is big-endian and a SWAP is required.

Common Pitfalls and Field Notes

  1. Implicit signedness flip. TIA Portal does not warn when moving a WORD to an INT. Always inspect the "Type" column in the tag table and the block interface. The fix is either to widen the variable to DINT/DWORD or to use CONV with the explicit same-signedness target.
  2. CONV rounding direction. CONV from REAL to INT truncates toward zero. For round-to-nearest, use ROUND before CONV. For round-toward-positive-infinity, use CEIL. For round-toward-negative-infinity, use FLOOR.
  3. ATH and HTA require declared STRING length. A STRING[4] cannot hold "4FFF6"; declare STRING[6] or larger. The +1 byte is for the implicit length byte managed by the STRING type.
  4. Profibus DP cycle time. If the parameter is in a high-priority slot, every PLC scan recomputes and transmits. For non-critical setpoints, place the write in a slower cyclic OB such as OB35 at 100 ms, or in OB1 guarded by a clock-bit pulse.
  5. HACD-2 scaling formula uses (desired − offset) * scale. If offset is non-zero, subtract it before multiplying. Using unsigned arithmetic on the scaled value can introduce a sign error when the scaled result crosses 32767.
  6. S7-1200 firmware version. Some older firmware versions (V4.0 and below) do not support all extended string instructions or have reduced STRING handling performance. Verify firmware ≥ V4.2 on the device identification page before relying on HTA/ATH for production code.
  7. GSD slot consistency. If you change the parameter slot length in the GSD (e.g. 16 → 32 bits), the entire slot map shifts. Recompile the hardware configuration and re-check adjacent parameters for offset errors.
  8. IEC check interacts with multi-instance DBs. If a multi-instance FB declares parameters with mixed signedness (for example, an INT input feeding a WORD output via a multi-instance call), IEC check flags it. Resolve by changing the parameter type or by inserting an explicit CONV.
  9. Watchdog reset on Profibus DP failure. If the slave drops out of "Data Exchange", the input process image freezes at the last value. Add an OB82 / OB86 error handler to detect the dropout and write a safe default (typically 0) to the drive slot.
  10. HTA output case. The HTA block emits uppercase hex characters by default. If your HMI expects lowercase, post-process the STRING or use the lower-case variant attribute if available in your firmware version.

Troubleshooting Matrix

Symptom Likely Cause Corrective Action
Drive shows mirrored sign value (e.g. -10 instead of 65526) WORD → INT MOVE without CONV Change both sides to the same signedness or route via DWORD
Drive shows 0 or 32767 for every setpoint INT overflow during scaling Route through DINT or scale the input down
HMI shows correct decimal but drive shows wrong engineering value Profibus DP byte-order assumption wrong Swap bytes with the SWAP_DWORD block or with POKE_BLK
HTA output shows fewer digits than expected N pin set too low Set N to match the bit width (4 for 16-bit, 8 for 32-bit)
Compile warning "Conversion from REAL to INT loses precision" Direct REAL → INT without TRUNC Insert TRUNC or ROUND before CONV
Drive accepts hex literal but rejects scaled result Drive expects fixed-point Q-format Multiply by 32767 (Q15) instead of the generic scale
Profibus DP slave drops to "Not Ready" after write Invalid parameter length or address Verify slot length against the GSD file
HMI displays lowercase hex '4fff6' instead of '4FFF6' ATH/HTA output not uppercased Verify the HTA block is set to emit uppercase hex
ATH returns 0 even though input STRING is correct N pin set higher than the STRING length Set N ≤ LEN(input STRING)
Drive shows engineering value but PLC shows wrong raw value Scale factor mismatch between PLC and drive Verify scale and offset on both ends against the parameter manual
Compile error "Type mismatch in MOVE block" after enabling IEC check Implicit WORD ↔ INT conversion Insert explicit CONV block or change types to match
Drive value oscillates between two values Two OBs writing the same Profibus slot Identify the duplicate write and remove it
HMI hex display is empty STRING length too small for the HTA output Increase STRING length to N + 1 or larger

Commissioning Tools and Wire-Level Verification

For proof beyond online watch tables, capture the actual bytes on the Profibus DP wire and compare them against the expected hex pattern. The following tools are commonly used:

  • Siemens PROFINET / Profibus analyzer: Integrated into TIA Portal under "Online → Diagnostics → Profibus DP Trace". Captures a configurable number of cycles and decodes each slot.
  • Softing PROFIusb: External USB Profibus DP analyzer with a Windows trace tool. Captures raw bytes per slot per cycle. Useful for verifying byte order.
  • Siemens SIMATIC Automation Tool: Reads the S7-1200 process image from the PLC side and compares against expected values without needing an online connection to TIA Portal.
  • Rexroth IndraWorks: The drive-side commissioning tool. Read parameter P-0-0085 to confirm the engineering value, and read the parameter channel echo to confirm the raw value the drive received.

A typical commissioning flow: (1) set the HMI setpoint to 0 and verify the wire bytes are zero; (2) set the HMI setpoint to mid-scale (for example 500) and verify the wire bytes match 16#00027F...; (3) set the HMI setpoint to full-scale and verify the wire bytes match the maximum raw value; (4) read the engineering value from the drive parameter monitor and confirm it matches the HMI setpoint at all three points.

Safety and Pre-Commissioning Checklist

  • Always run a Profibus DP diagnostic buffer check (Online → Diagnostics → Profibus DP) before energizing the drive.
  • For initial commissioning, set the drive to "parameter write disabled" and verify read-only echoes first. This prevents the drive from acting on a corrupt value during debug.
  • Use a Profibus DP trace tool to capture the wire bytes and compare against the expected hex pattern.
  • Keep IEC check enabled in all blocks; this prevents the WORD/INT mismatch described in the original problem.
  • Validate the HMI scaling against the drive's parameter monitor at zero, mid-scale, and full-scale setpoints to catch non-linearities.
  • Wire an OB82 / OB86 error handler so the PLC defaults the output slot to a safe value when the slave drops out of "Data Exchange".
  • Document the scale factor, offset, and bit-width for every parameter in a parameter sheet. The HACD-2 manual typically provides the formula; record the matching PLC-side formula in the same sheet.
  • Lock the firmware version of the S7-1200 in the project to prevent an automatic firmware update from changing the CONV or HTA behaviour.

FAQ

Why does my Profibus DP slave show the wrong value when I write a decimal number directly?

The slave interprets the bit pattern of the value, not its decimal representation. A 16-bit signed INT value such as 0xFFF6 is 65526 decimal as a WORD but -10 as a signed INT. Either route through a DWORD to keep the bit pattern intact, or convert with CONV to the same signedness as the slave expects. Always check the slave's GSD file for the expected data width and signedness.

What is the difference between the CONV instruction and the HTA / ATH instructions?

CONV converts between numeric data types (for example, INT → DINT or REAL → DWORD). HTA and ATH convert between numeric values and ASCII hex character strings (for example, DWORD 16#4FFF6 ↔ STRING '4FFF6'). Use CONV for bit-pattern-level Profibus DP writes; use HTA / ATH for HMI displays or for serial bridges that accept hex strings.

How do I convert 327670 decimal to hexadecimal in TIA Portal?

Store the value as a DINT, then convert to DWORD using DINT_TO_DWORD, then watch the tag online in hex display mode — it will show 16#0004FFF6. Use the CONV instruction block if you need to write the result to another tag, or the HTA instruction with N = 5 if you need a STRING output for the HMI.

What does enabling IEC check actually do in TIA Portal?

IEC check enforces strict type compatibility on block parameter assignments. With IEC check on, the compiler rejects implicit conversions between signed and unsigned types of the same width (for example, INT ↔ WORD), between types of different widths (for example, BYTE → INT without explicit CONV), and between bit-string and numeric types. This is the single most effective setting for preventing the WORD-to-INT sign-flip bug.

Which S7-1200 firmware version supports HTA and ATH reliably?

HTA and ATH are available from firmware V4.0 of the S7-1200 CPU, but full reliability on long STRING operands is best on firmware V4.2 or higher. Check the device identification in TIA Portal (Online → Accessible devices) and update the firmware if necessary before relying on these extended string instructions for production code.

Can I use the same approach on an S7-1500 or ET 200SP CPU?

Yes. The CONV, HTA, and ATH instructions are present in the S7-1500 basic and extended instruction sets with identical semantics. On the S7-1500 you also have access to LREAL (64-bit floating point) and the additional conversion blocks in the "Conversion operations" folder of the TIA Portal instruction tree. The IEC check behaviour is the same.

Back to blog