Problem Overview
Siemens TIA Portal recipe synchronization is one of the most useful features for batch and parameter-set applications on SIMATIC HMI panels connected to S7-1200 and S7-1500 controllers. Operators select a recipe record on the HMI, the record's data records (DS) are downloaded from the HMI's internal memory or external storage medium, and the configured PLC tags are overwritten with the recipe values.
Engineers occasionally observe a partial element loading anomaly: when the operator selects a recipe record on the recipe view, only some of the configured elements appear in the PLC. Selecting the same record again "completes" the missing elements. The issue is reproducible — the same tags fail every time — but the failing tags themselves show no configuration difference from the working tags.
This article documents the root cause identified in field cases, the diagnostic path required to confirm it, and the engineering practices that eliminate the fault class entirely.
Affected Components and Versions
| Component | Affected Range | Notes |
|---|---|---|
| TIA Portal | V13 SP1 through V18 (and later) | Recipe engine behavior is consistent across SP/Update releases |
| HMI Runtime | WinCC RT Advanced / Professional / Unified | All HMI panels supporting recipes |
| PLC firmware (S7-1200) | V4.0 and later | Recipe tag pointers: %DB area only |
| PLC firmware (S7-1500) | V1.5 and later (optimized block access relevant) | Recipe tags can be DB members or symbolic tags |
| Connection | S7 communication (PUT/GET or HMI tags) | Behavior identical regardless of transport |
Symptom Signature
The observed behavior has a very specific signature that distinguishes it from genuine communication or configuration faults:
- Operator selects recipe record "Recipe_A" in the HMI recipe view.
- The HMI sends all element values to the PLC tags defined in the recipe configuration.
- A subset of tags — typically 30-70% — show the expected recipe values; the remaining tags keep their previous value.
- The HMI status indicators show "Synchronization complete" with no error code.
- Selecting the same record a second time writes the missing elements correctly.
- The failing subset is identical every time and does not depend on record selection order.
- The failing tags are configured identically to the working tags (same PLC tag type, same HMI tag mapping, same offset/length).
Root Cause: User-Program Array Reinitialization
Recipe synchronization in TIA Portal writes to PLC tags one at a time. The HMI runtime fires the configured "Synchronize" event in the recipe view, which triggers a write to each element tag in sequence. If the user's PLC program contains logic that reinitializes the recipe-tagged DB elements during the same scan, the later writes overwrite or get overwritten by user-program logic — depending on the order of execution within the OB1 / OB123 cycle.
The most common offenders in field cases are:
- Array initialization in nested FBs/FCs: A function block contains a temporary or static array that is conditionally reset (e.g., on a mode change, on a fault clear, or in an initialization routine). The reset call sits in a deeper layer of the call stack and re-executes every scan, even when the trigger condition is no longer active.
-
"Initialize on first run" code: Patterns such as
IF first_run THEN ... END_IF;wherefirst_runis a static bit that the programmer resets inadvertently inside the same FB or in a sibling FB. - Recipe DB reused as working memory: The same DB that holds the recipe tags is also used as scratch memory by the control algorithm. Writing to the DB from the algorithm overwrites the freshly downloaded recipe values before the operator reads them back.
- Edge-triggered resets on rising edges: A rising-edge detection block resamples an enable bit and triggers a one-shot reset of the recipe DB each time the operator touches a different screen.
Diagnostic Methodology
Confirming the root cause requires eliminating the configuration and runtime layers first. Follow this sequence before opening the user program.
Step 1 — Verify Recipe Configuration
- Open the HMI recipe in the project tree.
- Confirm every element has a valid PLC tag assigned (no empty "Tag" field).
- Confirm the tag's name resolves in the PLC tag table — no red "???" or unresolved entries.
- Open the recipe view's "Properties → Synchronization" and verify the trigger mode matches the operator workflow:
| Trigger Mode | Behavior | Use When |
|---|---|---|
| Manual via button | Sync only fires when the operator presses the configured button | Operator-driven recipes |
| On record load | Sync fires the moment a record is selected | Automatic parameter sets |
| On record save | Sync fires when writing back to the PLC | Two-way editing required |
| On screen change | Sync fires on every screen change | Multi-screen recipes |
Step 2 — Verify HMI Tag Update Mechanism
- Open HMI Tags in the project tree and locate the recipe's PLC tags.
- Confirm the Acquisition mode is "Cyclic in operation" or "Cyclic continuous" — not "On demand".
- Confirm the Update time is consistent with the recipe view's "Synchronize to PLC" trigger interval. A 2-second cycle combined with a 1-second trigger can drop writes.
- On S7-1200/S7-1500 connections, confirm the Mode is set to "Absolute access" for symbolic tags when using optimized blocks; otherwise the HMI uses absolute addressing which can clash with multi-instance DBs.
Step 3 — Reproduce in a Stripped Configuration
- Disable the user program (OB1 empty, all FBs/FCs un-called).
- Trigger the recipe download from the HMI.
- Confirm every element arrives at the PLC tag — read back via watch table or HMI tag view.
If all elements arrive correctly with the user program disabled, the user program is the cause. Re-enable user code block by block until the fault returns; the last re-enabled block contains the offending code.
Step 4 — Trace DB Writes
- Open the recipe DB in the project tree.
- Add a cross-reference (right-click → "Cross-references") to every recipe element.
- Inspect each assignment site. Any assignment whose right-hand side is a constant or an unrelated variable is a candidate for overwriting the recipe value.
- For S7-1500 with optimized blocks, enable watch table with a 100 ms trigger and step through a recipe download. The DB member that "flips back" immediately after the HMI write identifies the overwriting call.
Resolution Patterns
Pattern A — Move Initialization Out of Scan-Cycle Code
Reinitialization logic belongs in OB100 (warm restart), OB101 (hot restart), or a one-shot block called from OB100 — never in the cyclic OB1 path.
Before (faulty):
// In FB "ModeManager", instance DB "ModeData"
IF #bInitRequired THEN
#arrRecipeValues := 0; // zero array every time init flag rises
#bInitRequired := FALSE;
END_IF;
After (correct):
// In OB100 — runs once on restart only
FB_ModeManager(iInit := TRUE);
// In FB "ModeManager", instance DB "ModeData"
// Cyclic path no longer touches the recipe array
Pattern B — Use a Dedicated Recipe DB
Never mix the recipe tag DB with the working-memory DB. Define a strictly-named "DB_Recipe" or "DataDB_RecipeXY" and reference it only from the recipe configuration and the HMI. Application code reads from it but never writes.
// Application code — read-only access
iSetpoint := "DB_Recipe".Setpoint[1];
// FORBIDDEN — do not write back into the recipe DB
"DB_Recipe".Setpoint[1] := iSetpoint * 2; // <-- this overwrites HMI recipe data
Pattern C — Guard Recipe Memory with a Sync-Lock
Use a boolean tag bRecipeSyncActive that the HMI sets to TRUE before downloading and to FALSE after. Application code skips all writes to the recipe DB while the lock is held.
// Cyclic OB1 block
IF NOT "HMI".bRecipeSyncActive THEN
// safe to update working memory from recipe
IF "Mode".bAuto THEN
iSetpoint := "DB_Recipe".Setpoint[1];
END_IF;
ELSE
// HMI is writing — keep hands off
END_IF;
Configure the recipe view's "Synchronize" event to set the lock tag first (via a function list call) and reset it last.
Pattern D — Replace Nested FB Calls with Pass-by-Reference
If the offending code is an array reset deep inside a utility FB, refactor to pass the recipe DB slice by reference (S7-1500 with optimized blocks) or by VARIANT (S7-1200 V4.0+ and S7-1500). The caller controls when memory is initialized; deep FBs cannot silently overwrite caller memory.
// FB_Utility with VARIANT in/out
VAR_IN_OUT
arrRecipe : VARIANT;
END_VAR
// Initialization happens in caller, not in this FB
Code: Recipe Sync Trigger with Lock Pattern
The following Structured Text function list entry on the HMI side sets the lock tag, downloads the recipe, and clears the lock. Configure it under "Recipe view → Properties → Events → Synchronize".
// HMI function list (synchronous sequence)
"HMI".bRecipeSyncActive := TRUE; // Step 1: claim the recipe DB
WAIT_FOR_CYCLE(1); // Step 2: ensure PLC reads lock before writes
"Recipe_View".SynchronizeRecord(); // Step 3: transfer record from HMI to PLC tags
WAIT_FOR_CYCLE(1); // Step 4: settle one OB1 cycle
"HMI".bRecipeSyncActive := FALSE; // Step 5: release lock
VARIANT in VAR_IN_OUT is supported only with limited length. Verify against the S7-1200 system manual for your firmware.
Verification Procedure
- Apply the chosen pattern (A-D) and rebuild the project.
- Download the PLC program and HMI image to the runtime.
- Open a watch table covering every recipe DB member.
- Trigger the recipe download from the HMI recipe view.
- Within one second, verify every DB member matches the recipe record's defined values.
- Repeat the download five times; results must be identical each cycle.
- Cycle the PLC through STOP → RUN to confirm warm-restart behavior still initializes correctly.
| Test Case | Expected Outcome | Pass Criteria |
|---|---|---|
| Download record 1 in AUTO mode | All elements arrive, all tag values match the record | Watch table shows 100% match within 2 seconds |
| Download record 1 in MANUAL mode | All elements arrive | Watch table shows 100% match |
| Download while output is enabled | No PLC STOP, no OB1 cycle skip | Diagnostic buffer clean |
| Power cycle and warm restart | Initial recipe state is correct | Recipe DB matches expected defaults |
| Save modified values from PLC back to HMI | All elements round-trip correctly | HMI record matches PLC watch table |
| Network interruption during sync | HMI retries or aborts cleanly | No partial state in PLC |
Related Issues in the Same Class
The partial-load symptom belongs to a broader class of "HMI writes silently overwritten by user code" faults. Field engineers should review their application for the following siblings:
Symptom: Recipe values flicker back to zero after selection
Cause: A cyclic OB1 block assigns 0 to the recipe DB when a process value is out of range, regardless of recipe data.
Fix: Route the substitution value into a separate "EffectiveValue" DB, leaving DB_Recipe untouched.
Symptom: Only the last element of the recipe loads
Cause: User code contains a MOVE_BLK or BLKMOV instruction that copies the working memory over the recipe DB at the end of every scan.
Fix: Repoint the BLKMOV source to a buffer; never use the recipe DB as the destination of a cyclic block move.
Symptom: Recipe loads only when the HMI is the only client
Cause: Another HMI or OPC UA client is also writing the same tags. The user sees "partial" data because both clients race.
Fix: Audit all write clients via the project's cross-reference. Restrict recipe tag ownership to a single HMI panel.
Symptom: Recipe loads correctly offline, fails online
Cause: The PLC is online with a different project than the HMI. Tag offsets diverge, and writes land in adjacent memory.
Fix: Verify with Online → Compare Offline/Online. The mismatch must be resolved before recipe operations are reliable.
Prevention: Coding Standard for Recipe DBs
- Name every recipe DB with the prefix
DB_REC_orRECIPE_so cross-references surface them immediately. - Mark every recipe DB member with the attribute "Write-protected from HMI" (S7-1500 optimized block attribute) — this enforces pattern B at the engineering-tool level.
- Code-review checklist: any
:=assignment to aDB_REC_member outside the HMI is a defect. - Use Know-How Protection on user FBs that contain initialization logic; the next engineer to maintain the program will see the protected block and be prompted to read the documentation.
- Add a comment block above every recipe DB declaration explaining which HMI recipe owns it.
- When using recipe records on SD card or USB, verify the file system path matches the HMI's project setting — mismatches can produce the appearance of partial loads because the HMI silently truncates a missing file.
Diagnostic Tree
+-- Recipe download partial? --+ | | YES NO | | v (look elsewhere) +-- Disable user program: OB1 empty, no FB calls | | | +-- Download complete? --+ | | | | YES NO | | | | v v | User program is the Recipe config / HMI tag | cause (you are here) configuration is the cause | | | v | Inspect recipe element | list, acquisition mode, | update time, connection | | | v | Compare offline/online; | verify symbolic resolution | v Re-enable FBs one at a time; last re-enabled FB that breaks sync is the offender. Inspect for: - array reset in cyclic path - one-shot init that re-triggers - MOV/BLKMOV into recipe DB - sibling FB writing the same area v Apply pattern A, B, C, or D; rebuild and verify.
When the Fault Is Genuinely Communication-Related
If the diagnostic tree above does not place the cause in user code, consider the following transport-layer faults. Each has a different signature from the partial-load case:
| Transport Symptom | Distinctive Signature | Likely Fault |
|---|---|---|
| No elements load | HMI shows communication error, red triangle on tag | Connection configuration, IP/subnet mismatch, PG/PC interface issue |
| All elements load but values are wrong | Watch table shows scrambled or offset values | Data type mismatch (INT vs REAL, BYTE vs WORD) |
| Random elements load, not reproducible | Different tags fail each cycle | Update-time too long, HMI tag cycle > recipe trigger |
| All elements load but only after delay | Tags settle 5-30 seconds after selection | Acquisition mode is "On change" or "On demand" |
| Recipe download aborts halfway | HMI shows error code 13xxxx | CPU in STOP, secure communication misconfigured |
FAQ
Why does the HMI show "Synchronization complete" when only some tags loaded?
The HMI runtime reports synchronization status based on whether every write call was dispatched to the S7 driver — not whether the PLC accepted the value. If the PLC program overwrites the recipe tag in the same OB1 scan that the HMI writes it, the HMI's write still succeeded at the driver layer. The "complete" status therefore does not prove the PLC retained the value; verify with a watch table on the PLC side.
How can I tell whether the fault is in the HMI, the PLC, or the connection?
Disable the user program (empty OB1) and trigger the recipe download. If all elements arrive, the user program is the cause. If elements still fail, compare the offline project against the online runtime, then inspect the HMI tag's acquisition mode and update cycle. The connection itself is the cause only when the HMI shows a communication error code; partial-element loading without error codes almost always points to user code.
Is there a TIA Portal option to retry a failed synchronization?
Yes. In the recipe view's "Properties → Synchronization" you can enable "Resync on next screen change" or wire the "SynchronizeRecord" function into a function list triggered by a button. For unattended recovery, configure a script on the Unified HMI that watches a "RecipeSyncFault" tag and re-triggers SynchronizeRecord() when set.
Can optimized-block access on S7-1500 cause partial recipe loads?
Optimized block access itself does not cause partial loads, but it changes the cross-reference behavior. If the recipe DB is declared with "Optimized block access" and the HMI accesses tags by absolute address, mismatched offsets can look like partial loads. Always use symbolic access for recipe tags on S7-1500 firmware V2.0 and later; verify in the HMI tag's properties that the access mode is symbolic.
What TIA Portal version first introduced the recipe-synchronization event lock pattern?
The lock-tag pattern is an application-level technique and works on every TIA Portal version that supports recipe tags — V11 SP2 and later. WinCC Unified added native recipe-lock semantics in V16; the legacy pattern described in this article remains the recommended portable solution for mixed-version fleets.