Overview: S7 Project Architecture in TIA Portal V16
When commissioning an S7-1200 or S7-1500 controller, the choice of how I/O is scanned, how symbols are organized, and how Data Blocks (DBs) are allocated determines long-term maintainability. TIA Portal V16 (and the V16 SP1 update released January 2021) introduces additional options for symbolic structuring, multi-instance block calls, and dynamic symbol re-binding that are not available in the classic STEP 7 V5.x range. Before applying any pattern, identify the controller family because addressing semantics differ between the classic range (S7-300/S7-400 with STEP 7 V5.x) and the current range (S7-1200/S7-1500 with TIA Portal). The recommendations below apply to the current range; legacy notes are provided where behavior diverges.
Three structural decisions must be made up front:
- Whether to consume the I/O through the automatic process image (PII/PIQ) or to read/write directly via peripheral access (PEW/PAB) inside the user program.
- Whether to centralize tag names in a PLC tag table, in a global DB, or in User-Defined Data Types (UDTs/PLC data types).
- Whether function blocks (FBs) are called as single-instance (each FB gets its own background DB) or as multi-instance (FBs share one parent instance DB).
The Siemens S7-1500 system manual, the S7-1200 system manual, and the TIA Portal programming and operating manual provide the full reference for the rules summarized here:
- S7-1500 Automation System System Manual
- S7-1200 Programmable Controller System Manual
- S7-1500 Programming and Operating Manual (S7-1500/ET 200MP)
- SIMATIC TIA Portal V16 Manuals Collection (SIOS)
- STEP 7 Basic/Professional V16 in TIA Portal - Function Manual
Prerequisites
- TIA Portal V16 (or V16 SP1) installed; the matching firmware version on the S7-1500 CPU is V2.6.x or higher. See the S7-1500 CPU firmware update description for supported combinations.
- Configured device network: S7-1500 CPU and any distributed I/O (ET 200SP, ET 200MP, SINAMICS drives, third-party PROFINET devices) on the same PROFINET subnet.
- PLC tag table created automatically by TIA Portal from the hardware configuration. To reach the editor: Project tree → PLC_x → PLC tags → Default tag table.
- A working watch table for verification: Project tree → PLC_x → Watch and force tables → Add new watch table.
I/O Scanning Behavior in S7-1200 and S7-1500
By default, the local I/O of an S7-1200/1500 CPU is updated synchronously with the OB1 cycle. The CPU copies the physical inputs into the Process Image of the Inputs (PII) at the start of OB1 execution, and writes the Process Image of the Outputs (PIQ) back to the physical outputs at the end. This decouples the application program from the duration of the physical I/O update and gives deterministic scan semantics.
| Update mode | Trigger | Typical use |
|---|---|---|
| Automatic (default) | OB1 cycle start/end | Standard I/O reads/writes; deterministic |
| Hardware interrupt | OB40 - OB47 (rising/falling edge of channel) | Fast reaction to a single digital event outside OB1 |
| Time-of-day interrupt | OB10 - OB17 (configurable time/date) | Scheduled actions; daily/monthly tasks |
| Synchronous cycle interrupt | OB61 - OB64 (PROFIBUS/PROFINET isochronous) | Closed-loop control loops; isochronous drive coupling |
| Direct peripheral access | PEW/PAB read inside user program | Reading latest value of a slow input from an interrupt OB |
You can override the default in the device configuration: Devices & networks → CPU → Properties → Process images → Overview. The "Update of the process image" column accepts three settings per I/O region:
- Automatic update — the CPU refreshes the area on every OB1 cycle. Default for the first 1024 bytes on the S7-1500.
-
Manual update — the application program is responsible for refreshing the area using the system function block
UPDAT_PI(update PII) orUPDAT_PO(update PIQ). Use this for I/O areas accessed only from interrupt OBs. -
No update — the area is excluded from the automatic process image. Reads must use direct peripheral access:
%IW0:P(input word, peripheral) or%QW0:P(output word, peripheral). The:Psuffix is the TIA Portal syntax for direct access.
Is I/O Mapping Mandatory?
In the classic range, I/O mapping was effectively mandatory because the only way to keep the program readable was to mirror the raw addresses (I0.0, Q4.1, IW64, QW80) into a DB and operate only on the mirrored tags. In the current range, TIA Portal's symbolic I/O capability makes explicit I/O mapping optional in most cases.
Symbolic I/O works because TIA Portal treats the address %I0.0 as both an absolute and a symbolic tag. The symbolic name (for example CONVEYOR_START_PB) is edited directly in the PLC tag table and is updated everywhere in the program when reassigned. Re-mapping an input to a different terminal block is therefore a single-line edit in the tag table, not a project-wide search-and-replace.
I/O mapping into a Data Block is still valuable in three situations:
-
Repeated structures — a bank of identical drives, valves, or I/O slices. A
DB_MAPPING_DRIVEcontaining an array of UDTs is easier to scale than a flat tag table. - Forcing time-updated I/O into scan-cycle semantics — if a hardware interrupt OB reads direct peripheral access, copy the value into a DB variable that the OB1 cycle can consume deterministically.
- Cross-program exchange — the HMI, the SCADA OPC UA server, and a remote CPU exchange values through a named DB rather than through overlapping tag tables.
Data Block Architecture: Global, Instance, and Multi-Instance
DBs in S7-1200/1500 fall into two physical categories, each generated by a different code path in TIA Portal:
| DB type | Created by | Retention | Typical use | |
|---|---|---|---|---|
| Global DB | Programmer (manually) | Optional per tag | Yes (recommended) | Recipes, HMI faceplates, status aggregation |
| Instance DB (single-instance) | Compiler when FB is called as a standalone instance | Optional per tag | Yes (recommended) | One FB call uses its own DB |
| Instance DB (multi-instance) | Compiler when FBs are declared as static variables of a parent FB | Follows parent | Yes (recommended) | Modular code: many FBs share one parent DB |
To enable optimized block access, open the DB or FB editor, right-click the block in the project tree, choose Properties → Attributes, and tick Optimized block access. Optimized blocks store only the tags that are actually used, eliminate type-alignment padding, and unlock retentive tag granularity.
Global DB example: HMI faceplate parameters
The pattern for an HMI faceplate is a global DB whose tags are exposed to WinCC Unified/Professional through the HMI tag connection. The DB holds the parameters and status of one device; the HMI references the same DB tags symbolically:
// DB "DB_HMI_Pump_01" - optimized block access, retentive for setpoints
TYPE "UDT_Pump_Params"
VERSION : 0.1
STRUCT
SpeedSetpoint_RPM : Real; // 0.0 .. 3000.0
SpeedActual_RPM : Real; // 0.0 .. 3000.0
Current_A : Real; // 0.0 .. 999.9
RunRequest : Bool; // command from HMI
FaultActive : Bool; // status to HMI
OpHours : DInt; // hours, retentive
END_STRUCT;
END_TYPE
DATA_BLOCK "DB_HMI_Pump_01"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
NON_RETAIN
Pump : "UDT_Pump_Params";
The HMI then binds to DB_HMI_Pump_01.Pump.SpeedSetpoint_RPM symbolically. With optimized access, the tag does not occupy a fixed offset, so reordering the UDT members later does not break the HMI connection as long as the symbol names are preserved.
Multi-instance pattern for modular code
A multi-instance call embeds the FB as a STATIC variable of a parent FB. The parent FB holds one DB; all child FBs share that DB. This is the canonical pattern for repeated function blocks — for example, ten motor starters in a single DB:
FUNCTION_BLOCK "FB_MotorStarter"
VERSION : 0.1
VAR_INPUT
Start : Bool;
Stop : Bool;
Overload : Bool;
END_VAR
VAR_OUTPUT
Running : Bool;
Fault : Bool;
END_VAR
VAR
State : Int; // 0=Idle, 1=Starting, 2=Running, 3=Stopping
T_Start : TON; // on-delay instance, multi-instance
END_VAR
BEGIN
// latching start logic, overload trip, etc.
END_FUNCTION_BLOCK
FUNCTION_BLOCK "FB_MCC_TenMotors"
VERSION : 0.1
VAR
M1 : "FB_MotorStarter"; // multi-instance, no separate DB
M2 : "FB_MotorStarter";
M3 : "FB_MotorStarter";
M4 : "FB_MotorStarter";
M5 : "FB_MotorStarter";
M6 : "FB_MotorStarter";
M7 : "FB_MotorStarter";
M8 : "FB_MotorStarter";
M9 : "FB_MotorStarter";
M10: "FB_MotorStarter";
END_VAR
END_FUNCTION_BLOCK
Calling FB_MCC_TenMotors once in OB1 generates a single instance DB IDB_MCC that contains all ten motor starters. Memory consumption is lower than ten independent instance DBs because the multi-instance shares headers, and the online view groups all starters under one parent block for diagnostics.
User-Defined Data Types (UDT) in TIA Portal V16
TIA Portal renamed the UDT concept to PLC data type. The two terms are equivalent. A PLC data type lives in Project tree → PLC_x → PLC data types and can be referenced by any DB, FB, or FC. In V16, PLC data types support:
- Nested structures (a UDT containing another UDT)
-
ARRAYof UDTs with explicit bounds, e.g.ARRAY[1..32] OF "UDT_Valve" - Direct HMI binding; the HMI imports the UDT and binds once to the array, propagating to all elements
- OPC UA exposure: the S7-1500 OPC UA server can publish a UDT as a complex data type
Use a UDT when three or more instances of the same logical structure exist. Below four, the marginal complexity of a UDT outweighs the benefit.
HMI Communication Block Pattern
It is common to see a dedicated DB named DB_HMI or DB_Communication in S7 projects. This is a global DB whose only purpose is to expose the values the HMI needs. A clean pattern groups all HMI data into one DB per HMI panel, with sections divided by UDTs:
DATA_BLOCK "DB_HMI_MP277"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
NON_RETAIN
STRUCT
System : "UDT_SystemStatus"; // 32 bytes
Motors : ARRAY[1..10] OF "UDT_MotorStatus"; // 10 * 64 bytes
Valves : ARRAY[1..32] OF "UDT_ValveStatus"; // 32 * 16 bytes
Recipes : ARRAY[1..20] OF "UDT_RecipeRecord"; // 20 * 128 bytes
END_STRUCT;
END_DATA_BLOCK
With this structure, the HMI imports DB_HMI_MP277.Motors as an array, and any tag added to the UDT propagates to all HMI screens automatically. Retention is set on the UDT elements that need to survive a CPU restart (for example Recipes[1].Parameters[5].Setpoint).
Recommended Program Block Layout
A typical S7-1500 project with TIA Portal V16 follows this block organization. The grouping is created with Program blocks → Add new group in the project tree:
| Group | Block | Type | Number / Naming | Description |
|---|---|---|---|---|
| OB - System | OB1 | Main cyclic | OB1 | Main scan, calls all program FBs |
| OB - System | Startup | Startup | OB100 | Warm restart / cold restart |
| OB - System | Time error | Error | OB80 | Catch cycle-time overrun |
| OB - System | Diagnostic | Error | OB82 | Module diagnostics interrupt |
| OB - System | Pull/plug | Error | OB83 | Module removal/insertion |
| OB - Hardware | Hardware interrupt | Interrupt | OB40 | High-priority digital event |
| OB - Cyclic | Cyclic interrupt | Time-driven | OB30 (or OB35) | 10–100 ms scheduled logic |
| FB - Process | Motor starter | Multi-instance | FB_MotorStarter | Single-motor logic, called as multi-instance in MCC FB |
| FB - Process | Valve actuator | Multi-instance | FB_Valve | Single-valve logic |
| FB - Process | Analog scaling | FC (no memory) | FC_ScaleAnalog | IEC 61131-3 standard scaling block |
| FB - Process | PID controller | FB (PID_Compact V2) | FB_PID | Built-in PID, called as multi-instance |
| FB - Aggregator | Motor control center | Multi-instance parent | FB_MCC_ZoneA | Holds M1–M10 multi-instances of FB_MotorStarter |
| DB - Data | HMI communication | Global | DB_HMI_Panel1 | Single HMI exposure point |
| DB - Data | Recipes | Global | DB_Recipes | Retentive recipe storage |
| DB - Data | System status | Global | DB_SystemStatus | Heartbeat, cycle time, last fault code |
| DB - Instance | MCC instance | Single-instance | IDB_MCC_ZoneA | Generated when FB_MCC_ZoneA is called from OB1 |
| UDT - Types | Motor status | PLC data type | UDT_MotorStatus | Repeated structure for all motors |
| UDT - Types | Valve status | PLC data type | UDT_ValveStatus | Repeated structure for all valves |
| UDT - Types | Recipe record | PLC data type | UDT_RecipeRecord | Recipe data layout |
Step-by-Step: Building a Clean Project in TIA Portal V16
- Configure hardware first. Drag the CPU, I/O modules, and any PROFINET devices into the network view. Do not write any program code until the hardware compiles successfully. This forces the PLC tag table to reflect the real I/O addresses.
-
Set process image defaults. Open CPU properties → Process images and decide for each I/O area whether it uses automatic, manual, or no update. For most digital inputs and outputs, leave the default. For analog inputs sampled in a hardware interrupt, switch to "Manual update" and call
UPDAT_PIin the OB40. -
Create PLC data types before DBs. Go to PLC data types, right-click, Add new data type. Build
UDT_MotorStatus,UDT_ValveStatus, and any other repeated structure first. This forces a clean separation between data shape and data instance. -
Create the HMI DB. Add a single global DB named
DB_HMI_Panel1with optimized access. Place anARRAY[1..N] OF "UDT_X"for each repeated entity that the HMI must show. -
Build function blocks. Add the FB for one motor starter. Use
VAR_INPUT,VAR_OUTPUT,VAR(static), andVAR_TEMPcorrectly. Enable optimized block access. Add a retain attribute onVARelements that need to survive restart (for exampleRunHours). -
Wrap FBs into multi-instance parents. Create
FB_MCC_ZoneAwith static instances ofFB_MotorStarter. InsideFB_MCC_ZoneA, expose each motor'sRunningandFaultto the HMI by writing toDB_HMI_Panel1.Motors[i]. -
Wire OB1. Open OB1, drag a single call to
FB_MCC_ZoneA. Pass symbolic tag names from the PLC tag table. Avoid absolute addresses in OB1; they should appear only in the FB input connections. -
Configure the HMI connection. In the HMI project, add a connection to the PLC. The HMI tag list should import
DB_HMI_Panel1once; the array members are then available as HMI tags. - Compile and download. Project tree → right-click PLC → Compile → Software (rebuild all blocks). Resolve any warnings before download. The most common warning is "Tag used but not assigned" caused by an I/O module not being mapped in the hardware configuration.
- Verify with a watch table. Create a watch table with the HMI DB tags, the OB1 cycle time, and one or two input bits. Trigger each input, observe the corresponding tag update. Force a few HMI tags to verify the data path both ways.
Verification Checklist
| Check | How to verify | Pass criterion |
|---|---|---|
| OB1 cycle time | Diagnostics → Cycle time → OB1 | Within 50% of configured max cycle time |
| Process image update | Force a digital input, observe PII value in watch table | Update within one OB1 cycle |
| Symbolic I/O | Rename a tag in the PLC tag table, recompile | No compiler errors; HMI tag updates automatically |
| Optimized block access | Right-click each DB/FB → Properties → Attributes | "Optimized block access" ticked |
| Multi-instance generation | Online → Blocks → right-click the parent FB → Open instance DB | Single instance DB contains all child instances |
| HMI binding | HMI project → HMI tags → Connection status | "Connected" and last update < 1 s |
| Retentivity | Online → Watch table → set value → CPU stop/run | Retentive tags keep value across stop/start |
Troubleshooting Matrix
| Symptom | Likely cause | Fix |
|---|---|---|
| Tag shows old value in HMI but correct in watch table | HMI update time too long; or array index out of bounds in the DB | Reduce HMI acquisition cycle to 100 ms; check array bounds in UDT |
| Output does not change despite PII bit set | Output forced; or "No update" set in process image | Release force from online → Force table; switch area to "Automatic update" |
| Compiler error: "Multi-instance requires optimized block access" | Parent FB still has standard block access | Open FB properties → Attributes → tick optimized block access → recompile |
| OB1 cycle time oscillates wildly | Unbounded loop or busy wait in FC; or oversized DB being copied every cycle | Profile the cycle with the trace function; remove whole-DB copies, use symbolic tag moves |
| Hardware interrupt OB does not fire | Channel not enabled in hardware configuration; or OB40 not present in project | Device → module → Properties → Inputs → enable hardware interrupt; add OB40 from the system blocks |
| OB82 diagnostic interrupt on every scan | Module is reporting a channel fault (broken wire, overload) | Read the diagnostic buffer: Online → Diagnostics → Diagnostic buffer; replace or repair the channel |
| Download fails with "Firmware version not compatible" | CPU firmware is older than the project was built for | Update the CPU firmware to the version listed in the TIA Portal compatibility matrix |
| Symbolic tag shows red in the program | Tag deleted from the PLC tag table; or address conflict | Right-click the tag → "Go to definition" to locate the orphan reference |
Performance and Memory Notes for S7-1500
The S7-1500 stores the program in work memory and loads blocks into load memory on demand. Optimized block access reduces the work memory footprint by storing only tags that are actually used. Multi-instance DBs reduce the per-instance header overhead and can cut instance-DB memory by 30–50% when many small FBs are used. PLC data types and arrays of PLC data types are stored as contiguous blocks and are cached as a whole, which is faster than reading individual DB members from a non-optimized DB.
For a project with approximately 50 motors, 100 valves, and 30 analog signals, a typical optimized project consumes 200–300 KB of work memory on an S7-1515-2 PN. The non-optimized equivalent of the same logic typically consumes 400–600 KB. Exact numbers depend on the number of FBs and the size of each UDT.
When to Re-introduce I/O Mapping into a DB
Re-introduce a mapping DB when any of the following appear:
- The HMI driver (for example, a legacy WinCC flexible 2008 tag import) cannot bind symbolically and requires fixed offsets.
- A third-party OPC UA client reads the data as a flat namespace and cannot traverse nested UDTs.
- The project is being re-engineered from a STEP 7 V5.x project with a fixed DB layout, and the conversion tool generates a mapping DB to preserve offset compatibility.
- A regulator or FAT test procedure references a specific absolute DB offset (for example, "DB200.DBX4.0 = command").
Field-Commissioning Procedure
- After hardware commissioning, download the project with PLC in Stop state.
- Open the watch table; force each output off first, then sequentially enable outputs and verify the physical actuator.
- Run the OB1 in single-step mode (online → Block → Single-step) and verify the program flow. Note the cycle time in the diagnostics buffer.
- Trigger each hardware interrupt source; verify the corresponding OB40..OB47 fires by checking the OB count in the online diagnostics.
- Pull one PROFINET module; verify OB83 (pull/plug) fires. Re-insert and verify the module returns to operation without a CPU restart.
- Trigger a diagnostic fault on one channel; verify OB82 fires and that the diagnostic buffer records the channel with the correct slot and channel number.
- Set a recipe value in
DB_Recipes; stop the CPU, then run; verify the value persists.
FAQ
Does TIA Portal V16 scan local I/O synchronously with OB1 by default?
Yes. On S7-1200 and S7-1500 CPUs, the local I/O of the first 1024 input and output bytes is automatically updated at the start and end of OB1. The default can be changed in the device configuration under Process images → Update of the process image, with options for automatic, manual, or no update.
Is an I/O mapping Data Block required like in older Siemens projects?
No. TIA Portal's symbolic I/O lets you assign names to addresses in the PLC tag table and rewire them at any time. An I/O mapping DB is useful only when repeated structures are needed, when an HMI or third-party client requires fixed offsets, or when converting a legacy V5.x project.
What is the difference between a single-instance and multi-instance Data Block?
A single-instance DB is created when an FB is called from OB1 or from another FB as a standalone instance. Each call gets its own DB. A multi-instance DB is created when an FB is declared as a STATIC variable of a parent FB; all child FBs share the parent's DB, which reduces memory use and groups diagnostics under one block.
Why are my multi-instance FBs not compiling in TIA Portal V16?
The most common reason is that the parent FB still has standard block access. Open the parent FB, go to Properties → Attributes, enable Optimized block access, recompile, and re-download. Multi-instance calls require optimized access on both parent and child FBs.
How do I expose a UDT to the HMI so all instances bind at once?
Declare an ARRAY[1..N] OF "UDT_X" in a global DB with optimized access. In the HMI tag editor, import that DB and the HMI will expand the array into N instances of the UDT. Adding a new member to the UDT later propagates the change to the HMI automatically as long as the HMI tag connection is symbolic.