Resolving TO_Axis vs DB_ANY Errors in TIA Motion Control FBs

David Krause16 min read
SiemensTIA PortalTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Problem Overview

When encapsulating MC_Power, MC_MoveJog, MC_MoveAbsolute, or any other PLCopen motion control function block inside a user-defined Function Block (FB) on a SIMATIC S7-1200 (for example CPU 1214C DC/DC/DC or CPU 1214FC) programmed with TIA Portal V15.1, the compile passes cleanly and the download to the target completes without complaint. Within seconds, however, the CPU's ERROR LED starts flashing red, the RUN LED goes dark, and the diagnostic buffer records an entry similar to:

Event ID 16#80B1
"Access error (data block type) DB1 in FB1 - Processing will continue (no OB processing)"

Cyclic OB execution is suspended. The CPU behaves as if a non-fatal class error has been promoted to a hard fault: a STOP->RUN transition, MRES, or power cycle is required to clear the state. The same MC blocks, when dropped directly into OB1, run perfectly. The fault is therefore not a motion problem, hardware problem, or wiring problem; it is a data-type problem introduced by the wrapper FB.

Symptom Stack

Layer Observed Behavior
Compile No error, no warning. Block consistency OK.
Download to target Transfer completes; RUN LED may briefly turn green.
CPU front panel ERROR LED flashes red; RUN LED off or flashing red.
Diagnostic buffer Event ID 16#80B1, text "Data block type mismatch" or "Access error (data block type)".
Online & Diagnostics Class "Programming error", OB1 halted, no further cyclic execution.
Axis Control Panel Disconnected — TO not reachable while CPU is in error state.
The diagnostic-buffer text "Processing will continue (no OB processing)" is misleading. The error is non-fatal in the sense that the firmware does not reset the CPU, but the cyclic program is suspended and a STOP->RUN transition (warm restart) is required. A power cycle is the most reliable recovery on S7-1200.

Root Cause: Datatype Mismatch

The PLCopen motion control FB family on S7-1200 is generated from the Siemens technology-object runtime. Every MC block exposes an Axis input typed as a derived User-Defined Type based on the abstract UDT TO_Axis. The hierarchy, as compiled into the motion control library, is:

TYPE TO_Axis
  // abstract base, contains common fields:
  //   VersionNumber, InternalToInterface, etc.
END_TYPE

TYPE TO_PositioningAxis EXTENDS TO_Axis
  // positioning-specific fields:
  //   Position, Velocity, StatusWord, ErrorWord, ...
END_TYPE

TYPE TO_SpeedAxis EXTENDS TO_Axis
  // speed-only fields:
  //   Velocity, StatusWord, ...
END_TYPE

TYPE TO_ExternalEncoder EXTENDS TO_Axis
  // encoder fields:
  //   Position, StatusWord, ...
END_TYPE

When you drag a technology object from the project tree directly onto the Axis input of an MC block that lives in OB1, TIA Portal performs compile-time type resolution. The TO's instance-DB number is stored in the call environment together with its UDT fingerprint (a 16-byte version stamp at the start of the DB). The MC block's internal code dereferences the DB header, finds the expected UDT signature, validates it, and runs.

When the MC block is moved inside a wrapper FB and the wrapper FB declares an input of type DB_ANY, the connection becomes a generic DB-number reference. TIA Portal stores the DB number but loses the UDT fingerprint because DB_ANY is by definition untyped. At runtime, the firmware attempts to validate the block header as a TO_PositioningAxis (or whichever specific UDT is required), reads the version stamp at DBB 0..7, and finds the header of a regular instance DB rather than a technology object DB. The mismatch is logged as event 16#80B1 and the OB is suspended.

Why DB_ANY Feels Right but Is Wrong

DB_ANY is the correct datatype for passing an arbitrary instance DB to blocks such as DPRD_DAT, DPWR_DAT, PEEK / POKE, or the data-log instructions that need a DB number but no schema. Motion control FBs are not generic-data consumers; they are tightly coupled to the technology-object schema and require a UDT that matches the axis variant. The S7-1200 firmware performs a strict runtime check; there is no implicit conversion from DB_ANY to a UDT-typed reference.

