Overview: Dual-Encoder Position Control in SIMOTION
Many high-precision machine applications require the position control loop to close on the load-side encoder while the velocity control loop continues to operate on the motor-side encoder. This configuration compensates for mechanical compliance, backlash, belt stretch, gearbox windup, and torsional deflection that would otherwise degrade accuracy if only motor-side feedback were used. SIMOTION supports this scenario natively through the Technology Object (TO) Axis, which accepts up to three encoder channels, and through Axis Data Sets (ADS) that allow runtime selection of the active encoder for the position controller.
This reference covers the engineering steps in Siemens Industry Online Support documentation and SCOUT/SCOUT TIA, the system-function programming required for deterministic runtime switching (_setAndGetEncoderValue() with CommandID), and the commissioning checks used to verify that the load-side position loop is stable, accurate, and free of following-error excursions when the data set is switched.
System Architecture and Component Model
A typical load-side controlled axis consists of the following elements:
- SIMOTION controller (SIMOTION D4x5/D4x5-2, P320/420, or C240/C240 PN) running the motion control runtime.
- SINAMICS S120 drive line module and motor module connected over PROFINET IRT or PROFIBUS DP with PROFIdrive telegram (typically telegram 3, 5, or 103/105).
- Motor-side encoder (Encoder 1): incremental, sin/cos 1 Vpp, EnDat 2.1/2.2, resolver, or SSI; processed in the Sensor Module (SMCxx or SME2x) of the SINAMICS.
- Load-side encoder (Encoder 2): mounted on the machine output, coupled directly to the load (ball screw, rack, conveyor, robot link, etc.). This encoder is routed to a free SMC/SME slot and exposed as a second encoder word in the PROFIdrive telegram, or to a TM (Terminal Module) connected to the SIMOTION.
The transmission ratio between motor and load is stored in the Axis TO configuration under LoadGear.Numerator / LoadGear.Denominator and LoadGear.Reverse. For a 1:1 ratio the value is 1:1 with reverse direction set as required by the mechanical layout.
Prerequisites
Before starting the configuration, confirm the following:
- SCOUT (or SCOUT TIA) is installed at a version compatible with the SIMOTION runtime. SIMOTION V4.5/V5.x engineering is required for the latest Axis TO features.
- The SIMOTION project compiles cleanly and the Axis TO already exists with the motor-side encoder configured and tuned.
- Encoder 2 is wired to an SMC/SME or TM and visible in the topology (online diagnostics should show the encoder as OK).
- The PROFIdrive telegram configured on the drive has two encoder words (telegrams 5, 105, 6, 106, or explicit 860/861 configuration) so that G1_XIST2 and G2_XIST2 are both available.
- The PLCopen or MCC program for the axis is paused or in a safe state so that configuration changes can be downloaded.
Step 1: Add the Load-Side Encoder in the Axis TO
Open the Axis TO configuration in SCOUT and navigate to the Encoder subsection. Three encoder slots are available per axis.
- Select Encoder 2 in the list view.
- Assign the encoder type (Incremental, Absolute SSI, EnDat, etc.) and the corresponding Sensor Module address.
- Set the resolution to the load-side encoder's actual line count or singleturn bits (e.g. 20-bit singleturn EnDat → 1048576 increments/rev).
- Enter the mechanical adaptation values:
Adaptation factorfor line counts per motor revolution when gearing differs, or set to 1 for 1:1 load transmission. - Configure the reference mark handling, error reaction, and zero-mark evaluation per application requirements.
- Download the configuration to the SIMOTION and verify that Encoder 2 reports a non-zero, stable actual value while manually jogging the axis slowly.
Step 2: Create a Second Axis Data Set (ADS)
An Axis Data Set contains a complete set of axis parameters including the active encoder number. The default data set (typically ADS 0) uses Encoder 1; create ADS 1 (or ADS 2) for load-side control.
- Open the Axis Data Sets dialog of the Axis TO.
- Click Add to create a new ADS. The new data set inherits the parameters of the active data set; review and adjust.
- Set
EncoderNumber := 2in the new ADS. - Confirm the controller data set (CDS) and motor data set (MDS) selections are appropriate. Typically MDS is unchanged because the motor is the same; CDS may differ to allow different controller gains for the load-side loop.
- Repeat the following error limits, positioning window, and position controller Kp/Kv values. For a load-side loop the proportional gain is usually slightly lower and the integral action slower, because the mechanical plant has more inertia and compliance.
- Set the active ADS to the desired start-up data set (typically ADS 0 with motor-side encoder) before download.
| Parameter | ADS 0 (Motor-side) | ADS 1 (Load-side) |
|---|---|---|
| EncoderNumber | 1 | 2 |
| ControllerDataSet | CDS 0 | CDS 1 (or 0) |
| MotorDataSet | MDS 0 | MDS 0 |
| PositionController.Kp | 1.0 (tuned) | 0.8 - 1.0 (re-tune) |
| PositionController.Kv | 1.0 | 1.0 - 2.0 |
| FollowingErrorWarning | 0.05 rev | 0.05 rev (load-side) |
| PositioningWindow | 0.01 rev | 0.01 rev (load-side) |
Step 3: Configure the Control Loop Structure
SIMOTION Axis TO uses a cascaded structure: current loop → velocity loop → position loop. The position loop accepts only one encoder at a time (selected by EncoderNumber in the active ADS), while the velocity loop can be configured to use either the same encoder or, alternatively, a different encoder through the VelocityEncoder configuration (available in SIMOTION V4.4 and later).
For the case described in the source — speed control on motor encoder, position control on load encoder — set the following in the Axis TO configuration:
-
VelocityEncoder = ENC_MOTOR (Encoder 1)— set in the Axis TO's velocity control section. The velocity controller reads from Encoder 1 regardless of the active ADS. -
PositionEncoder = ENC_ACTUAL_ADS— position controller reads from the encoder selected by the currently active ADS (Encoder 1 in ADS 0, Encoder 2 in ADS 1).
VelocityEncoder is not visible in the Axis TO dialog, the project is on a runtime that derives velocity from the position-control encoder. In that case, the velocity loop will follow the position loop's encoder; the speed controller will close on the load encoder when the load-side ADS is active. For most machine tools and dynamic axes, this is acceptable because the load is the controlled variable.Step 4: Programmatic Runtime Switching
Switching ADS at runtime is the recommended path. The function block _setAndGetEncoderValue() from the SIMOTION system library provides a controlled, command-oriented transition.
ST Example: Switch to Load-Side Encoder
// Switch position control to load-side encoder
VAR
fbEncoderSet : _setAndGetEncoderValue;
udCommandId : UDINT;
dActualPos : LREAL;
bDone : BOOL;
bBusy : BOOL;
bError : BOOL;
wErrorId : WORD;
END_VAR
// Trigger the switch
fbEncoderSet(
Axis := Axis1, // axis reference
EncoderNo := 2, // 2 = load-side
SetValue := FALSE, // do not set absolute value
GetValue := FALSE, // no read back of value
CommandId := udCommandId, // out: tracking ID
Done := bDone,
Busy := bBusy,
Error := bError,
ErrorId := wErrorId
);
IF bDone THEN
// Switch ADS to 1 (load-side data set)
Axis1.AxisDataSetControl := ADS_1; // user-defined enum
Axis1.AdsSwitch(); // explicit switch FB call
END_IF;\code>
Why CommandID Is Required
The field report explicitly notes that without a unique CommandID the caller cannot reliably determine when _setAndGetEncoderValue() has completed. SIMOTION system functions are asynchronous; the busy/done bits must be observed until Done = TRUE. Persist the latest CommandId in a project-global UDINT tag so that re-entrant calls do not collide.
Recommended Pre-Switch Sequence
- Stop the axis:
Axis1.Stop()and wait forStandstill = TRUE. - Set
VelocityEnable = FALSEto drop the speed controller output. - Call
_setAndGetEncoderValue(EncoderNo := 2, ...)to inform the Axis TO of the upcoming encoder swap. - Wait for
Done = TRUE(orError = TRUEwith evaluation ofErrorId). - Switch ADS via the Axis Data Set control mechanism.
- Re-enable the axis:
VelocityEnable := TRUEand clear any following-error latches. - Resume motion commands.
Step 5: Verify Position Reference Between Encoders
When switching from motor-side to load-side feedback, any difference in absolute position reference manifests as a step in following error at the instant of the switch. Eliminate the step through the following procedure:
- Reference both encoders to a common machine zero (use the homing routine once with Encoder 1 active, then switch ADS and re-reference with Encoder 2 active, comparing absolute positions).
- Compute the offset:
dOffset = ActualPosEncoder1 - ActualPosEncoder2. - Configure this offset in the Axis TO under
PositionOffset.Encoder1ToEncoder2(parameter name varies by runtime; in SCOUT it appears in the Encoder configuration under Adaptation/Offset). - Verify by switching ADS at standstill and confirming the following error remains within the positioning window without a visible step in the trace.
Step 6: Commissioning and Verification
After the project has been downloaded and the controller is running:
- Open the Axis Trace in SCOUT for the affected axis. Record the following signals simultaneously: PositionSetpoint, PositionActualEncoder1, PositionActualEncoder2, VelocitySetpoint, VelocityActual, FollowingError, AxisDataSetActive.
- Jog the axis at a low velocity (e.g. 5% of Vmax) in both directions; confirm Encoder 1 and Encoder 2 track each other within the configured mechanical tolerance (≤ 0.01 rev for direct-drive 1:1 axes).
- Run a positioning profile (typical S-curve with 100 ms jerk time) and record the following error peak. Compare against the warning and shutdown limits.
- Perform a forced ADS switch at mid-motion (a transient switching test). The following error should show a controlled step that decays within 200-500 ms depending on the Kv setting.
- Re-tune the position controller Kp and Kv on the load-side ADS using the trace as the response reference. SIMOTION's autotuning tool can be used but verify manually with the trace for the final gain values.
Fault Codes and Error Reaction
Encoder-related faults in SIMOTION Axis TO use the 50000-59999 range. Relevant entries:
| Fault Code | Meaning | Likely Cause | Remedy |
|---|---|---|---|
| 50005 | Encoder error, Sensor Module | Wiring, sensor module address, sensor type mismatch | Check SMC/SME wiring; verify topology online |
| 50006 | Encoder initialization error | Wrong encoder type, parameter set | Re-check encoder configuration in SCOUT |
| 50011 | Reference mark not found | Homing speed too high, sensor issue | Reduce homing velocity; verify reference cam |
| 50016 | Following error exceeded | Tuning, mechanical bind, encoder mismatch | Re-tune controller; verify encoder offset |
| 50100 | ADS switch refused | Axis in motion, drive not ready | Stop axis, wait for Standstill, retry |
| 50110 | Encoder swap error | _setAndGetEncoderValue failed | Inspect ErrorId; verify CommandID logic |
Troubleshooting Matrix
| Symptom | Possible Cause | Diagnostic Step |
|---|---|---|
| Following error step at ADS switch | Encoder reference offset not compensated | Compute and apply Encoder1ToEncoder2 offset |
| Position oscillation after switch | Kp too high for load inertia | Reduce Kp by 20% and re-trace |
| Position lag increases over time | Integrator windup during switch | Reset integral component on ADS switch |
| Axis does not respond after switch | EncoderNumber mismatch with ADS | Verify ADS configuration matches active encoder |
| CommandID never returns Done | Command overwritten by re-entrant call | Use unique CommandID per call; gate against Busy |
| Velocity loop unstable with load encoder | VelocityEncoder not set to Encoder 1 | Set VelocityEncoder = ENC_MOTOR explicitly |
| SINAMICS warns F31117 / F31118 | Encoder signal error at Sensor Module | Check screen, ground, shield of load encoder cable |
Best Practices and Field-Proven Notes
- Always stop the axis and disable the controller before switching encoders. SIMOTION will reject an ADS switch in Motion state with fault 50100.
- Maintain a single
UDINTcounter forCommandIDincrements across all axes to keep audit trails simple. - Use the EncoderData diagnostic function in SCOUT to compare raw counts of Encoder 1 and Encoder 2 during commissioning; differences outside tolerance indicate mechanical play or scaling errors.
- Keep motor and load encoder cable screens grounded at the cabinet entry; floating screens are a leading source of intermittent 50110 errors.
- For axes with significant backlash or torsional compliance, prefer a load-side position loop with a position feed-forward from the motor encoder. SIMOTION supports this through the
PositionFeedforwardconfiguration in the Axis TO. - Document the Encoder1ToEncoder2 offset as a startup parameter; if either encoder is replaced, the offset must be re-measured.
- For safety-related axes (Safety Integrated), coordinate the encoder change with the safety configuration: the safe encoder is typically the motor-side encoder and must remain in use for SIL monitoring.
Summary
Implementing load-side position control in SIMOTION requires three coordinated steps: (1) configure the load encoder as Encoder 2 in the Axis TO, (2) create a second Axis Data Set that selects EncoderNumber = 2, and (3) implement a controlled runtime transition using _setAndGetEncoderValue() with a tracked CommandID followed by an explicit ADS switch. With the velocity loop tied to the motor encoder (or computed from the active position encoder) and the position loop tied to the load encoder, the axis achieves the precision of a load-referenced system while retaining the dynamic stiffness of motor-side velocity control.
How do I configure SIMOTION to use a load-side encoder for position control while keeping motor-side feedback for speed?
Add the load encoder as Encoder 2 in the Axis TO configuration, create a new Axis Data Set (ADS) with EncoderNumber = 2, and keep the velocity loop closed on Encoder 1 by configuring VelocityEncoder = ENC_MOTOR in the Axis TO. Download the project, then switch the active ADS at runtime when the axis is at standstill.
What is the correct way to switch the active Axis Data Set at runtime in SIMOTION?
Stop the axis (Axis.Stop()), disable velocity, call _setAndGetEncoderValue(EncoderNo := 2, CommandId := <unique UDINT>), wait for Done = TRUE, then perform the ADS switch. A unique CommandID is required to reliably detect completion of the asynchronous function call.
Why does the following error step when switching from motor-side to load-side encoder?
The two encoders rarely have identical absolute reference at the moment of switching. Apply the offset in the Axis TO under the Encoder configuration (Encoder1ToEncoder2 or equivalent), and verify the result with the Axis Trace showing FollowingError during the switch.
Which SIMOTION fault codes indicate an encoder or ADS switching problem?
Faults 50005 and 50006 indicate encoder or sensor module errors, 50016 indicates a following-error violation, 50100 means an ADS switch was refused because the axis was not at standstill, and 50110 indicates a failed encoder swap from _setAndGetEncoderValue(). Check the Axis TO trace and online diagnostics to isolate the cause.
Can the position and velocity loops use different encoders in SIMOTION?
Yes. Set VelocityEncoder to Encoder 1 (motor-side) in the Axis TO so the velocity loop stays on the motor encoder, and let the position loop follow the encoder selected by the active ADS (Encoder 2 in the load-side data set). This is the standard pattern for load-side position control with motor-side velocity control.