1. Problem Overview
Engineers building line-scale or machine-cluster projects frequently end up with several S7-1200 CPUs — for example 6ES7214-1AG40-0XB0 (CPU 1214C DC/DC/DC) or 6ES7215-1AG40-0XB0 (CPU 1215C) — connected on a single PROFINET subnet and each running a near-identical control program. Only a small slice of the program needs to differ per station: the IP address of a downstream Modbus TCP slave, a station number, a process tag name, or the assignment of a few I/O points. The rest of the logic, the HMI screens, and the data block layouts are duplicates.
The first reflex is to copy the project, change a few constants, and download it N times. That approach works for one commissioning, then collapses the moment a bug fix has to be pushed to station 1 and station 7 simultaneously, or when a UDT changes shape. Copy/paste across projects is the single largest source of version drift in brownfield S7-1200 fleets.
The real problem is therefore narrower than it first appears: how do you keep global data blocks, PLC tag tables, FC/FB code, UDTs, and Unified HMI screens synchronized across many S7-1200 stations without copy/paste drift, while still letting each CPU carry its own per-instance configuration (Modbus slave IP, station number, CPU IP address itself)?
This article describes a structured workflow in TIA Portal V18 (the patterns also apply to V17 and V19) for keeping the executable code, tag tables, data block layouts, and HMI screens synchronized across many S7-1200 stations while still allowing per-instance runtime configuration. The workflow centers on four building blocks:
- Global Library (.al18 file) for shared master copies and library types.
- Type-instanced Data Blocks built from a single UDT shared in the library.
- PLC tag tables stored as library types so symbol names propagate to every CPU.
- Runtime configuration via Web Server / Watch Tables / PRONETA, so per-station values (CPU IP, Modbus slave IPs, station number) live in data blocks — not in project properties — and the same offline project can be downloaded to every CPU.
The result is one source of truth for application code and a single point of change for bug fixes, while each CPU still receives its station-specific commissioning data through standard Siemens tooling — no per-station re-engineering required.
2. Architecture Decisions and Prerequisites
Before opening the Global Library editor, classify every artifact in the project as shared or per-station. The classification drives whether the artifact lives in the library as a type, as a master copy, or stays local to each CPU.
| Artifact | Classification | Where it lives | How it changes |
|---|---|---|---|
| FCs (functions) | Shared | Global Library — type | Edit in library, instances auto-update |
| FBs (function blocks) | Shared | Global Library — type | Edit in library, instances auto-update |
| UDTs (user-defined data types) | Shared | Global Library — type | Edit in library, all derived DBs reflow |
| Instance DBs of shared FBs | Per-station | Local in each PLC | Instance data only; structure comes from FB type |
| Global DBs containing per-station constants | Per-station | Local in each PLC, same layout | Initial values written at commissioning |
| PLC tag table (default + user) | Shared (names) / Per-station (values) | Tag table as type in library, values as instance data | Symbols propagate; current values stay local |
| OBs (Organization Blocks) | Shared | Local copy in each PLC (TIA cannot library-ize OBs) | Edit in one PLC, export and re-import via copy/paste or library master copy of the OB |
| HMI screens (Unified Comfort) | Shared | Global Library — type (with HMI tag prefix) | Edit in library, propagate to all HMI instances |
| PROFINET device configuration | Per-station | Local to each PLC | Cannot be library-ized directly; use IP-via-DB pattern instead |
| CPU IP address | Per-station | NOT in project — written via PRONETA / Web Server / TIA Online & Diagnostics | Same project downloads to every CPU; IP assigned post-download |
Prerequisites
- TIA Portal V18 (or V17/V19) with the S7-1200 HSP installed that matches the CPU firmware.
- One S7-1200 per station with identical article numbers, or at minimum identical firmware major version (e.g., all V4.4.x).
- One TIA project containing one master PLC station (the “template”) plus clones for the rest of the fleet. Alternatively, use the device proxy workflow: drag one fully-configured CPU from the global library into each new project.
- Access to Siemens Industry Online Support for the S7-1200 system manual and the “Programming and Style Guide for S7-1200/1500.”
- Siemens PRONETA (V3.x or higher) for network discovery and IP assignment; download from Siemens PRONETA product page.
3. Building a Global Library in TIA Portal V18
A Global Library is a stand-alone .al18 file that exists independently of any project. It contains types (auto-propagating master copies) and master copies (manual-update master copies) for blocks, tag tables, HMI screens, entire configured PLCs, and pre-configured PROFINET devices.
Step-by-step: create the library skeleton
- In TIA Portal, choose Libraries → Global libraries → “Create new global library”. Pick a network share, not a local path — the library file must be reachable by every engineer who will edit the project, otherwise divergence reappears within a week.
- Name the library
FLEET_Common_v1.al18. Use a version-suffixed filename so old releases stay recoverable. - Create the folder structure inside the library:
-
Master copies / Blocks /— for one-off copies (OBs, HMI-specific blocks). Types / Blocks / FCTypes / Blocks / FBTypes / Blocks / DBTypes / Blocks / UDTTypes / Tag tablesTypes / HMI / ScreensTypes / PLCs / S7-1200_Template
-
- Set TIA Portal's library autosave: Options → Settings → Libraries → tick “Save libraries automatically” with a 10-minute interval.
Master copy vs type — the decision that drives everything else
When you drag a block from a project into the library, TIA Portal asks whether it is a master copy or a type. The choice is not aesthetic:
| Property | Master copy | Type (library type) |
|---|---|---|
| Updates to instances | Manual, per instance, via right-click “Update” | Automatic on next compile / project open if “Synchronize” is enabled |
| Versioning | Library can hold multiple versions side by side | Only the latest version is exposed |
| Interface change handling | Renames; warns on signature change | Forces update or breaks instance if signature changes incompatibly |
| Best use | OBs, project-specific HMI screens, anything you want to keep multiple frozen versions of | FC/FB code, UDTs, default tag table, HMI screen templates |
| Fleet-scale fit | Poor — one missed Update and one PLC is now on the old code | Excellent — TIA Portal refuses to compile with stale types |
Fleet rule: Put every FC, FB, UDT, PLC tag table, and shared HMI screen in the library as a type. Use master copies only for OBs and for one-off versions you intend to retire.
4. Reusing Code Blocks as Master Copies
The first concrete win is putting every shared FC and FB into the global library as a type. The mechanic is the same for both, but FBs need a small additional decision because each FB needs an instance DB.
Step-by-step: ship FCs and FBs from the template PLC into the library
- Open the template PLC project. Make sure every FC and FB compiles cleanly with no warnings — warnings in library types propagate to every CPU and appear in every diagnostic buffer.
- Select the FC/FB in the project tree, drag it into
Types / Blocks / FC(orFB) in the global library. When prompted, choose Type. - Open the library, right-click the new type → Properties → “Use as type” — verify the checkbox is set.
- For every other PLC station in the fleet, open the project and drag the library type into the Program blocks folder of the station's S7-1200. TIA Portal creates a local instance that references the library type.
- For FBs, TIA Portal automatically creates a matching instance DB per drop location. Rename instance DBs by station, e.g.,
FB_Motor_Station1_IDB,FB_Motor_Station2_IDB.
Updating shared code from the library
- Edit the FC/FB inside the global library (double-click to open the library's editing view).
- Save the library. Close the library editing view.
- Re-open every project that uses the type. TIA Portal shows a yellow exclamation badge in the project tree on any element that has an available update.
- Right-click the station → “Library → Synchronize...”. Review the diff. Confirm.
- Compile and download only the changed blocks to each station. Online → “Download to device” with the “Consistent download” option disabled for sub-50 KB block changes (faster, and the S7-1200 supports partial block downloads).
5. Synchronizing PLC Tag Tables Across CPUs
Symbolic addressing is mandatory for code that has to move between stations. M-memory (%MW0, %MB10, %M5.0) is the legacy approach and the source thread correctly flags it as emulated on S7-1200/1500, with poor visibility in cross-reference and poor support for optimized block access.
The right pattern for shared symbols
- Open the template PLC. Build one or more user-defined tag tables (right-click “PLC tags → Add new tag table”). Name them by function, e.g.,
tt_Process,tt_Motor,tt_Alarms. - Declare every shared symbol with its full data type, e.g.:
Motor_Start : Bool; // %DB10.DBX0.0Motor_Speed_SP : Real; // %DB10.DBD4Station_ID : USInt; // %DB10.DBB8 - Drag each tag table into the global library under
Types / Tag tables. Confirm “Use as type.” - In every other station, drop the library type into the local “PLC tags” folder. The symbols appear identically in every CPU's symbol table.
What propagates and what does not
| Tag property | Propagates via library type? | Notes |
|---|---|---|
| Symbol name | Yes | Always |
| Data type | Yes | Always |
| Comment / tooltip | Yes | Useful for Unified HMI text fields |
| Address binding (I / Q / M / DB) | Partially | M-addresses are emulated and re-bound per CPU; DB-addresses propagate as long as the DB is also shared as a type |
| Current value (online) | No | By design — values are runtime state |
Practical recommendation: Put every shared boolean, integer, real, and string into a global DB with optimized access and reference it through the tag table. Avoid M-memory entirely. Not only does this fix the S7-1200/1500 emulation penalty (M-memory writes happen via an internal data block and bypass the optimized-block fast path), it also means that a tag table drop into the next station picks up the correct DB addresses because the DB itself is a library type.
6. Using Type-Instanced Data Blocks for Per-CPU Data
The shared UDT defines the shape. The instance DB provides the values. This separation is what makes the same program shippable to every CPU.
Build the per-station configuration UDT
Inside the global library, create a UDT named UDT_StationConfig:
TYPE UDT_StationConfig :
STRUCT
Station_ID : USInt; // 1..255, written at commissioning
Station_Name : String[32]; // e.g., "LineA_Module3"
CPU_IP : String[15]; // for display only; actual IP set via PRONETA
Modbus_Slave_IP : String[15]; // e.g., "192.168.0.51"
Modbus_Port : UInt; // default 502
Modbus_UnitID : Byte; // Modbus unit / slave ID, 1..255
Scan_Time_ms : UInt; // cycle for Modbus polling, e.g., 250
Spare_DINT[0..7] : DInt; // 32 bytes reserved for future use
END_STRUCT
END_TYPE
Build the per-station configuration DB
- In the template PLC, create a global DB named
DB_StationConfig. Set “Optimized block access” ON (default on S7-1200 V4+). DragUDT_StationConfiginto the DB as a single instance. - Drag
DB_StationConfiginto the global library as a type. Set the DB's start value to all zeros except for fields that should have a safe default (e.g.,Scan_Time_ms = 250,Modbus_Port = 502). - Mark the DB as non-retain if station-specific values can be re-entered at every cold start; mark it retain if commissioning happens once and the values must survive power-cycle.
- Drop the library type into every other station's PLC program. Rename per station, e.g.,
DB_StationConfig_LineA1.
Reference the per-station DB from code
// FB_ReadModbus (in shared library)
#iStatus := "MB_CLIENT_DB".Master_Slave_IP; // bind once
// At runtime, the actual slave IP comes from DB_StationConfig:
"MB_CLIENT_DB".Master_Slave_IP := "DB_StationConfig_LineA1".Modbus_Slave_IP;
The FB does not change between stations. Only the instance of DB_StationConfig changes, and only its values are station-specific.
7. Moving IP and Device Configuration into Runtime DBs
The single highest-leverage habit in a multi-CPU S7-1200 fleet is: never store the CPU's own IP address, the Modbus slave's IP address, or any station-specific device parameter in the offline project. Store them in DBs and write them at commissioning time.
Why this matters
- If the CPU's IP is in the offline project, you must compile a different project per station. That defeats the entire library workflow.
- If the IP is in a DB, you compile once and download the same project to every CPU. Commissioning assigns IPs via PRONETA, Web Server, or TIA Online & Diagnostics.
- If a CPU is replaced in the field (a real maintenance scenario on S7-1200 fleets), the replacement CPU is loaded with the same project and the commissioning engineer enters the IP from the front panel of the Web Server.
Setting the CPU IP via PRONETA
- Connect the laptop running PRONETA to the PROFINET subnet.
- Start PRONETA → Network Analysis. The tool discovers every S7-1200, identifies its MAC, current IP, and device name.
- For each CPU, right-click → “Assign PROFINET device name” and “Assign IP address”. The IP and name are written to the CPU directly; the offline project is untouched.
- After all CPUs are named, click “Topology” in PRONETA to verify that each CPU's ports (P1R / P2R) match the offline topology. Mis-wired PROFINET cables show up here before they cause late-night commissioning calls.
Setting the CPU IP via TIA Online & Diagnostics
- Open the online accessible nodes view. Select the target CPU.
- Right-click → “Online & Diagnostics” → “Assign IP address”. Enter the IP, subnet mask, and PROFINET device name.
- Confirm. The CPU restarts its PROFINET interface (typically < 5 seconds; the CPU program keeps running).
8. Web Server and Watch Tables for Commissioning
Even with PRONETA, the field engineer still needs to write the Modbus slave IP, port, station number, and other per-station values into DB_StationConfig. Two patterns make this practical without re-engineering the offline project.
Pattern A — Watch table driven by a Web Server page
- Create a watch table in the template PLC named
wt_StationConfig. Drag the symbols"DB_StationConfig".Station_ID,"DB_StationConfig".Modbus_Slave_IP,"DB_StationConfig".Modbus_Port,"DB_StationConfig".Modbus_UnitID, and"DB_StationConfig".Scan_Time_msinto it. - Enable the Web Server on the S7-1200: Device properties → Web server → “Enable Web server on this module.” Set a strong administrator password.
- Under “User-defined pages,” enable the watch table. Tick “Read” and “Write” for the symbols. The Web Server will generate an HTML page from the watch table automatically.
- At commissioning, the field engineer opens
http://<cpu-ip>in a browser, logs in, opens the watch-table page, edits the values, and clicks “Write.” No TIA Portal, no laptop with the project, no USB.
Pattern B — Operator-input HMI page on the Unified Comfort panel
- Build one HMI screen in the template project named
Screen_Commissioning. Bind input fields to theDB_StationConfigsymbols. - Store the screen in the global library as a type.
- For every CPU with a Unified Comfort panel, drop the screen from the library. Re-bind the HMI tag prefix to the local instance of
DB_StationConfig.
Web Server constraints to know in advance
| Constraint | Value / Limit | Notes |
|---|---|---|
| Max concurrent Web Server users (S7-1200) | 5 active sessions | Per system manual; sessions over the limit are rejected |
| HTTPS required? | Yes, recommended for write-enabled user-defined pages | Use the “Generate certificate” wizard or load a CA-signed cert |
| User-level write access | Per watch-table symbol | Granular; do not grant “write all” to a single shared operator account |
| Write of STRING symbols via watch table | Supported on V4.4 firmware; partial on V4.2 | Test on the actual firmware before commissioning |
| HTTP-only mode | Available but insecure for write | Use only on isolated commissioning laptops |
9. Unified HMI Integration with Library Types
A Unified Comfort HMI (MTP700 / MTP1000 / MTP1200) that visualizes 7 S7-1200s does not need 7 separate HMI projects. The HMI tags and screens can be library-typed, with a single prefix parameter pointing at the right PLC.
Step-by-step: build the Unified HMI from library types
- In the template PLC + HMI project, configure the HMI connection to a symbolic placeholder PLC name, e.g.,
PLC_Station_Template. - Build the HMI tag table with a prefix (e.g.,
STATION_) and the suffix coming from the PLC tag table symbols. This makes screen reuse trivial: change the prefix, the screen reads from a different CPU. - Build the screens. Drag them into
Types / HMI / Screensin the global library. - For each station, drop the screens into the HMI project. In the HMI connection, point the symbolic connection at the actual PLC.
Unified HMI limitations
- HMI alarm configuration cannot be fully library-typed — alarm texts and alarm classes need to be re-bound per project. Build alarm texts in the PLC (text-list driven) so the HMI side stays thin.
- Recipes on the HMI are project-local. If each station has recipe data, store it in a per-station DB on the PLC instead of in the HMI recipe memory.
- User administration on Unified HMI is project-local. Either use a central SIMATIC Logon server, or replicate the accounts with a library-typed export/import script.
10. Project Download, Verification and Change Propagation
With the library, DB, and Web Server patterns in place, the project download sequence is the same for every CPU. That uniformity is the whole point.
First-time commissioning sequence (per station)
- Open the TIA project for this station. The library symbols populate automatically.
- Connect the laptop to the PROFINET subnet. Run PRONETA — assign PROFINET device name and IP address to the S7-1200.
- In TIA Portal, Online → Download to device. Choose the right CPU. Select “Download to device” (full) for first-time load.
- Open the Web Server in a browser. Navigate to the watch-table page. Enter station-specific values:
Station_ID,Modbus_Slave_IP,Modbus_Port,Modbus_UnitID. Click “Write.” - Restart the CPU (or issue an MB_CLIENT connection reset) so the new Modbus parameters take effect.
- Verify: open
wt_StationConfigonline in TIA — confirm the values match what was entered. - Verify: trigger a Modbus read from the slave, confirm
MB_CLIENT_DB.Done is set withinScan_Time_ms.
Subsequent change propagation (e.g., bug fix in an FC)
- Edit the FC in the global library. Save.
- Open every project. Run “Library → Synchronize...”. Review diff.
- Compile. Online → “Download to device — Software (only changes)”. TIA downloads only the modified blocks; the program scan is interrupted for < 200 ms on the S7-1200.
- Verify: open the modified FC online, confirm the timestamp matches the library version. Confirm the diagnostic buffer has a “Firmware update” or “Download finished” entry with the matching time.
11. Troubleshooting Matrix
| Symptom | Likely root cause | First check | Fix |
|---|---|---|---|
| One station runs older code after a library sync | Engineer opened project but did not run “Synchronize” | Compare FC timestamp online vs library | Open project, right-click station → “Library → Synchronize” |
| Watch-table page shows “Write failed” for a STRING tag | CPU firmware < V4.4 | Online & Diagnostics → “CPU information” | Upgrade firmware or write STRING via HMI input field instead |
| MB_CLIENT error code 0x8081 (connection timeout) | Wrong Modbus_Slave_IP in DB_StationConfig, or the wrong DB instance is being read | Watch table: "DB_StationConfig".Modbus_Slave_IP
|
Write correct IP via Web Server; restart MB_CLIENT |
| Library type instance does not auto-update after library edit | Element was dragged as “Master copy” not “Type” | Library → element properties → “Use as type” | Delete instance, re-drag as type; verify auto-update on next open |
| Symbol table in station 3 is empty after drop from library | Tag table dragged as master copy, then closed without saving | Project tree → PLC tags → right-click → “Show library references” | Re-drag tag table type, recompile |
| M-memory addresses differ between stations | M-memory is project-local, not library-typed | Cross-reference for any %M usage | Refactor: replace every %M with a symbol in a shared DB; remove all %M usage |
| HMI shows “No connection” to one station after project copy | HMI connection was edited to point at the wrong PLC | HMI project → Connections → check the symbolic name | Re-point the HMI connection at the correct CPU; redownload HMI |
| Web Server returns 503 service unavailable | More than 5 active sessions, or Web Server disabled in Device properties | Online & Diagnostics → Web server → “Active sessions” | Close idle sessions; verify “Enable Web server on this module” is ticked; restart the Web Server via “Stop/Start Web server” |
| UDT edit in library breaks all instance DBs | UDT change is signature-incompatible (e.g., changing BOOL to INT mid-struct) | Compile error list → “Incompatible change” entries | Add new tag at the END of UDT (additive change is always compatible); or migrate via versioned UDTs (UDT_StationConfig_v1, v2) |
| Download to S7-1200 fails with “Firmware version not supported” | Project compiled against newer firmware than the CPU has | Compare CPU firmware vs project target firmware | Install matching HSP, recompile, or upgrade CPU firmware |
12. Field-Proven Caveats
- Firmware drift is the silent killer. Pin the firmware version in the TIA project (Device properties → “Firmware version”) so the project cannot silently compile for V4.5 when half the fleet is still on V4.2. Every station should run the same firmware; this is non-negotiable for library-typed code.
- Watch the size budget. An S7-1200 with firmware V4.4 has 100 KB of work memory (CPU 1214C) or 150 KB (CPU 1215C). Each library-typed instance consumes the same memory as a copy. If the fleet pattern is “drop 15 instance DBs per station,” verify with a memory audit before commissioning the 16th station.
- Do not use retentive global DBs for safety-relevant setpoints. If a Modbus port number changes after a power cycle, the system should fault visibly, not silently reconnect to the wrong slave. Use the Setpoints pattern: an Input DB holds the default, an operator action copies it into the working DB on first scan, and a deliberate write is required to change it.
- HTTPS on the Web Server requires a CPU that supports it. S7-1200 CPUs from firmware V4.2 onward support secure Web Server. V4.0 and V4.1 only do HTTP — fine for commissioning on a closed laptop, never on a production network.
- PROFINET device names matter for replacement CPUs. If a CPU is replaced and the device name is not restored, the IO controller will not start IO data exchange. PRONETA can re-assign device names from a saved scan.
- The S7-1200 supports partial block downloads but not partial program-block downloads for blocks that have instance DBs in use. When changing an FB interface, TIA Portal will require a full download of the FB and all its instance DBs — plan a short stop, not a hot patch.
13. Related Standards and References
For deeper reading, the following official Siemens documents and standards apply:
- Siemens Industry Online Support — entry point for S7-1200 system manuals, TIA Portal help, HSP downloads, and the S7-1200/1500 Programming and Style Guide.
- SIMATIC S7-1200 product page — article numbers, firmware matrix, and module-level specifications.
- SIMATIC TIA Portal product page — version compatibility and licensing.
- Siemens PRONETA product page — PROFINET commissioning and diagnostics tool.
- PROFIBUS Nutzerorganisation e.V. (PNO) — PROFINET Installation Guide for cable, topology, and grounding rules referenced by the TIA Portal topology editor.
Frequently Asked Questions
Should I store the CPU's own IP address in the TIA project or in a data block?
Store it in the data block only — but more precisely, do not store it in the offline project at all. Assign the CPU's IP via PRONETA, TIA Online & Diagnostics, or the Web Server at commissioning time. The offline project then compiles once and downloads identically to every CPU in the fleet.
What is the difference between a master copy and a type in the TIA Portal global library?
A master copy is a frozen reference; updates must be applied manually to each instance via right-click → Update. A type is a master copy flagged with “Use as type”; TIA Portal auto-propagates updates to every instance on next compile or project open. Use types for any FC/FB/UDT/PLC tag table that you want to keep in lockstep across the fleet.
Can I share a Unified HMI screen across multiple PLCs in the same project?
Yes. Store the screen in the global library as a type. For each PLC, drop the screen into the HMI project and re-bind the HMI connection and the tag prefix to that PLC's instance of the shared data block. The screen code is identical; only the symbol binding changes.
How do I push a bug fix in a global library FC to every PLC station?
Edit the FC inside the library, save, and reopen every project. TIA Portal flags each instance with a yellow badge. Run “Library → Synchronize” on each station, compile, then download only the changed blocks via Online → Download to device → “Software (only changes).” Plan a stop of less than 200 ms on the S7-1200.
Why is M-memory discouraged on S7-1200 for shared programs?
M-memory (%MB, %MW, %MD) is emulated in a hidden system data block on S7-1200/1500, which bypasses the optimized block fast path and hurts scan time at scale. More importantly, M-memory addresses are project-local: they cannot be library-typed and will silently drift between stations. Replace every %M usage with a symbolic tag in a shared DB with optimized access.