Siemens S7-1200 Motion Control Architecture

Understanding why the firmware check exists requires a quick tour of the S7-1200 motion control subsystem. The relevant components are:

  • Technology Objects (TOs) — DBs with the UDT TO_PositioningAxis, TO_SpeedAxis, or TO_ExternalEncoder generated by the "Add new object" wizard under Technology objects > Motion Control in the TIA project tree.
  • MC Instruction Library — Blocks under Instructions > Technology > Motion Control, each typed against the specific TO UDT. The library is regenerated on each TIA Portal upgrade; the V15.1 library uses firmware target V4.3 and higher.
  • PTO / Pulse Train Output — Hardware interface (onboard CPU outputs or signal-board outputs such as SB 1222 DQ4) bound to the TO via the axis configuration editor. Up to four PTOs are supported on a CPU 1214, depending on the firmware version and signal-board configuration.
  • Axis Control Panel — Online commissioning tool that exercises jog, homing, and absolute moves without requiring any PLC code. Used to validate that the axis hardware and TO configuration are correct before connecting MC blocks.
  • Trace / Scope — TIA's built-in signal trace, capable of recording axis variables at 1 ms resolution on S7-1200 firmware V4.2 and higher.

Reference documentation: SIMATIC S7-1200 Motion Control V15.1 Function Manual; SIMATIC S7-1200 Programmable Controller System Manual (V15.1); PLCopen Technical Committee 2 — Motion Control.

Correct Resolution: Declare Inputs as TO_Axis

The fix is to declare the wrapper FB's axis input with the actual UDT that the MC block expects. There are three valid approaches. Pick the one that matches your code-reuse strategy.

Approach 1 — Use TO_Axis (Generic Axis)

Use the abstract base type when a single FB must work with positioning, speed, and external-encoder axes interchangeably.

  1. Open FB1 in TIA Portal.
  2. In the FB interface, change the input Axis_Name from DB_ANY to TO_Axis.
  3. Save and compile. The MC blocks inside FB1 accept the input because TO_PositioningAxis, TO_SpeedAxis, and TO_ExternalEncoder all inherit from TO_Axis.
  4. At the call site of FB1 in OB1, drag the technology object from the project tree onto the Axis_Name input. TIA Portal performs an implicit downcast to the correct UDT and the firmware check passes.

Example FB1 interface declaration in SCL (compiled output of the TIA Portal editor):

FUNCTION_BLOCK FB_AxisController
VAR
  AxisName      : TO_Axis;        // accepts any axis variant
  PowerInst     : MC_Power;
  MoveRelInst   : MC_MoveRelative;
  MoveAbsInst   : MC_MoveAbsolute;
  JogInst       : MC_MoveJog;
  ResetInst     : MC_Reset;
  bEnable       : BOOL;
  fDistance     : LREAL;
  fVelocity     : LREAL;
END_VAR

BEGIN
  PowerInst(Axis := AxisName, Enable := bEnable);
  // MoveRelInst(Axis := AxisName, Distance := fDistance, Velocity := fVelocity, Execute := bEnable);
  // MoveAbsInst(Axis := AxisName, Position := fDistance, Velocity := fVelocity, Execute := bEnable);
END_FUNCTION_BLOCK

Approach 2 — Use the Specific Axis Variant

If the FB is dedicated to a single axis type, use the more restrictive type. This enables compile-time type checks and prevents the FB from being wired to the wrong technology object class.

VAR
  AxisName : TO_PositioningAxis;   // restricts to positioning axes only
END_VAR

Attempting to connect a TO_SpeedAxis to this input produces a compile error in the message window: "The data types of the actual parameter and the formal parameter do not match." This is the safest pattern in machine-builder code where a wrapper FB is intended for one motion type.

Approach 3 — Multi-Instance via Static VAR (No External Input)

If only one axis is ever used inside FB1, declare the MC blocks as multi-instance statics in the FB's Static section, drag the technology object directly into each MC block's Axis input, and eliminate the external axis input altogether. This was the original workaround used to clear the error in the field report.

