Overview
The Siemens SIMOTION D425 is a high-performance motion controller from the SIMOTION D family, designed for complex multi-axis applications in packaging, printing, textile, and converting machinery. Programming is performed in SCOUT (or SCOUT TIA) using Structured Text (ST) per IEC 61131-3. A recurring engineering task when interfacing SIMOTION with WinCC Flexible / TIA Portal HMI panels is the conversion of array elements to individually addressable scalar tags, so each element can be logged, trended, or displayed as a discrete HMI field.
This reference covers three canonical conversion patterns observed in field engineering:
- Decomposing a
WORDarray into individually named scalar variables (word1,word2, …) for direct tag binding. - Converting a
DINTarray (di_selected_RecipeCount[0..10]) toWORDelements using the IEC standardDINT_TO_WORDconversion operator for HMI logging. - Stringifying an array of strings into a single delimited string for archive export or barcode generation.
For controller specifications, refer to the SIMOTION D4xx Operating Instructions on Siemens Industry Online Support.
Prerequisites
| Component | Specification | Notes |
|---|---|---|
| Controller | SIMOTION D425 (6AU1425-* variants) | CX32-2 / I/O expansion supported |
| Firmware | SIMOTION V4.4 SPx or V5.x | DINT_TO_WORD intrinsic available in all versions |
| Engineering | SCOUT V5.x / SCOUT TIA | ST editor with IEC 61131-3 conformance |
| HMI | WinCC Flexible 2008 SP5 or TIA Portal WinCC | Tag logging requires scalar tags or array-tag element access |
| Compiler | MCC / DCC chart or ST source file | Enable Optimized data access for performance |
Data Type Specifications
SIMOTION ST follows IEC 61131-3 type semantics. The relevant elementary types for this conversion are:
| Type | Width (bits) | Range | Typical use |
|---|---|---|---|
DINT |
32 | −231 … +231−1 | Counters, recipe indices, scaled process values |
INT |
16 | −32 768 … +32 767 | HMI-friendly integer values |
WORD |
16 | 0 … 65 535 (unsigned) | Bit masks, raw I/O, archive logging tags |
BOOL |
1 | 0 / 1 | Individual bits within WORD via %X notation |
Because DINT can hold negative values and magnitudes up to ±2.1×109, a direct narrowing conversion to WORD requires the engineer to guarantee that the source values are within the unsigned 16-bit range. Otherwise the conversion is undefined per IEC 61131-3 and the runtime will produce the implementation-defined result (on SIMOTION, the low-order 16 bits are retained; negative values wrap to 0…65 535 modulo arithmetic).
DINT_TO_WORD, clamp the source via LIMIT(0, value, 65535) or branch on sign using an IF construct. This prevents the HMI archive from recording garbage on overflow events such as recipe index reset to 0.Conversion Architecture
Three architectural patterns are used in production code. Selection depends on whether the HMI requires discrete tags (e.g. for Tag Logging with absolute tag references) or can consume an entire array via index variables.
| Pattern | Memory Cost | CPU Cost | Best For |
|---|---|---|---|
Scalar explosion (word1..word10) |
10 × 16 bit + 10 names | 10 assignments per cycle | Legacy WinCC Flexible with discrete tag binding |
| Indexed array | 1 × (n × 16 bit) | 1 indexed read per access | Modern TIA Portal with array tags + index |
| DUT / UDT with member tags | 1 × (n × 16 bit) + type | 1 indexed read per access | Recipe data, structured parameters |
Step-by-Step: Pattern A — Scalar Explosion for Legacy HMI
When WinCC Flexible cannot consume an array tag, explode the array into individually addressable WORD variables in the controller's global data block.
- Declare the source array and the scalar target tags in the unit's
VAR_GLOBALsection. - Implement a cyclic ST program (in a MCC or LAD/FBD chart's ST subprogram) that copies element by element.
- Re-run the program on every cycle so the HMI always reads a consistent image.
INTERFACE
VAR_GLOBAL
(* Source DINT array, e.g. recipe count values 0..10 *)
di_selected_RecipeCount : ARRAY[0..10] OF DINT;
(* Exploded WORD targets for HMI logging *)
wordarray : ARRAY[0..10] OF WORD;
END_VAR
END_INTERFACE
IMPLEMENTATION
PROGRAM explodeArrayToWord
VAR
i : DINT;
END_VAR
FOR i := 0 TO 10 DO
wordarray[i] := DINT_TO_WORD(LIMIT(0, di_selected_RecipeCount[i], 65535));
END_FOR;
END_PROGRAM
END_IMPLEMENTATION
Step-by-Step: Pattern B — Single-Word Indexing
When the downstream consumer only needs one element at a time (typical for a HMI recipe view that scrolls through entries), expose a single 16-bit output and an index.
PROGRAM getWordByIndex
VAR_INPUT
iIndex : DINT; (* 0..10 *)
END_VAR
VAR_OUTPUT
wValue : WORD;
bError : BOOL;
END_VAR
IF (iIndex >= 0) AND (iIndex <= 10) THEN
wValue := DINT_TO_WORD(LIMIT(0, di_selected_RecipeCount[iIndex], 65535));
bError := FALSE;
ELSE
wValue := 0;
bError := TRUE;
END_IF;
END_PROGRAM
Bind wValue and iIndex as HMI tags. Drive iIndex from a HMI slider or UpDown control. The runtime index check guarantees that operator mis-entry (e.g. iIndex = 11) returns a clean zero and a diagnostic bError bit, instead of an out-of-bounds access that would trigger an IO-ACCESS-ERROR on the controller.
Step-by-Step: Pattern C — Array-to-Single-String Aggregation
For barcode or CSV archive export, an array of strings must be flattened into one delimited string. SIMOTION ST has no built-in join function, so a manual CONCAT loop is required.
FUNCTION_BLOCK StringJoiner
VAR_INPUT
arrStrings : ARRAY[0..9] OF STRING[20];
cSeparator : CHAR; (* typically ',' or ';' *)
END_VAR
VAR_OUTPUT
sResult : STRING[255];
END_VAR
VAR
i : DINT;
END_VAR
sResult := '';
FOR i := 0 TO 9 DO
IF (i > 0) THEN
sResult := CONCAT(sResult, STRING(cSeparator));
END_IF;
(* Trim trailing zero-length entries *)
IF (LEN(arrStrings[i]) > 0) THEN
sResult := CONCAT(sResult, arrStrings[i]);
END_IF;
END_FOR;
END_FUNCTION_BLOCK
The same pattern can be applied to a WORD array by first calling WORD_TO_STRING on each element, then concatenating with a delimiter. For JavaScript / TypeScript based HMIs (Web Navigator), the Array.from() static method provides an equivalent one-liner: Array.from({length:10}, (_,i) => arr[i]).join(',').
Data Logging with Converted Values
WinCC Flexible Tag Logging requires either scalar tags or array-tag-with-index. The exploded wordarray[0..10] from Pattern A can be bound directly:
- In the HMI project, open Connections > Tags and create tags
wordarray_0throughwordarray_10, each pointing to the corresponding array element via the controller's area pointer (e.g.DB.wordarray[i]in SIMOTION, the array is exposed as a contiguous block). - Configure a Data Log with one column per tag. Set the acquisition cycle to match the controller's IPO or servo task (typically 1–4 ms for fast process, 100–1000 ms for trends).
- Enable Logging method = Circular log with a segment size of 50 000 records to prevent SD card wear on the HMI panel.
For Pattern B, the single tag wValue is logged continuously while the HMI increments iIndex synchronously, producing one row per element per cycle — suitable for snapshot debugging but not for high-speed trend logging.
Verification Procedures
-
Offline syntax check in SCOUT: Project > Compile > Check Consistency. Compiler error 1200-2E08 typically indicates an out-of-range array bound; error 1200-2E15 indicates a missing
END_TYPE/END_VAR. -
Online watch table: open the unit's instance DB in Watch table mode and verify that
wordarray[i]updates asdi_selected_RecipeCount[i]changes (use Force on the DINT source to inject test values 0, 1, 100, 32768, 65535, 65536, −1). -
Range test: feed value 65 536 (one above WORD max). Expected:
wordarray[i] = 0per low-bit truncation ifLIMITis bypassed; ifLIMITis in place,wordarray[i] = 65535and the HMI archive shows the clamped ceiling. -
HMI tag test: in WinCC Flexible Tags, force each
wordarray_Ntag to a known value and verify it appears in the live trend. If the tag shows??, the HMI connection is misconfigured (check the area pointer and the PLC–HMI connection name in PG/PC interface). -
Archive round-trip: trigger a recipe change, export the resulting CSV from the data log, and confirm that column count equals
wordarraylength and that all values are within 0…65 535.
Troubleshooting Matrix
| Symptom | Likely Cause | Diagnostic | Resolution |
|---|---|---|---|
| HMI shows 0 for all elements | Array bound mismatch (DINT 1..10 vs HMI 0..9) | Watch table: confirm wordarray[0] is non-zero when di_selected_RecipeCount[0] is non-zero |
Unify index base; re-declare array as ARRAY[0..10] in both controller and HMI |
| Compiler error "Type mismatch WORD <- DINT" | Direct assignment without conversion operator | Check ST source for naked word := dint;
|
Insert DINT_TO_WORD(...) with LIMIT guard |
| IO-ACCESS-ERROR in diagnostic buffer | Index out of bounds on indexed access | Diagnostic buffer entry "Area length violation on ArrayIndex" | Wrap access in IF (i >= lo) AND (i <= hi) THEN guard |
| Logging stops after 50 000 records | Circular log full, no segment rollover | Check Segments > Number setting on the data log | Increase to 30 segments of 50 000 records (≈ 1.5 M rows) or extend via the Sequential log option |
| Garbage values in archive | DINT negative values truncated to WORD | Watch di_selected_RecipeCount[i] for negative entries |
Clamp with LIMIT(0, ...) or pre-filter with IF value >= 0 THEN
|
Array element wordarray[10] undefined |
Array declared 0..9 but accessed at index 10 |
Cross-check all FOR i := a TO b bounds |
Match LO/HI limits of ARRAY[lo..hi] with loop indices |
Performance Considerations
On a SIMOTION D425 with the default servo task at 1 ms, an n = 11 element loop with LIMIT + DINT_TO_WORD executes in < 0.5 µs per element (D425 measured at ≈ 0.04 µs / assignment in benchmark mode). The exploded-array pattern therefore has negligible impact on the deterministic cycle. Avoid the pattern for arrays larger than 1 000 elements; for those, expose the array tag directly to the HMI and let the HMI index the log column.
For arrays of REAL / LREAL values, prefer REAL_TO_WORD only when the value is guaranteed to lie in the integer range 0…65 535. For floating-point trend logging, bind the REAL tag directly and use the HMI's Decimal places attribute to control display precision.
Related Functions in the SIMOTION Standard Library
-
DINT_TO_WORD(value)— narrowing conversion, retains low 16 bits. -
LIMIT(MN, IN, MX)— clampsINto the range[MN, MX]; pair withDINT_TO_WORDto enforce range discipline. -
WORD_TO_INT(value)— widening sign-extension; useful when the HMI tag isINTand the source isWORD. -
CONCAT(s1, s2)— string concatenation for Pattern C; both operands areSTRING, theCHARmust be cast viaSTRING()first. -
LEN(str)— returns the actual length of aSTRINGvariable, used to skip empty array entries during join.
FAQ
Why does my HMI show 0 for every array element even though the controller's watch table shows the correct values?
This is almost always an index-base mismatch. The controller declares ARRAY[1..10] while the HMI imports the tag as a 0-based array and reads element 0, which does not exist (or contains the controller's element 1 mapped to a different memory offset). Re-export the controller as the HMI's data source so the array bounds are identical on both sides, or change both to ARRAY[0..9] explicitly.
Is DINT_TO_WORD safe for negative numbers?
No. The IEC 61131-3 standard defines narrowing conversions as implementation-defined when the source value is out of range. On SIMOTION the low 16 bits are preserved, so −1 becomes 65535 (two's complement low bits). Always wrap with LIMIT(0, value, 65535) or branch on sign before conversion if negative values are possible.
Can I bind a DINT array directly to WinCC Flexible Tag Logging without conversion?
Yes, if the HMI supports array tags with index (TIA Portal WinCC does natively; WinCC Flexible 2008 requires the array to be declared as a structure or as discrete tags). For high-frequency logging, expose individual WORD elements as discrete HMI tags to avoid the runtime overhead of repeated indexed reads on the HMI side.
What is the maximum array size SIMOTION D425 supports in ST?
The IEC 61131-3 theoretical limit is 231−1 elements, but practical limits are governed by the controller's work memory (typically 32 MB on D425). A WORD array of 1 000 000 elements uses 2 MB; a REAL array of the same length uses 4 MB. Always size below 50 % of available work memory to leave headroom for cyclic buffers and trace recordings.
How do I convert a WORD array to a CSV string for SD-card export?
Use a FOR loop that calls WORD_TO_STRING on each element, then CONCAT with a ',' separator, and finally write the resulting STRING to a file via the FileLib standard library (fopen, fwrite, fclose on the controller's CFast card). The string-cap of the export buffer is governed by the STRING declaration length; allocate 4× the element count to allow for separator overhead.