FM 350-2 Load Value Job 10: Retain Counter Position After S7-300 Restart
When the Siemens FM 350-2 counter module is paired with an incremental encoder such as the SICK DKP 40 (360 ppr) in a CAM-controller application, the actual count value is lost on every S7-300 CPU restart. The module has no retentive counter memory and the incremental encoder has no absolute reference, so both the electronic count and the mechanical reference vanish together at power-off. This article documents the field-proven procedure to mirror the count value into a retentive area of the CPU, then re-load it into the FM 350-2 at warm restart (OB100) using Job 10 of the channel job interface, with a software-gate sequence that prevents the load from being rejected by the module.
The procedure targets STEP 7 V5.x and TIA Portal, applies to all FM 350-2 order numbers (6ES7350-2AH01-0AE0, 6ES7350-2AH00-0AE0) and the CPU 315-2DP referenced in the original application, and is aligned with the FM 350-2 Function Manual chapter 6.5 (load value) and chapter 7 (diagnostic / job-error codes). The TIA Portal documentation for FM 350-2 user-program integration is at Using FM 350-2 from the user program (S7-300, S7-400).
1. Problem Definition
Symptom observed in the field: a 360-pulse incremental encoder is wired to FM 350-2 channel 0. While the software gate is open, the actual count value tracks the shaft angle correctly. After a power-off / power-on (or STOP → RUN transition that triggers a warm restart with OB100), channel 0 returns to 0 instead of retaining the last valid position. The first zero pulse re-anchors the encoder, but during the first revolution after restart the value reported by the FM 350-2 is not guaranteed to match the mechanical angle.
For a CAM controller (cut-to-length, rotary knife, indexing table, labeling station) this symptom produces one or more of the following field failures:
- Length / angle error in the first product after a power-on
- Mechanical collision when the machine re-energizes mid-cycle
- Safety stop triggered by interlock logic that expects a known position
- Operator intervention required to manually home the machine after every power-on
The symptom is independent of encoder type as long as it is incremental (24 V single-ended, RS422 differential, or HTL). A TTL or HTL incremental encoder has the same behavior: no absolute reference, no retentive count.
2. Root Cause Analysis
Two separate effects combine to produce the symptom. Both must be addressed for a correct solution.
2.1 Incremental encoder has no absolute reference
An incremental encoder outputs two quadrature channels (A, B) and an optional zero pulse (N). The counter value is a count of edges relative to the last N pulse. On power-off, the electronic counter inside the encoder and the counter inside the FM 350-2 both reset. After power-up, the count starts at 0 again and only becomes valid after the next N pulse has been seen. The SICK DKP 40 datasheet confirms: 360 ppr with N pulse, no SSI / no EnDat / no Profibus absolute interface.
2.2 FM 350-2 has no retentive counter memory
Unlike the S7-300 CPU which retains M flags, DB words and timers marked as retentive, the FM 350-2 counter registers are volatile. The actual value reported in DB40 (the user-assigned data block, default = DB40 for the first FM 350-2 in the rack) is not backed up across power-off. To survive a restart the value must be stored in a retentive area of the CPU and written back to the FM 350-2 at startup.
The FM 350-2 Function Manual states this explicitly in the description of the load value (Job 10): the load value is transferred to the counter with this job, and the actual count value of channel n is overwritten. This is the only mechanism to inject a non-zero value into the counter, and it is non-retentive by design.
3. FM 350-2 Module Variants and Hardware
Before coding the solution, confirm which FM 350-2 variant is in the rack. The DB layout, the supported encoder types, and the maximum count frequency depend on the order number:
| Order number | Channels | Max frequency | Encoder types | Status |
|---|---|---|---|---|
| 6ES7350-2AH00-0AE0 | 8 | 1 MHz | 24 V single-ended | Discontinued, replaced by -2AH01 |
| 6ES7350-2AH01-0AE0 | 8 | 1 MHz | 24 V single-ended, RS422 differential | Current production |
Both variants are wired to the S7-300 backplane and assigned one shared data block (DB) by STEP 7 / TIA Portal. The assignment is configured in the FM 350-2 hardware properties (HW Config → FM 350-2 → Properties → Addresses). The default for the first FM 350-2 in the rack is DB40; the user can change it to any free DB number.
4. Data Block Layout (DB40 example)
The DB layout below matches the FM 350-2 Function Manual and the symbol names generated by STEP 7 V5.5 / TIA Portal V13 and later. Always open the generated DB40 in your project and read the symbol comments — never hard-code offsets from memory, because the exact layout can change with the FM 350-2 firmware and the STEP 7 / TIA Portal version used to generate the DB.
| Address | Type | Symbol | Direction | Description |
|---|---|---|---|---|
| DBD0 | DWORD | JOB | User → FM | Job interface: write job number, then read completion |
| DBD4 | DWORD | JOB_RESULT | FM → User | Job result (read) |
| DBD8 | DWORD | JOB_ERROR | FM → User | Job error code (read) |
| DBW14 | WORD | CTRL_CH0 | User → FM | Channel 0 control bits (software gate, etc.) |
| DBW16 | WORD | FB_CH0 | FM → User | Channel 0 feedback bits (gate open, etc.) |
| DBD24 | DWORD | ACT_CNT_CH0 | FM → User | Channel 0 actual count value |
| DBD32 | DWORD | CMP_CH0 | User → FM | Channel 0 comparator / setpoint value |
| DBD52 | DWORD | LD_CNT_CH0 | User → FM | Channel 0 load value (Job 10 target) |
For channel 1 to 7 the offsets repeat at fixed spacing (28 bytes per channel in the default configuration). Use the symbol names generated by STEP 7 / TIA Portal to write to the correct channel — do not calculate offsets manually.
5. Job Interface and Job 10 (LOAD)
The FM 350-2 exposes a job interface in DBD0 of the assigned DB. Writing a job number to DBD0 causes the module to execute that job. The job result appears in DBD4 and the error code (if any) in DBD8. The module clears DBD0 when the job is accepted. Selected job IDs from chapter 6.5 of the Function Manual:
| Job ID | Name | Action |
|---|---|---|
| 0 | No job / cleared | Default state of DBD0 |
| 3 | Cancel active job | Stops the running job |
| 4 | Read actual value, channel 0 | — |
| 10 | LOAD, channel 0 | Load DBD52 into the actual count value of channel 0 |
| 11 | LOAD, channel 1 | Load value of channel 1 |
| ... | ... | ... |
| 17 | LOAD, channel 7 | Load value of channel 7 |
| 100..107 | Read measured value | Frequency, period, velocity per channel |
Sequence to load a value into channel 0:
- Confirm the software gate of channel 0 is closed (DBX14.0 = 0, or its symbol equivalent). Job 10 is rejected with error 2 if the software gate is open.
- Write the target value into DBD52 (LD_CNT_CH0).
- Write 10 (decimal) into DBD0 (JOB).
- Poll DBD0 — the FM 350-2 clears DBD0 when the job is accepted. The error code (if any) is in DBD8. The "ack" bit in the channel feedback word (DBW16) can also be used as a secondary confirmation.
- On error, refer to chapter 7 of the Function Manual for the error-code mapping (see Table 5 below).
- Re-open the software gate of channel 0 (DBX14.0 = 1) once the load is complete and the application is ready to resume counting.
6. Save-and-Restore Procedure
The strategy is a three-step save-and-restore, executed on every scan and once at warm restart:
- OB1 mirror. On every scan, copy DB40.DBD24 (ACT_CNT_CH0) into a retentive DWORD in the CPU (e.g., DB100.DBD0). The retentive attribute on DB100 (or on the variable itself) keeps the last value across power-off.
- OB100 restore. At warm restart, close the software gate of channel 0, write the saved value into DBD52 (LD_CNT_CH0), trigger Job 10, wait for completion, then re-open the software gate.
- OB101 hot restart (optional). If the application uses hot restart (CPU 317 / CPU 319, OB101), repeat the restore in OB101 to handle the case where the FM 350-2 reset without going through a full warm restart.
6.1 Mark the mirror variable as retentive
In STEP 7 V5.x: open the DB that holds the saved counter (e.g., DB100), right-click the variable (e.g., "SavedCount_CH0", type DWORD) and select "Retain". Confirm the variable is shown in the retentive column of the DB declaration. In TIA Portal: open the DB in the project, click on the variable, open the "Properties" pane and set "Retain" = "Set in IDB" (or "Retain" = "True" in the declaration). The same effect can be achieved by marking the entire DB as retentive in the PLC properties — but be careful, this retains the full DB content including any scratch variables.
6.2 OB1 logic: continuously mirror the actual count value
Mirror once per OB1 cycle. There is no need to use a clocked bit — the cost of copying a DWORD on every scan is negligible.
LAD snippet (NW1 of OB1):
L DB40.DBD 24 // ACT_CNT_CH0
T DB100.DBD 0 // SavedCount_CH0 (retentive)
NOP 0
ST equivalent:
"DB100".SavedCount_CH0 := "DB40".ACT_CNT_CH0;
6.3 OB100 logic: restore the value with Job 10
OB100 is executed once at the end of the warm restart, after the FM 350-2 has completed its own initialization. By the time OB100 runs the module is ready to accept jobs. The sequence is: close software gate → write load value → trigger Job 10 → wait for completion → re-open software gate.
LAD snippet (NW1..NW5 of OB100):
// NW1: close software gate of channel 0
SET
S "M_GateClosed_Ch0" // user flag for diagnostics
R "M_GateOpen_Ch0"
// NW2: write the retentive mirror into the load-value cell
L DB100.DBD 0 // SavedCount_CH0 (retentive)
T DB40.DBD 52 // LD_CNT_CH0
// NW3: trigger Job 10 (LOAD)
L L#10 // Job 10 = LOAD channel 0
T DB40.DBD 0 // JOB := 10
// NW4: wait for the module to clear DBD0 (ack of the job)
L DB40.DBD 0
L L#0
<>I
JC NW4 // loop until DBD0 = 0
// NW5: optional error check
L DB40.DBD 8 // JOB_ERROR
L L#0
<>I
JC err // branch to error handler
SET
S "M_LoadOK_Ch0"
R "M_LoadErr_Ch0"
SPA end
err: R "M_LoadOK_Ch0"
S "M_LoadErr_Ch0"
end: NOP 0
ST equivalent (cleaner for production code, uses an edge-triggered flag to fire once per warm restart):
IF "FirstScan_OB100" THEN
"FirstScan_OB100" := FALSE;
// 1. Force software gate of channel 0 closed
"DB40".SW_GATE_CH0 := FALSE;
// 2. Optional: one OB1 pass with gate closed so the FM 350-2
// sees the gate state before Job 10 is issued. Without this
// pause, the module can still reject Job 10 with error 2.
// 3. Mirror the saved value into the load-value cell
"DB40".LD_CNT_CH0 := "DB100".SavedCount_CH0;
// 4. Trigger Job 10 (LOAD)
"DB40".JOB := 10;
// 5. Wait for the job to clear. A simple delay of 50 ms is
// sufficient at the module's 1 kHz internal job rate.
END_IF;
// OB1 follow-up: re-open the software gate after the job is acked
IF NOT "DB40".SW_GATE_CH0 AND "DB40".JOB = 0 AND "Restart_Armed" THEN
"DB40".SW_GATE_CH0 := TRUE;
"Restart_Armed" := FALSE;
END_IF;
6.4 Re-open the software gate only when the encoder reference is valid
The saved count value is only meaningful if the mechanical shaft has not moved while the PLC was off. In a CAM controller the operator should be required to either:
- Confirm the machine is in a safe home position before re-opening the gate, or
- Run a "homing" sequence: jog the shaft until the N pulse is detected, then re-open the gate using the value derived from the N pulse rather than the saved value.
The pattern "restore-and-trust" is acceptable only when the mechanical assembly cannot move while the PLC is de-energized (holding brake on a vertical axis, locked indexing table, brake-engaged rotary encoder).
7. Software Gate Control Details
The FM 350-2 has two gates per channel: a hardware gate (driven by the DI input of the FM 350-2 front connector) and a software gate (driven by a bit in the user program). Counting is enabled only when both gates are open. To use Job 10 you must close the software gate.
For channel 0, the relevant bits in DB40 are:
| Bit | Name | Direction | Description |
|---|---|---|---|
| DBX14.0 | SW_GATE_0 | User → FM | Open software gate of channel 0 (1 = open, 0 = closed) |
| DBX16.0 | FB_SW_GATE_0 | FM → User | Feedback: software gate of channel 0 is open |
Some STEP 7 versions generate the gate control as a separate bit per channel, others as a single bit field. Always cross-check the symbol names in your generated DB40. The naming convention shown here matches the FM 350-2 symbol names from STEP 7 V5.5 SP4 and later.
8. Verification
- Force the actual count value (e.g., 250) by jogging the encoder to a known angle and reading the value in a VAT (Variable Table) on DB40.DBD24.
- Set the "FirstScan_OB100" edge flag in OB100 (or directly trigger a STOP → RUN transition on the CPU).
- After the restart, open a VAT on DB40.DBD24. The value should be the load value (e.g., 250), not 0.
- Open a VAT on DB100.DBD0 — the value should also be 250, proving that the mirror was retained across the power-off.
- Verify DB40.DBD0 has returned to 0 (job acked) and DB40.DBD8 = 0 (no error).
- Verify the software gate is open again (DB40.DBX14.0 = 1 and DB40.DBX16.0 = 1) so the application can resume counting.
Diagnostic add-on: if Job 10 fails, light up a panel indicator with the error code from DB40.DBD8. Table 5 maps the most common error codes per chapter 7 of the Function Manual.
9. Job Error Code Reference
| DBD8 value | Meaning | Common cause | Fix |
|---|---|---|---|
| 0 | Job accepted, no error | — | — |
| 1 | Unknown job number | Wrote a number not in the job list (chapter 6.5) | Check job number in DBD0 |
| 2 | Job not permitted in current operating state | Software gate of channel 0 is open | Close the software gate (DBX14.0 = 0) before Job 10 |
| 3 | Invalid parameter | Load value out of count range, or wrong channel for this job | Check DBD52 against HW Config count limits |
| 4 | Module not configured for this operation | Channel not assigned, or wrong operating mode (e.g., not in "count continuously") | Re-open HW Config and check channel enable + mode |
| 5..9 | Module-internal errors | Hardware fault, firmware bug | Power cycle the rack, replace FM 350-2 if persistent |
10. When to Switch to an Absolute Encoder
If the mechanical shaft CAN move while the PLC is off, the save-and-restore procedure is unsafe. The correct engineering solution is an absolute encoder, which reports the true mechanical angle within one revolution (singleturn) or across many revolutions (multiturn) at every scan of the bus, with no need to home after power-on.
For an S7-300 station with FM 350-2, two paths are practical:
- Absolute encoder on Profibus-DP — read directly by the CPU through the integrated DP port of the CPU 315-2DP, or through a CP 342-5. The FM 350-2 is no longer needed for the position itself; the FM 350-2 can be retained for the high-speed counting task on a separate input (e.g., a second encoder on a different axis).
- Absolute encoder with SSI / EnDat interface on a different module — the FM 351 (positioning module for S7-300) supports SSI absolute encoders, and the SM 338 POS-input module can read SSI directly. The FM 350-2 is not used in this path.
Common absolute encoders used with S7-300:
- SICK AFM60 / DFS60 (Profibus-DP, singleturn and multiturn variants)
- Heidenhain ECN / EQN (EnDat, with the appropriate SM 338 / FM 351 variant)
- TR Electronic CEV58 / CEH58 (Profibus, multiturn)
- Baumer Hübner POG / PGN (Profibus, heavy-duty industrial)
The trade-off is cost: a 360-ppr incremental encoder such as the SICK DKP 40 is in the 50–100 € range, while a Profibus-DP absolute multiturn encoder is typically 600–1 200 €. For machines where the mechanical angle at power-on is safety-relevant, the additional cost is the right engineering decision. For machines that can afford a "first cycle at undefined position" the incremental + save-and-restore procedure is acceptable.
11. Common Pitfalls and Troubleshooting Matrix
| Symptom | Likely cause | Fix |
|---|---|---|
| Job 10 always returns error 2 | Software gate of channel 0 is still open when the job is issued | Close the software gate (DBX14.0 := 0) BEFORE writing Job 10, and let one OB1 cycle pass |
| DB40.DBD24 shows the saved value once, then the encoder keeps incrementing | You read the load value but the gate was not closed, so the load was applied on top of the running count | Re-check the gate logic; the load value replaces the actual value only when the gate is closed |
| DB100.DBD0 is 0 in OB100 | OB1 mirror runs AFTER OB100, so the saved value is from the previous-to-last scan, not the last scan of the previous run | Save the value on every scan (already done) and ALSO in OB101 (hot restart) and on the falling edge of the mode selector. For belt-driven applications, save on a 10 ms clock |
| Value correct, but the first revolution after restart is wrong | Shaft moved while PLC was off | Switch to absolute encoder, or add a homing sequence after restart that re-anchors on the N pulse |
| DB40 offsets are different in your project | STEP 7 / TIA Portal generated a different DB layout for the FM 350-2 version you have | Always read the symbol names in the generated DB; never hard-code offsets from memory |
| Job 10 executes but value is immediately overwritten by the encoder | Software gate was re-opened before the module finished processing the load | Wait for DBD0 to clear to 0 AND add a 50 ms delay before re-opening the software gate |
| PLC goes to SF (system fault) when Job 10 is issued | FM 350-2 firmware does not support Job 10 in the current operating mode | Check the FM 350-2 operating mode in HW Config. Job 10 is supported in "count continuously", "count once" and "count periodically" |
| Value retained across one STOP → RUN, lost on next power cycle | Mirror variable is NOT marked as retentive | Mark DB100.DBD0 as retentive in the DB declaration |
12. Topology and Timing Diagrams
12.1 Topology
The S7-300 rack layout for the original application: the CPU 315-2DP occupies slot 2, the FM 350-2 occupies slot 4, the encoder is wired to the front connector of the FM 350-2 (24 V single-ended, or RS422 differential for longer cables).
12.2 Load value state machine
The OB100 load sequence is implemented as a 5-state state machine. Each state runs to completion in one OB100 scan, except "wait for ack" which loops on DBD0 = 0.
12.3 Timing diagram for the OB100 load sequence
The load sequence takes 2 to 3 OB1 scans to complete. Most of the time is the module-internal job turnaround (typically 1 to 10 ms for Job 10 on a FM 350-2 firmware ≥ V3.0). Add a 50 ms safety margin before re-opening the software gate.
Reading the diagram left to right: 0–10 ms = software gate open, DBD0 = 0 (no job), counter is incrementing; 10 ms = OB100 starts, software gate closed; 10–15 ms = DBD52 written from DB100.DBD0, DBD0 := 10; 15–40 ms = module processes Job 10 (1–10 ms internal), DBD0 still reads 10; 40 ms = module clears DBD0 to 0, actual count value (DBD24) is now the loaded value; 40–60 ms = 20 ms safety margin before re-opening the software gate.
13. Related Documentation
- Siemens TIA Portal docs — Using FM 350-2 from the user program (S7-300, S7-400) — covers the integration sequence and the job interface used in this article.
- Siemens Function Manual "FM 350-2 Counter Module for S7-300" — chapter 6.5 describes the load value function and the job interface; chapter 7 lists the diagnostic / job-error codes.
- Siemens S7-300 Automation System — Module Specifications manual for the FM 350-2 order numbers, terminal assignment, and diagnostic LEDs.
- STEP 7 / TIA Portal online help — topic "Retentive data blocks" for marking DBs as retentive.
FAQ
Why does the FM 350-2 show 0 after every CPU restart?
The FM 350-2 has no retentive counter memory; the actual value is volatile. With an incremental encoder the count is relative to the last zero pulse, so both the encoder reference and the module count are lost on power-off. Store the last value in a retentive area of the CPU (e.g., DB100.DBD0) and re-load it with Job 10 in OB100.
Which job number loads a value into channel 0?
Write 10 (decimal) to DB40.DBD0 after putting the target value in DB40.DBD52. The FM 350-2 clears DBD0 when the job is accepted. Job 10 only runs when the software gate of channel 0 is closed; otherwise the job is rejected with error 2.
Can I keep the software gate open while loading a value?
No. Job 10 is rejected with error code 2 if the software gate of channel 0 is open. Close the software gate (DB40.DBX14.0 := 0), let one OB1 cycle pass so the FM 350-2 sees the gate closed, write the load value into DBD52, trigger Job 10, wait for DBD0 to return to 0, add a 50 ms safety margin, then re-open the gate.
Is the saved value still correct if the shaft moved while the PLC was off?
No. The saved value is only correct if the mechanical position is unchanged. For machines that may drift on power-off (uncoupled rotating mass, vertical axis without brake) you must add a homing routine that re-anchors on the encoder N pulse, or replace the incremental encoder with a Profibus-DP absolute encoder.
Why is OB100 the right place to trigger Job 10?
OB100 (warm restart) runs once after the FM 350-2 has completed its own initialization, and the module is ready to accept jobs. OB1 runs in every cycle afterwards, so the mirror variable in DB100 has been updated by the first OB1 scan after the OB100 restore.
Do I need a second FM 350-2 if I switch to an absolute encoder?
No. A Profibus-DP absolute encoder is read directly by the CPU 315-2DP through the integrated DP port. The FM 350-2 can be removed from the rack if the only task was the position read. If you need the high-speed counter (e.g., for a second axis), keep the FM 350-2 for the secondary task and read the absolute encoder from the CPU.