FUNCTION_BLOCK FB_AxisStatic
VAR
  PowerInst   : MC_Power;          // multi-instance, no external Axis input
  bEnable     : BOOL;
END_VAR

BEGIN
  PowerInst(Enable := bEnable);    // Axis wired directly to "Axis1" TO inside the block
END_FUNCTION_BLOCK

The TO reference is resolved at compile time inside the multi-instance's input. There is no DB_ANY indirection, so the runtime type check passes unconditionally. The cost is that the FB can only drive one specific axis; you cannot reuse it for "Axis2" without a project re-edit.

Why Multi-Instance Matters

Placing MC blocks in the static section of an FB creates a multi-instance. The instance DB created when FB1 is called holds all of the MC block's internal data plus FB1's own static tags. The TO reference is resolved once, at compile time, inside the multi-instance's input. This is the recommended pattern for the S7-1200 and is documented in the TIA Portal help under Multi-instances in FBs.

Storage Class Resolution Mechanism Type Safety Multi-Axis Support
Multi-instance static Compile-time, in-block Strong (compile-time) One axis per FB call; use array of FBs for many
FB input typed as TO_Axis Compile-time, at call site Strong (compile-time + runtime UDT check) Yes — pass any axis at call time
FB input typed as specific UDT (TO_PositioningAxis) Compile-time, at call site Strongest (compile-time type match) Yes, but only matching axis variants
FB input typed as DB_ANY Untyped pointer at runtime None — fails MC block validation Yes, but broken
FB input typed as INT (DB number) Manual interpretation None Yes, but broken

FB Call Site Wiring

After the datatype change, OB1 wires the technology object to the FB input. Two wiring methods work:

  1. Drag-and-drop — Drag the technology object from the project tree (or from the "Technology objects" folder in the PLC tags) onto the FB instance's Axis_Name input. TIA Portal stores the full TO reference, including the UDT fingerprint.
  2. Symbolic assignment — Use the symbolic name of the TO in SCL or STL. The assignment operator resolves the TO at compile time.

Do not pass the absolute DB number (e.g. DB_ANY from a global DB of INT values) under any circumstance; this is the path that produces the original error.

Verification Procedure

  1. After the datatype change, perform a full compile of the S7-1200 station. The message window must show "0 errors, 0 warnings."
  2. Download the project in RUN mode. TIA will prompt to stop the CPU if the interface change requires it.
  3. Watch the CPU's ERROR LED — it must remain off.
  4. Open Online & Diagnostics > Diagnostic buffer. Confirm no new entries with event ID 16#80B1 or class "Programming error / Data block type mismatch".
  5. Place FB1 in OB1 with the technology object connected to the Axis_Name input.
  6. Set bEnable := TRUE via a watch table.
  7. Use the Axis Control Panel (or a MC_MoveJog instance) to verify the drive follows the command. Confirm MC_Power.Status = TRUE and MC_Power.Error = FALSE.
  8. Run a controlled move with MC_MoveRelative or MC_MoveAbsolute and verify the actual position matches the command within the configured positioning tolerance.
  9. Trigger an error scenario (e.g. disable the drive enable input on the drive side) and verify MC_Power.Error = TRUE and MC_Power.ErrorID reports a sensible motion-control error code.
  10. Recover with MC_Reset and confirm the axis returns to operable state.

Related Error Codes and Their Meaning

Event ID Meaning Typical Cause
16#0071 MC block internal error Axis not configured in TO tree
16#80B1 Data block type mismatch DB_ANY passed where TO_Axis expected (this article's root cause)
16#8090 TO not found / version incompatible TO deleted but reference remains; project upgraded from V13 SP1 without TO conversion
16#80A1 Axis already enabled by another MC_Power Two MC_Power instances point to the same TO
16#80C3 Axis not enabled (MC_Power.Status = FALSE) Power enable not asserted or hardware enable missing
16#80C4 Homing required Absolute move issued before homing or after restart
16#80C5 Homing in progress Move command issued while homing is active
16#80D0 Encoder value range overflow Modulo configuration error or high travel distance

