Configuring CopyStrIntoArray FB in TIA Portal for S7-1200 and S7-1500
This reference documents the correct deployment of the CopyStrIntoArray function block (FB) inside TIA Portal V15.1 through V18, targeting S7-1200 (firmware V4.2 and higher) and S7-1500 (firmware V1.8 and higher) controllers. The block copies the character payload of a STRING tag into a typed ARRAY buffer and is typically used when downstream code (peer-to-peer telegrams, ASCII protocol stacks, code-page conversion, label printing) needs character-by-character index access rather than the opaque STRING container the Siemens runtime normally provides.
The single most common deployment failure is a data-type mismatch on the FieldRead / FieldWrite instruction pair inside the block. The block body operates on CHAR elements, but users routinely wire Byte arrays. The PLC compiles fine, the call returns no error code, and the buffer fills with garbage. The procedures below eliminate that failure mode and cover the surrounding pitfalls (length handling, padding, non-printable characters, multi-byte code pages).
1. Function Block Interface and Semantics
The published CopyStrIntoArray FB exposes the following formal interface. Pin names vary by library version; the table below maps the standard convention used in the community FB circulating as CopyStrIntoArray in the Siemens global library exchange.
| I/O | Name | Type | Description |
|---|---|---|---|
| Input | enable |
BOOL |
Rising edge triggers one copy operation. Level-triggered usage is permitted but causes continuous re-execution on every OB1 scan. |
| Input | sourceString |
STRING[254] |
Source string. Max 254 payload bytes plus the implicit 2-byte length header. |
| Input | startIndex |
INT |
Zero-based position inside sourceString where copying begins. Default 0. |
| Input | endIndex |
INT |
Zero-based last index (inclusive) to copy. The block copies endIndex - startIndex + 1 elements. |
| Output | done |
BOOL |
Set for one OB1 cycle when the copy completes without bounds error. |
| Output | error |
BOOL |
Latched error flag. Reset on next rising edge of enable. |
| Output | status |
WORD |
Diagnostic word. See error code table below. |
| InOut | targetArray |
ARRAY[*] of CHAR |
Destination buffer. Variably sized using the * syntax (TIA V14+). |
ARRAY[..] OF CHAR, not ARRAY[..] OF BYTE. The block performs implicit character conversion only when the formal parameter is CHAR. A BYTE array will compile, accept the wiring, but produce a compiler warning (Type mismatch in FB call suppressed by some users) and return indeterminate content.2. Prerequisites
- Installed TIA Portal V15.1 or later. Earlier versions (V13, V14) lack the
ARRAY[*]variable-length formal parameter introduced in V14 SP1. - CPU firmware compatible with the formal parameter type used:
- S7-1200: firmware V4.2 or later (S7-1200 CPU firmware update V4.2 to V4.6 for full
ARRAY[*]support). - S7-1500: firmware V1.8 or later (S7-1500 CPU firmware update V1.8 to V2.9).
- S7-1200: firmware V4.2 or later (S7-1200 CPU firmware update V4.2 to V4.6 for full
- Global library containing the
CopyStrIntoArrayFB. Obtain the.zipfrom your internal library server or Siemens Application Examples catalog. Verify the SHA-256 checksum before import. - An instance DB for the FB call. TIA Portal generates this automatically when the FB is dragged onto a network.
- A
STRINGtag populated from an upstream process (HMI tag, receive buffer, recipe DB). - A target
ARRAYdeclared in a global DB or as a static tag of the calling FB.
3. Library Import and Master Copy Setup
- Open TIA Portal and load the project. In the Project tree, right-click the CPU and choose Open the global library.
- Select Libraries → Open global library → Browse and navigate to the supplied
.zipfile. - Drag the
CopyStrIntoArrayfolder from the library pane into the Program blocks node of the CPU. TIA Portal creates a Master Copy of the FB. - Compile the Program blocks folder. The Master Copy is now stored in the project. Updates to the source library require manual propagation.
4. Step-by-Step Configuration of the Call
4.1 Declare the Target ARRAY
Create a global DB (for example Data_Dest) and add a tag named CharBuffer:
CharBuffer : ARRAY[0..53] OF CHAR; // 54-character destination buffer
The dimension 0..53 matches the original example discussed in the field (54 characters). If you use a different size, update the endIndex accordingly.
4.2 Declare the Source STRING
In the same DB (or in the calling FB's Input section) add:
SourceStr : STRING[80];
Length is the maximum payload plus 1 (the trailing null is implicit). STRING[80] holds up to 80 characters.
4.3 Wire the Call
- Open the OB or FB where the copy should occur (typically OB1 for testing, a cyclic interrupt OB for production).
- From Program blocks → Master Copies, drag
CopyStrIntoArrayonto a network. TIA Portal creates an instance DB namedCopyStrIntoArray_DB. - Connect the inputs and outputs:
-
enable→ tag or boolean condition (for example,"Trigger".bCopy). -
sourceString→"Data_Dest".SourceStr. -
startIndex→0(constant INT). -
endIndex→53(constant INT). For dynamic length, readLEN(SourceStr) - 1from the standard function and pass it. -
targetArray→"Data_Dest".CharBuffer.
-
- Compile the block. TIA Portal performs type checking; any
Byte/Charmismatch is now flagged with error0706 "Type mismatch in the FB call".
4.4 Verify the FB Body
Open the Master Copy of the FB and inspect Network 3. The original implementation contains two instructions:
-
%FieldReadblock reading from the sourceSTRING. -
%FieldWriteblock writing to the destinationARRAY OF CHAR.
Both must be configured with the formal InOut parameter, not a concrete data block tag. Right-click the FieldRead input labeled Input and select Interconnect to formal parameter → sourceString. Repeat for Output → targetArray.
The index inputs of the FieldRead/FieldWrite must use the same DINT tag that the block exposes internally (commonly named iIndex). Confirm by hovering the connector; the tooltip should show "#iIndex", not a global tag name.
5. Common Error Conditions
| Status (hex) | Meaning | Likely cause | Remediation |
|---|---|---|---|
0000 |
OK, copy complete | — | — |
8001 |
Enable FALSE, no operation |
enable tag is low |
Set trigger; verify logic preconditions. |
8201 |
startIndex < 0 |
Negative constant passed | Validate input; clamp to 0 in calling logic. |
8202 |
endIndex > LEN(sourceString) |
Off-by-one or oversized constant | Use LEN(sourceString) - 1 as upper bound. |
8203 |
endIndex < startIndex |
Index inversion | Swap indices or check upstream logic. |
8204 |
Target array too small | Array dimension smaller than copy count | Resize targetArray or reduce endIndex. |
8205 |
Type mismatch in formal parameter | Target wired as BYTE array |
Change declaration to ARRAY OF CHAR. |
8401 |
NULL pointer access | Symbolic tag unresolved | Recompile; verify that all DBs are loaded on the CPU. |
CopyStrIntoArray found in public libraries. If your instance uses a vendor-supplied version, consult the block's online help (Alt+F1 on the FB in TIA Portal) for the authoritative list.6. Why BYTE Fails and CHAR Works
Siemens' STRING data type stores each character in 8 bits. The numeric representation matches BYTE (0…255), and the two are layout-compatible. The visible difference emerges at the symbolic layer:
-
CHARis interpreted as an ASCII / ISO-8859-1 / UTF-8 code point. The TIA Portal watch table displays it as'A'. -
BYTEis interpreted as a numeric value. The same bit pattern appears as16#41or65.
When the FB body uses FieldRead with a CHAR formal parameter, the compiler inserts a width check (DWORD → CHAR = 1 byte) and emits optimized copy code. When the parameter is BYTE, the same instruction runs, but the symbolic watcher prints the cell as a number. Engineers who read the array in the watch table then see numbers instead of characters and assume the copy failed. In reality, the data is correct; the presentation layer is wrong.
If the downstream consumer requires a BYTE array (for example, a raw TCP send buffer that must be transmitted as bytes), use one of three approaches:
- Declare the
InOutparameter asVARIANTand perform an explicitMOVE_BLKon the underlyingBYTEview. - Use
ATC(Any Type Conversion) functions to copyCHARtoBYTEafter the FB returns. - Convert the destination to
CHARand re-interpret each cell as a byte when assembling the telegram. This is the recommended route for ASCII protocols.
7. Verification Procedure
After deployment, run the following checks before handing the system to commissioning:
-
Online watch: Open the instance DB and the destination DB in a watch table. Force
enable = TRUE. Thedonebit should pulse for one cycle andstatusshould read16#0000. -
Element comparison: In the watch table, expand the
CharBufferarray. Each cell should display the corresponding character ofSourceStr. If the array shows numeric values, the array was declared asBYTE. Fix the declaration and recompile. -
Length check: Confirm that the trailing cells (positions 54+) of the array are untouched. The FB does not clear the buffer; it only overwrites positions
startIndextoendIndex. Pad the buffer with$00or$20before each call if your consumer is sensitive to residual content. -
Edge case — empty string: Set
SourceStr = ''and trigger the FB.statusshould return16#0000and no array element should be modified. Ifstatus = 16#8202, the block's start index handling rejects the empty string. Wrap the call with a guard:IF LEN(SourceStr) > 0 THEN .... -
Edge case — extended characters: Characters above 0x7F (e.g., ü, Ö, ß in ISO-8859-1) are copied as single bytes. If the consumer expects UTF-8, encode before the call. If it expects UTF-16, do not use this FB; use
Character_Set_Convertfrom the Siemens standard library.
8. Alternative Implementations
For projects where importing a third-party FB is undesirable, the same operation can be written in five networks of ladder or three statements of SCL:
8.1 SCL Implementation
// Copy STRING payload to ARRAY OF CHAR
// Source: SourceStr : STRING[80]
// Target: CharBuffer : ARRAY[0..79] OF CHAR
FOR #i := 0 TO MIN(LEN("Data_Dest".SourceStr) - 1, 79) DO
"Data_Dest".CharBuffer[#i] := "Data_Dest".SourceStr[#i+1];
END_FOR;
// Pad remainder with space (0x20) or null (0x00)
FOR #i := MIN(LEN("Data_Dest".SourceStr), 80) TO 79 DO
"Data_Dest".CharBuffer[#i] := ' ';
END_FOR;
STRING access (SourceStr[1] is the first character). When passing to a 0-based ARRAY, the loop counter must offset by 1.8.2 Ladder / FBD Implementation
For users restricted to graphical languages, instantiate the Siemens standard block MOVE_BLK_VARIANT (S7-1500) or BLKMOV (S7-1200) and configure the source as P#DB.SourceStr BYTE 80 and the destination as P#DB.CharBuffer BYTE 80. This treats both regions as raw byte arrays and bypasses the symbolic CHAR/BYTE distinction. The price is loss of symbolic debugging; values appear as bytes in the watch table.
9. Performance and Cycle-Time Considerations
The block uses a software loop. On an S7-1516 (firmware V2.8), a 54-character copy completes in roughly 8–12 µs of OB1 time. The block is suitable for cyclic execution at 10 ms without cycle-time impact. For high-frequency burst use (1 ms OBs, 200+ bytes per call), profile with the TIA Portal Task analysis tool and consider replacing the loop with MoveBlock for a 5–10× speedup.
10. Diagnostic and Commissioning Checklist
| Step | Action | Expected result |
|---|---|---|
| 1 | Compile project after import | No warnings, no errors |
| 2 | Download program and instance DBs | CPU in RUN, no SF LED |
| 3 | Force enable = TRUE with empty string |
status = 16#0000, buffer unchanged |
| 4 | Force SourceStr = 'Hello' and enable = TRUE
|
CharBuffer[0..4] = 'H','e','l','l','o' |
| 5 | Force endIndex = 100 with short string |
status = 16#8202, error = TRUE
|
| 6 | Set endIndex = 53 with 54-char string |
status = 16#0000, all 54 cells populated |
| 7 | Trigger 1,000 times via test OB | Cycle time increase < 1 ms |
11. Frequently Asked Questions
Why does my CHAR array show numeric values like 65 and 72 in the watch table?
The destination array is declared as ARRAY[..] OF BYTE instead of CHAR. TIA Portal displays BYTE cells as unsigned integers. Change the array declaration to CHAR, recompile, and reload; the watch table will then render the cells as ASCII characters.
What is the difference between FieldRead and direct array indexing in SCL?
Both produce identical runtime results. FieldRead / FieldWrite are the graphical-language equivalent of ARRAY[i] in SCL. Use whichever your project style guide mandates. FieldRead is required inside the FB body because the block cannot dereference a VARIANT parameter using array index syntax in LAD or FBD.
Can the block copy more than 254 characters?
No. The formal parameter sourceString in the published library version is typed as STRING[254], the maximum allowed by the S7-1200/1500 runtime. For longer payloads, declare a DB_ANY region and use MOVE_BLK instead.
The block does not run on my S7-1200 with firmware V4.0. Why?
Firmware V4.0 and V4.1 do not fully support the ARRAY[*] variably-sized formal parameter used in the targetArray InOut. Update the CPU to firmware V4.2 or later per the Siemens firmware update portal, or replace the ARRAY[*] formal with a fixed-size ARRAY[0..53] OF CHAR in a local copy of the FB.
How do I clear the buffer before each copy?
The block does not clear residual data. Insert a FILL_BLK call immediately before the CopyStrIntoArray call, set fill pattern to 16#00 for null padding or 16#20 for space padding, and size it to the full array length. This guarantees deterministic content for downstream code that does not handle trailing garbage.