Overview: Mirroring WinCC Runtime Language in the PLC
Multilingual WinCC projects on Comfort Panels, WinCC Advanced Runtime, and WinCC Professional Runtime let the operator switch between languages through an HMI button configured with the ChangeLanguage system function. The PLC, however, does not automatically receive any notification of that change — yet many recipes, audit trails, alarm archives, and PLC-side messages need to know which operator locale is active to log localized actions or to switch between language-specific message classes.
This reference describes three reliable methods for synchronizing language state between the WinCC runtime and a SIMATIC S7-1200, S7-1500, S7-300, or S7-400 controller, and then walks through commissioning, verification, and fault diagnostics.
HMIRuntime.Language is not available — use the SetBit/ResetBit tag-event approach instead.Prerequisites
Before configuring language tags, verify the following baseline:
| Item | Requirement | Notes |
|---|---|---|
| TIA Portal | V15.1 or higher (V18 / V19 recommended) | V14 SP1 works but lacks OnLanguageChanged event support on Unified panels |
| HMI Runtime | WinCC Comfort / Advanced / Professional | Unified Comfort Panels use a different scripting model — see the Unified scripting reference |
| PLC | S7-1200 / S7-1500 (recommended), S7-300 / S7-400 / ET200SP | Any controller with a configured HMI connection |
| Project Languages | Project → Languages & Resources: English + Italian (or other locales) enabled | WinCC requires the locale identifier (LCID) installed on the panel |
| Operator permissions | "Change language" right assigned to the relevant user group | If restricted, the language tag will not toggle even if the bit fires |
| PLC ↔ HMI connection | Integrated or named connection with Language & Font area pointer enabled | Required for Method 3 only |
Architecture: Bidirectional Language Tag Flow
Two distinct information paths can be configured. Both can coexist on the same panel.
Path A — HMI → PLC (status mirror)
The HMI detects the operator's language change through a button event or a tag-change handler, then writes a status bit (or the full LCID) into a configured PLC tag. The PLC reads this tag to know the current operator locale.
Path B — PLC → HMI (command channel)
A configured HMI connection area pointer named Language & Font carries an integer from the PLC that selects the active language index. The PLC writes the desired index and the runtime switches automatically without operator input.
Method 1 — Reading the Active Language with HMIRuntime.Language
The WinCC Runtime scripting object HMIRuntime exposes a read-only Language property that returns the locale identifier (LCID) of the currently active user interface language. This is the canonical method for HMI-internal logic that depends on language, such as branching in VBScript or triggering a SetBit to a PLC tag.
Typical Windows LCIDs encountered in Siemens projects:
| Language | LCID (decimal) | LCID (hex) | Project language index |
|---|---|---|---|
| English (United States) | 1033 | 0x0409 | 0 |
| English (United Kingdom) | 2057 | 0x0809 | 0 / 1 (depends on order) |
| German (Germany) | 1031 | 0x0407 | 1 |
| Italian (Italy) | 1040 | 0x0410 | 2 |
| French (France) | 1036 | 0x040C | 3 |
| Spanish (Spain) | 3082 | 0x0C0A | 4 |
| Chinese (Simplified) | 2052 | 0x0804 | 5 |
Minimal VBScript reading the runtime language
Attach the following code to a button's Click event or to a tag's Change event:
' Returns the active runtime language LCID
Dim lngLCID
lngLCID = HMIRuntime.Language
SmartTags("HMI_Language_LCID") = lngLCID
Where HMI_Language_LCID is an INT tag connected to a PLC address (for example, DB100.DBW0 on an S7-1500) via the standard HMI tag list.
Method 2 — Driving the PLC Status Word from Button Events
When the operator changes language with an HMI button configured for the system function ChangeLanguage, that button accepts an unlimited number of additional events. Two of those events — SetBit and ResetBit — let you mirror the new language into one or more PLC bits without writing a single line of script.
Step-by-step configuration
- In the WinCC project tree, locate the language button on the screen (typically the language toggle icon).
- Open the button's Properties → Events.
- Confirm that an existing event ChangeLanguage with a configured language parameter is present.
- Add a new event: SetBit with PLC tag
DB100.DBX0.0(English status) when the language parameter is set to English (LCID 1033 or project index 0). - Add a new event: SetBit with PLC tag
DB100.DBX0.1(Italian status) when the language parameter is set to Italian (LCID 1040 or project index 2). - For each added SetBit, also add the corresponding ResetBit for the opposite language so the bits are mutually exclusive.
Resulting PLC tag layout (example for English / Italian)
| Bit / Word | Symbol | Meaning |
|---|---|---|
| DB100.DBX0.0 | HMI_Lang_EN | TRUE while English is active |
| DB100.DBX0.1 | HMI_Lang_IT | TRUE while Italian is active |
| DB100.DBX0.2 | HMI_Lang_DE | TRUE while German is active (optional) |
| DB100.DBW2 | HMI_Lang_LCID | Full LCID as INT (mirror of HMIRuntime.Language) |
| DB100.DBB4 | HMI_Lang_Index | Zero-based project index (0=EN, 1=DE, 2=IT) |
Method 3 — Driving the WinCC Language from the PLC
WinCC Comfort and WinCC Advanced support a built-in connection area pointer named Language & Font. When this pointer is enabled and mapped to a PLC integer tag, the runtime polls that tag and changes the active language index whenever the value changes. This is the canonical answer to the follow-up question: "Can I set a bit in the PLC to select the language in the HMI?"
Configuration path
- In the TIA Portal project tree, open HMI device → Connections.
- Select the connection used for the target panel (e.g., "HMI_Connection_1").
- In the Connection properties, enable the Language & Font area pointer.
- Bind it to a PLC tag of type INT or WORD — recommended:
DB100.DBW6namedPLC_Lang_Command. - Compile and download both the PLC and HMI projects.
PLC logic to drive the language
Write the desired project index to PLC_Lang_Command. WinCC reads the index on every cycle and selects the matching language:
| PLC value | Project language selected |
|---|---|
| 0 | First configured language (typically English) |
| 1 | Second configured language |
| 2 | Third configured language (e.g., Italian) |
| 3 | Fourth configured language |
| n outside range | Runtime ignores the change; last valid language stays active |
S7-1500 Structured Text example (TIA Portal)
// Network 1: English command
IF "Cmd_Lang_EN" THEN
"PLC_Lang_Command" := INT#0;
END_IF;
// Network 2: Italian command (overrides English if both set in same cycle)
IF "Cmd_Lang_IT" THEN
"PLC_Lang_Command" := INT#2;
END_IF;
// Network 3: Optional sentinel for re-trigger (see Pattern B below)
IF "Cmd_Lang_Refresh" THEN
"PLC_Lang_Command" := INT#99;
"Cmd_Lang_Refresh" := FALSE;
END_IF;
Edge-detected behaviour
The pointer is change-driven: the runtime compares the polled value against the previous value and only switches if the integer changes. Toggling between two identical indices does not force a refresh. If a refresh is needed, write the target index, wait one acquisition cycle (default 1 s on Comfort Panels), then either clear the tag to a sentinel value (e.g., 99) or write the next desired value.
Tag Configuration Reference
| Setting | Recommended value | Rationale |
|---|---|---|
| PLC tag data type (status bits) | BOOL via DBX | One bit per language, mutually exclusive |
| PLC tag data type (LCID mirror) | INT | Holds full LCID up to 65535 |
| PLC tag data type (command pointer) | INT | WinCC pointer expects 16-bit integer |
| HMI acquisition mode (status bits) | Cyclic continuous | Bit transitions must propagate |
| HMI acquisition mode (command pointer) | Cyclic continuous, 1 s | Default for area pointer |
| Update cycle | 500 ms – 1 s | Faster cycles increase HMI load |
| PLC retention | Non-retentive | Operator should re-select after power cycle |
| Pointer length | 2 bytes (INT) | WinCC expects exactly 2 bytes for Language & Font |
VBScript Reference Library
The following snippets cover the three most common patterns. All scripts are valid for WinCC Comfort/Advanced V15.1 to V19 and WinCC Professional V16 to V19.
Pattern A — Write LCID to PLC on every change
' Attach to the "Change" event of the screen's language button
Sub OnClick(ByVal Item)
Dim sLang
sLang = HMIRuntime.Language
SmartTags("HMI_Language_LCID") = sLang
' Optional: decode and set discrete bits
Select Case sLang
Case 1033, 2057
SmartTags("HMI_Lang_EN") = True
SmartTags("HMI_Lang_IT") = False
Case 1040
SmartTags("HMI_Lang_EN") = False
SmartTags("HMI_Lang_IT") = True
Case Else
SmartTags("HMI_Lang_EN") = False
SmartTags("HMI_Lang_IT") = False
End Select
End Sub
Pattern B — Force a refresh of the Language & Font pointer
' Use when re-applying the same language after configuration
Sub OnClick(ByVal Item)
Dim iCurrent
iCurrent = SmartTags("PLC_Lang_Command")
' Pulse a sentinel value to force edge detection
SmartTags("PLC_Lang_Command") = 99
HMIRuntime.Trace "Sentinel written - runtime will re-evaluate on next poll"
SmartTags("PLC_Lang_Command") = iCurrent
End Sub
Pattern C — Subscribe to HMIRuntime events for centralized handling
Available on WinCC Professional and Unified Comfort Panels (V17+). Use the OnLanguageChanged event:
' Global module or screen-level event
Sub OnLanguageChanged(ByVal newLanguage)
SmartTags("HMI_Language_LCID") = newLanguage
End Sub
For more scripting details consult the VBScript Reference for WinCC Comfort/Advanced manual.
Commissioning and Verification
- Compile the TIA Portal project. Resolve all warnings — HMI area pointer mismatches appear as warnings of category "HMI Tag Consistency".
- Download to the PLC first, then to the HMI. Reboot the panel if the firmware version changed.
- Open the configured language button. Toggle English ↔ Italian three times.
- Monitor
DB100.DBX0.0andDB100.DBX0.1online in the PLC. They must toggle mutually exclusive. - Verify
DB100.DBW2(LCID mirror) holds 1033 for English and 1040 for Italian. - For Method 3, force
PLC_Lang_Commandto 0, 1, 2 from the PLC watch table. Confirm the HMI language changes within one acquisition cycle. - Open the HMI's diagnostic page (Control Panel → System Information → Runtime Diagnostics) and verify no pointer errors are reported under "Area pointers".
- Test power-cycle behaviour. After a warm restart, the HMI typically defaults to project index 0 unless you bind the Language & Font pointer to a retentive PLC tag.
- Test operator rights. Log in as a restricted user; confirm the language change button is greyed out and no PLC bit fires.
- Capture a screenshot of the HMI audit trail (if WinCC Logging is licensed) showing both languages were selected during commissioning.
Troubleshooting Matrix
| Symptom | Likely cause | Resolution |
|---|---|---|
| PLC bits stay FALSE after language change | Operator group lacks "Change language" right | Grant the right under User Administration → Authorizations |
| Bits toggle but LCID mirror stays 0 | HMI tag for LCID is not configured as "Cyclic continuous" | Switch acquisition mode to "Cyclic continuous" with 1 s cycle |
HMIRuntime.Language always returns 1033 |
Project only has English enabled | Project → Languages & Resources → enable Italian and translate all texts |
| Language & Font pointer has no effect | Pointer not enabled on the connection | Open Connections → enable "Language & Font" and bind to an INT tag |
| Runtime reports "Area pointer error 0x8004XXXX" | PLC tag length mismatch (e.g., DWORD bound where INT expected) | Bind a 2-byte INT tag; the pointer length is fixed at 2 bytes |
| Both language bits TRUE simultaneously | SetBit configured but ResetBit on previous language missing | Add ResetBit events for sibling languages |
| Script "HMIRuntime.Language not found" | Running on Unified Comfort Panel with JavaScript engine | Use UI.ActiveScreen.FocusedItem.Language or the global Languages property — see Unified scripting reference
|
| PLC-driven command ignored on warm restart | Pointer tag is non-retentive and PLC resets to 0 | Mark tag retentive OR re-write the desired value in OB100 / first OB1 scan |
| Tag transition takes >2 s | Acquisition cycle too long or PLC update too slow | Reduce cycle to 500 ms; verify PLC cycle time < 50 ms |
| Localized PLC alarm texts do not change | Alarm texts stored as PLC-side text references instead of HMI-side | Move alarm text configuration to the HMI project and bind only the alarm number to the PLC |
Field-Proven Best Practices
- Always combine the bit-status mirror (Path A) with the LCID mirror in the PLC so downstream logic has both a quick boolean test and a precise identifier.
- Keep the language pointer under PLC control only on startup or via a dedicated engineering screen. Letting the operator control the language from the PLC defeats the purpose of multilingual HMI.
- Document the project language index order in the PLC source comments. Index assignments shift whenever the engineer reorders the language list, which silently breaks PLC-driven selection.
- For Unified Comfort Panels, prefer the new
Languagesglobal object over VBScript-legacy calls. The legacyHMIRuntime.Languagestill works in compatibility mode but is deprecated. - Add a status tag
HMI_Lang_Unknownthat fires if the runtime reports an LCID not present in the project. It catches translation gaps early during FAT. - When deploying to multiple panels, give each panel its own PLC DB block for language state. A single shared DB requires tag multiplexing that is brittle on slow PROFINET links.
- Use TIA Portal's Cross-reference tool to confirm every language change button has its Set/Reset events bound — missing events cause silent failures during SAT.
Frequently Asked Questions
How do I detect which language is active on a WinCC panel from the PLC?
Use an HMI tag connected to HMIRuntime.Language (returns the LCID as an integer, e.g., 1033 for English or 1040 for Italian) or attach SetBit / ResetBit events to the language button that write to dedicated PLC bits such as DB100.DBX0.0 for English and DB100.DBX0.1 for Italian. Both approaches run without extra licensing.
Can a PLC bit force the WinCC runtime to switch language?
Yes. Enable the Language & Font area pointer on the HMI connection and bind it to a 16-bit INT PLC tag. The runtime polls the tag every acquisition cycle (default 1 s) and selects the language whose project index matches the integer value (0 = first language, 1 = second, 2 = third, and so on).
What is the difference between LCID 1033 and project index 0?
LCID 1033 is the Microsoft locale identifier for English (United States) and is returned by HMIRuntime.Language. Project index 0 is the zero-based position of English in your project's "Languages & Resources" list and is what the Language & Font pointer expects. They are independent — index 0 always refers to the first configured language regardless of its LCID.
Why does my SetBit fire but the corresponding ResetBit never clears the previous language?
WinCC button events are not mutually exclusive. If you add SetBit for Italian but forget to add ResetBit for English, the English bit stays TRUE. Add ResetBit events for every sibling language on every language button to guarantee exclusive state.
Does this work on Unified Comfort Panels and WinCC Professional?
Yes, with one caveat. On Unified Comfort Panels the legacy HMIRuntime object is replaced by the global Languages and UI objects in JavaScript. The Language & Font pointer and SetBit/ResetBit PLC tag events work unchanged. On WinCC Professional the legacy VBScript model is fully supported; you can additionally subscribe to the OnLanguageChanged event introduced in V17.
For authoritative details on area pointer configuration see the WinCC Comfort/Advanced Communication manual and the VBScript for WinCC reference. For Unified scripting refer to the Unified Comfort Panel programming manual.