Event IDs are taken from the S7-1200 Motion Control V15.1 Function Manual diagnostic-event table. The complete list runs from 16#8000 through 16#80FF; consult the manual for the full map.

Common Pitfalls and Edge Cases

  • Dropping the technology object into a tag of type INT. This compiles but produces a runtime crash identical to DB_ANY. Always use a UDT from the Motion Control palette.
  • Reusing the same FB instance DB across multiple MC blocks expecting different axis types. Mixing TO_PositioningAxis and TO_ExternalEncoder in the same instance is not supported and produces a UDT-incompatibility error at compile time only if you are lucky.
  • Forgetting to update the technology object DB number after copying FB code from another project. The DB number is project-scoped and must be regenerated or remapped through the project tree.
  • Using TIA Portal V13 SP1 or V14 projects without running the TO upgrade tool. The TO UDT hierarchy was reorganized in V15.0. Projects created in V13 SP1 with MC blocks require a one-time conversion via the "Upgrade technology objects" command under the project-tree context menu.
  • Calling the wrapper FB from a different priority class (e.g. OB35 cyclic interrupt) without re-evaluating motion semantics. MC blocks can be called from any OB, but the technology object's update tick is tied to the configured servo/POU cycle. Mismatched cycle times cause jitter or following errors.
  • Using a global DB field of type TO_Axis to share the axis between FBs. This works but creates a single global handle; calling two MC blocks that each expect exclusive ownership of the TO can lead to event 16#80A1 (axis already enabled).
  • Renaming a technology object in the project tree without updating the symbolic references. Symbolic references in SCL and the ladder editor follow the rename, but DB-number references stored in instance data do not. Use "Rewire" or "Compile all" after any rename.

Firmware Version Notes

The S7-1200 motion control subsystem has evolved across firmware versions. The behaviour described in this article is consistent from firmware V4.1 onward, with these notable milestones:

Firmware TIA Portal Relevant Change
V4.0 V13 SP1 Initial PLCopen Part 2 support; original TO UDT layout.
V4.1 V14 Improved diagnostics; clearer error messages for UDT mismatches.
V4.2 V14 SP1 Trace / scope at 1 ms for axis variables; new modulo configuration.
V4.3 V15 / V15.1 TO UDT hierarchy extended; S7-1200 supports up to 4 PTOs and 4 encoders.
V4.4 V16 ProDiag support for motion blocks; OPC UA exposure of TO variables.
V4.5 V17 Increased number of supported TOs to 12; enhanced torque-diminished homing.

The CPU 1214C originally shipped with firmware V4.0; current production is V4.4 or higher. Always check the firmware version in Online & Diagnostics > General before assuming a specific behaviour.

S7-1500 Differences

The S7-1500 motion control subsystem uses the same PLCopen FB interface and the same TO UDT concept, but with significant extensions:

  • TO counts — S7-1500 supports up to 32 axes on a CPU 1515 and up to 128 on a CPU 1518, compared with 4 to 12 on S7-1200.
  • Synchronous operations — S7-1500 supports cams, cam tracks, and the full PLCopen Part 4 synchronization profile. S7-1200 supports only Part 1 (single-axis motion) and a subset of Part 2 (electronic gearing).
  • Datatype handling — The same TO_Axis / TO_PositioningAxis / TO_SpeedAxis hierarchy applies. The fix described in this article transfers directly: declare wrapper FB inputs as the correct UDT and the runtime UDT check passes.
  • Axis alarms — S7-1500 exposes axis alarms in the PLC alarm view; S7-1200 returns the error via MC_xxx.ErrorID only.

If you are porting an S7-1200 program that contains the wrapper FB to an S7-1500, the FB interface does not need to change. The TO UDT is the same.

Array-of-Axis Pattern for High Axis Counts

For machines with many similar axes, an array of wrapper FB instances provides scalable, maintainable code. Declare an array of the wrapper FB and an array of TO references, then loop through the array in OB1:

VAR PUBLIC
  AxisController : ARRAY[1..4] OF FB_AxisController;
  AxisRefs       : ARRAY[1..4] OF TO_PositioningAxis;
  bEnable        : ARRAY[1..4] OF BOOL;
END_VAR

