Overview
Tag multiplexing allows an HMI tag to reference a target whose number (for example, the Data Block number) is supplied at runtime from a variable such as a memory word. In Siemens WinCC Flexible and ProTool this is configured declaratively: the DB Constant/Multiplexed and DBD Constant/Multiplexed fields accept either a literal DB number or a pointer to a memory location (MW, DBW) whose value selects the active DB at runtime. The same capability is not exposed as a tag-dialog property in WinCC 7.0 (TIA-era classic) and is unavailable in the standard tag editor of the configuration studio.
The pattern that engineers typically need is the equivalent of DB(MW0).DBD0: a 32-bit REAL or DWORD read from byte offset 0 of the DB whose number is currently held in MW0. The PLC can provide this indirection directly using an ANY pointer; WinCC can also perform the lookup at script level and bind the resulting value to a process tag. This reference documents both paths, the limits imposed by the tag query interface, and the verification procedure for a CPU 315-2 PN/DP (6ES7 315-2EH14-0AB0) running against WinCC V7.0 SP3 Update 2 or later.
Multiplexing Concept in HMI/SCADA Systems
Multiplexing solves a class of problems in which the data set an operator screen must show is not known at configuration time. Typical cases include recipe parameters stored in one DB per recipe, alarm-class definitions split across multiple DBs, batch records indexed by batch number, and per-motor drive parameter sets. In every case, the screen layout is identical; only the source DB changes.
| HMI Platform | Tag Editor Field | Mechanism | Limit |
|---|---|---|---|
| ProTool | DB / DBD Multiplexed | DB number from MW, offset from DBW | DB 0-255, offset 0-65534 |
| WinCC Flexible 2008 SP5 | DB Multiplexed / DBD Multiplexed | Pointer in MW, area+offset in DW | DB 0-32767, offset 0-65534 |
| WinCC V7.0 (Classic) | Not exposed in tag dialog | Indirect via PLC pointer OR C script | Any valid DB number |
| WinCC RT Professional (TIA) | Not exposed in tag dialog | Indirect via PLC pointer OR VB/C script | Archive query: 20 tags / 128 chars each |
Where the dialog field is not exposed, the multiplexing is implemented either on the PLC side (the CPU builds the address and the tag points to the resulting memory) or on the HMI side (a script reads the value and pushes it into a process tag). Both methods are valid; the choice is dictated by the data-flow direction and by which side already owns the indirection logic.
Why Direct Address Multiplexing Is Not Available in WinCC 7.0
The WinCC 7.0 tag configuration dialog binds each tag to a fixed absolute address: a single combination of area, DB number, byte offset, and bit offset. The tag manager hands the address to the channel DLL (typically S7-OS for the MPI/TCP channel) which then issues a fixed read var / write var request to the CPU. The tag object itself is a static C structure created at compile time of the project. The C structure does not contain a slot for an indirect index, and the channel DLL does not parse a token such as DB(MW0).DBD0.
The two recommended indirection layers are:
- PLC-side indirection (preferred for read/write): an S7-300 FB or OB scans a data block, builds a typed copy in a shared mirror DB, and the HMI tag reads from the mirror. The DB number for the active source is held in MW0, exactly as the original requirement asked for.
-
Script-side indirection (preferred for display): a WinCC C or VBScript function reads the index from one process tag, calls
GetTagWordorGetTagFloatfor the resolved tag name, and writes the value into a display tag. The script runs in the picture cycle.
Workaround Architecture: ANY Pointer-Based Indirection
An ANY pointer in S7-300/400 is a 10-byte descriptor that names an area, a count, a transport size, and a byte offset. It is the same structure that the SFCs (SFC20 BLKMOV, SFC84 HALT_IO, etc.) and FBs use to pass variable addresses. The classic structure on an S7-300 is:
| Byte | Field | Value for DBD Source | Notes |
|---|---|---|---|
| 0 | Syntax ID | 16#10 | Always 0x10 on S7-300/400 |
| 1 | Transport size | 16#06 | 0x02=BYTE, 0x04=WORD, 0x06=DWORD |
| 2-3 | Count | 16#0001 | Number of items in transport-size units |
| 4-5 | DB number | MW0 (variable) | 0 for non-DB areas |
| 6-9 | Area + byte offset | 16#84000000 + offset | 0x84=DB, 0x83=DI, 0x82=M, 0x81=I, 0x80=Q |
If MW0 holds the desired DB number and the byte offset inside the source DB is fixed at 0 (matching the DB1.DBD0 example), the indirection is a two-byte patch: write the value of MW0 into bytes 4-5 of a 10-byte ANY that always describes DB area, DBD 0, 1 element. The CPU can be instructed to read through that ANY using SFC20 BLKMOV (any source to any destination) or by writing the value directly to a single double word with explicit load/store of the index.
Implementation 1: STL ANY Pointer Construction in OB1
The following STL block (programmed in the cyclic OB1) maintains a mirror of the active source DBD in a fixed global DB. The active DB number is taken from MW0; the operator can change MW0 from the HMI (it is a configured tag), and the next OB1 pass will copy the new value into MD100.
// OB1 — STL
NETWORK 1 // Build the ANY pointer in DB99
L MW 0 // Active DB number (1..N)
T DBW 2 // Patch bytes 4-5 of the ANY in DB99
NETWORK 2 // BLKMOV from any-DB, DBD0 to MD100
CALL SFC 20
srcblk := DB99.DBX0.0 // 10-byte ANY in DB99
ret_val:= MW10
dstblk := P#M 100.0 DWORD 1
Configure DB99 as a DB of 10 bytes. Initialize the bytes once in DB99 with the following values; the only field the OB rewrites is bytes 4-5.
DB99 (DB-ANY-Handle)
Byte 0 : 16#10 // Syntax ID
Byte 1 : 16#06 // Transport size = DWORD
Byte 2 : 16#01 // Count high = 0
Byte 3 : 16#00 // Count low = 1
Byte 4 : 16#00 // DB number high (overwritten by OB1)
Byte 5 : 16#00 // DB number low (overwritten by OB1)
Byte 6 : 16#84 // Area = DB
Byte 7 : 16#00 // Byte offset high
Byte 8 : 16#00 // Byte offset mid
Byte 9 : 16#00 // Byte offset low
In the WinCC tag editor, configure one process tag that points to DB99.DBD0 is not used here; instead, bind the tag directly to M 100.0 DWORD (the mirror). The HMI never needs to know the active source DB number — it just reads the value that OB1 most recently copied.
Implementation 2: SCL Block with Indirect Access
SCL is the more maintainable option for engineers comfortable with Pascal-like syntax. The block uses the WORD_TO_BLOCK_DB conversion and the ANY pointer that SCL generates for pointer variables.
FUNCTION_BLOCK FB100
VAR_INPUT
i_db_index : WORD; // Active DB number (MW0 from HMI)
i_offset : DWORD; // Byte offset inside the source DB (0 for DBD0)
END_VAR
VAR_OUTPUT
o_value : REAL; // Mirror value exposed to WinCC
o_status : WORD; // 0 = OK, 1 = DB not loaded
END_VAR
VAR_TEMP
t_src_any : ANY;
t_ret : INT;
t_src_db : WORD;
END_VAR
BEGIN
t_src_db := WORD_TO_INT(i_db_index);
// Build ANY pointing at DB[db_index].D[offset]
t_src_any := DW#16#10060000
OR (WORD_TO_DWORD(t_src_db) * DWORD#65536)
OR (DWORD#16#84000000 + i_offset);
o_status := 0;
// BLKMOV 1 DWORD from t_src_any into a temporary DWORD
BLKMOV(SRCBLK := t_src_any,
RET_VAL := t_ret,
DSTBLK := P#DB200.DBX0.0 DWORD 1);
IF t_ret <> 0 THEN
o_status := 1;
o_value := 0.0;
ELSE
o_value := DWORD_TO_REAL(DB200.DBD0);
END_IF;
END_FUNCTION_BLOCK
FB100 is called from OB1 with i_db_index := MW0. The HMI reads DB200.DBD0 for the resolved REAL value and MW20 for the status word. A status of 1 indicates that the requested DB is not loaded in work memory; check SZL ID 0x0132 (list of all DBs) on the CPU to confirm which DB numbers are valid.
Implementation 3: WinCC C Script Multiplexing
When the indirection must be resolved entirely on the HMI side (for example, because the PLC program is owned by a different team and cannot be modified), the C script below runs in the Global Script runtime and pushes the resolved value into a display tag every cycle.
// WinCC C script - global action, 1s trigger
#include "apdefap.h"
void PollMux(void)
{
DWORD dbNo, offNo;
FLOAT result;
char tagName[64];
dbNo = GetTagDWord("PLC_DB_Index"); // bound to MW0
offNo = GetTagDWord("PLC_Offset_Index"); // optional
// Validate range to keep the channel DLL safe
if (dbNo == 0 || dbNo > 32767) return;
_snprintf(tagName, sizeof(tagName),
"PLC_DB%d_DBD%d",
(unsigned int)dbNo,
(unsigned int)offNo);
result = GetTagFloat(tagName);
SetTagFloat("Mux_Display", result);
}
Every combination of dbNo and offNo that the operator can select must have a pre-configured tag named PLC_DB<n>_DBD<m>. The S7 channel DLLs of WinCC V7.0 enumerate the configured tag list when the channel is opened; the script simply looks up the right name. For 50 recipes and 10 parameters this is 500 tags — a small price compared with running a script on the PLC.
WinCC RT Professional Archive Query Limits
If the multiplexing is required for an archive lookup (alarm logs, process value tags) rather than a live tag, the constraints of the archive OLE DB provider apply. Per the TIA Portal documentation for WinCC RT Professional, a single query against the process value archive is restricted to:
- A maximum of 20 tags per query.
- A maximum of 128 characters per tag (this includes the full
ArchiveName::TagNamequalifier).
These limits come from the SQL generation layer that translates OLE DB calls into the underlying MS-SQL queries against the runtime database. They are documented at Querying Process Value Archives (RT Professional). If the multiplexing involves an archive query that resolves to more than 20 tags, the script must split the request into batches of 20 and merge the result sets.
Configuration Parameters and Limits
| Parameter | Value / Range | Source / Constraint |
|---|---|---|
| PLC: Active DB number (MW0) | 1 - 32767 | WinCC channel DLL rejects DB=0 and DB>32767 |
| PLC: Byte offset inside DB | 0 - 65534 | 24-bit pointer in ANY; S7-300 max DB size 64 KB |
| PLC: Transport size | BYTE 0x02 / WORD 0x04 / DWORD 0x06 / REAL (DWORD 0x06) | Defined by S7-300 system software |
| WinCC: Tags per archive query | 20 | Querying Process Value Archives (RT Professional) |
| WinCC: Tag name length in archive query | 128 chars | OLE DB provider SQL buffer |
| WinCC: S7 channel partner resource | 1 - 64 per logical connection | Channel DLL > Connection Parameters > Partner Resource |
| CPU 315-2 PN/DP (6ES7 315-2EH14-0AB0) | Firmware V3.3 or later for SCL indirect DB access | Product manual, section 4.5 |
Verification and Test Procedure
- Tag-list cross-check. In WinCC Explorer open Tag Management > S7-TCP > MyConnection > Tags and confirm that the mirror tag (MD100 or DB200.DBD0) is online and shows OK in the status column.
-
PLC table watch. In STEP 7 V5.5 SP4 (or TIA V15.1 for the same S7-300 project) open Monitor/Modify on MW0. Set the value to 1, 2, 3 and verify that MD100 tracks the value of
DB1.DBD0,DB2.DBD0,DB3.DBD0respectively. - Out-of-range test. Set MW0 to 0 and to 32768. The status word MW20 must read 1 and the mirror must hold 0.0 (or the last valid value, depending on the chosen SCL semantics).
- Archive round-trip (RT Professional only). Trigger a 20-tag query and a 21-tag query. The 21-tag query must return a provider error with a message stating the 20-tag limit. Reference: Querying Process Value Archives (RT Professional).
- Load test. Run OB1 with a 50 ms cycle and a 50-step source DB list. Confirm that BLKMOV completes within 30 ms on the CPU 315-2 PN/DP. The SFC20 RET_VAL must be 0.
Troubleshooting Matrix
| Symptom | Likely Cause | Countermeasure |
|---|---|---|
| Mirror tag shows 0.0 and never changes | Bytes 4-5 of ANY not updated; SFC20 RET_VAL = W#16#80A1 | Confirm DB99 is not optimized/blocked. Check that MW0 is initialised to a valid DB before OB1 runs the first time. |
| Mirror tag reads from the wrong DB | Byte order of DB number written to bytes 4-5 is reversed (S7-300 is big-endian for ANY) | Write the word to DBW 2, not to two separate byte writes. See the STL example in Implementation 1. |
| SFC20 RET_VAL = W#16#80B1 | Source DB not loaded (length 0 or never initialised) | Open SZL 0x0132 on the CPU to enumerate loaded DBs. Drop the source DB list to only those flagged as loaded. |
| Channel DLL reports "Address not valid" | Tag bound to DB number 0 or 65535 | Validate the index in the script (C path) or in OB1 (PLC path) and clip to 1-32767. |
| WinCC loses connection to CPU intermittently during script polling | Script cycle faster than the channel partner can serve; partner resource exhausted | Increase the script trigger to 1 s. Reduce the partner resource usage by switching the C script from GetTagFloat per call to one GetTagMulti call when supported. |
| Archive query returns no rows despite data being present | Tag name exceeds 128 chars or the batch is over 20 tags | Split into 20-tag batches and shorten the archive/tag qualifier names. See Querying Process Value Archives (RT Professional). |
FAQ
Does WinCC V7.0 expose DB-multiplexing in the tag dialog like WinCC Flexible?
No. The WinCC V7.0 tag editor binds a tag to a fixed absolute address (area + DB number + byte offset + bit offset). There is no "DB Multiplexed" field in the tag properties. Multiplexing must be implemented either on the PLC side via an ANY pointer (see Implementation 1) or on the HMI side via a C script (see Implementation 3).
Which S7-300 transport size should I use for a DBD (REAL) read?
Use transport size 0x06 (DWORD) in the ANY pointer. A REAL is 32 bits on the S7-300 and is bit-identical to a DWORD on the wire, so 0x06 is correct. Use 0x02 for an 8-bit BYTE, 0x04 for a 16-bit WORD/INT, and 0x06 for 32-bit DWORD/REAL/DINT.
What happens if I set the active DB number (MW0) to a DB that is not loaded?
SFC20 returns W#16#80B1 (area length error) and the mirror keeps its last value. The SCL implementation in this article surfaces a 1 in the status word MW20; the HMI script can read MW20 and show an "Index invalid" alarm. Always validate against SZL ID 0x0132 (list of all data blocks) on the CPU before publishing a new DB list to the operator.
How many tags can a single WinCC RT Professional archive query return?
Maximum 20 tags per query, with a maximum of 128 characters per tag (including the archive::tag qualifier). Larger requests must be batched in the application. See Querying Process Value Archives (RT Professional).
Can the ANY pointer approach be migrated to S7-1500 / TIA Portal?
No. The S7-1500 has a different ANY structure (16 bytes, optimized block access) and TIA Portal restricts indirect DB access with fully-qualified DB names. Use the PEEK/POKE instructions or the Variant data type in SCL on the S7-1500. The patterns above apply only to S7-300/400 and to S7-1500 with classic, non-optimized DBs.