// OB1:
FOR i := 1 TO 4 DO
  AxisController[i](
    AxisName := AxisRefs[i],
    bEnable  := bEnable[i]
  );
END_FOR;

Each call of FB_AxisController uses a different element of AxisRefs. The compiler emits a multi-instance data block that contains all four FB instances plus their MC block statics, scaled by the array bound. This pattern is the recommended approach for indexing-based motion control and is documented in the TIA Portal help under FB multi-instances in arrays.

Hardware Variants and PTO Limits

The CPU 1214 family includes several hardware variants. The PTO count and encoder support depend on the variant and on whether a signal board is installed:

CPU Order Number (example) Onboard PTOs With SB 1222 Firmware at Delivery
CPU 1214C DC/DC/DC 6ES7214-1AG40-0XB0 4 4 (SB shared with onboard) V4.4
CPU 1214C DC/DC/Rly 6ES7214-1HG40-0XB0 4 4 V4.4
CPU 1214FC DC/DC/DC (fail-safe) 6ES7214-1AF40-0XB0 4 4 V4.4
CPU 1214C AC/DC/Rly 6ES7214-1BG40-0XB0 4 4 V4.4

The four onboard PTOs are fixed to specific output bytes. The signal-board PTOs share output resources with the onboard PTOs and must be configured under Device configuration > Pulse generators. If the project demands more than four axes, step up to a CPU 1215 or CPU 1217, or move to the S7-1500 platform.

Troubleshooting Matrix

Symptom Likely Cause Diagnostic Step Fix
ERROR LED red, 16#80B1 DB_ANY passed where TO_Axis expected Inspect FB interface in editor; check input datatype Change input to TO_Axis or specific UDT
Compile error "Data types do not match" Wrong UDT or generic INT Hover over the red squiggle in editor Use the specific TO UDT required by the MC block
ERROR LED red, 16#8090 TO deleted from project tree Compare project tree to FB interface Recreate TO or rewire FB to an existing TO
MC_Power.Status stays FALSE, no error Hardware drive enable missing Check drive wiring and configuration Enable drive-side enable input; check PTO wiring
Axis following error in trace Closed-loop tuning or mechanical binding Inspect trace recording of position vs command Adjust axis dynamics; verify mechanical installation
MC_Power.Error = TRUE after recovery Error condition not cleared Check MC_Power.ErrorID and ErrorInfo Issue MC_Reset after fixing root cause

FAQ

What does the "Access error (data block type)" diagnostic message mean on an S7-1200?

It means the firmware tried to interpret a data block as a UDT that does not match the block's actual type. In motion-control FBs this almost always traces to a DB_ANY input where a TO_Axis is required. The error is event ID 16#80B1 and halts OB execution until a STOP->RUN transition.

Can I pass a technology object to a function block using DB_ANY?

No. MC_Power and the other PLCopen MC blocks are compiled against the TO UDT and perform a runtime type check. Use TO_Axis, TO_PositioningAxis, TO_SpeedAxis, or TO_ExternalEncoder as the FB input type. DB_ANY strips the UDT fingerprint and breaks the check.

Why does MC_Power work in OB1 but not inside my wrapper FB?

When the block sits in OB1, the technology object is wired directly and the type check is resolved at compile time. Inside a wrapper FB, the input is a parameter and must be declared with a UDT that survives the indirection. DB_ANY loses the UDT fingerprint and the runtime check fails.

Do I need a separate instance DB for each FB that contains MC blocks?

Yes. Each call of the wrapper FB must have its own instance DB (single-instance or multi-instance) so that the MC blocks' static tags do not collide. Multi-instance statics inside the FB share the parent instance DB and are the recommended pattern. Arrays of FBs in a multi-instance DB scale to many axes without DB explosion.

Which TIA Portal version introduced the strict TO_Axis type check?

The behaviour has been in place since S7-1200 motion control V4.1 firmware, paired with TIA Portal V14. TIA Portal V15.1 enforces it at compile time and surfaces clearer diagnostic messages compared to V13 SP1, where the error often appeared as a generic "OB processing error" without a clear pointer to the data type.

Back to blog