1. Problem Statement
On a Sinumerik 808D PPU141.1 milling controller, two user-defined M functions (M50 and M51) that are expected to execute strictly sequentially from an MDI (Manual Data Input) block are instead executed in parallel. The symptoms observed in the field are:
- Both M50 and M51 actions start within the same PLC scan cycle.
- The corresponding read-in disable (NC_READDIS) flag at
DB3200.DBX6.1drops for both codes before either M-function auxiliary action has been acknowledged. - Output devices driven by M50 (for example, an indexer or chuck clamp) and M51 (for example, a coolant pulse or door interlock) actuate together, producing tool/machine fault conditions.
- Inserting a
G4 F0.4dwell between the M50 and M51 lines in the MDI block masks the symptom, but inflates the cycle time across a 12-code M-function sequence and is therefore unacceptable in production.
The defect is not in the MDI program itself; the defect is in the way the PLC decodes, latches, and releases the read-in disable for the two consecutive M functions. This article documents the root cause, the four engineering solutions, sample ladder/STL code, and a verification matrix that fixes the issue without inserting artificial dwell time.
2. Sinumerik 808D PPU141.1 M-Code Signal Architecture
The Sinumerik 808D PPU141.1 panel processing unit contains an integrated S7-200-compatible PLC subsystem that decodes M functions coming from the NC and exposes them to the user PLC program through fixed data blocks. Two blocks are relevant for the M50/M51 issue:
| Data Block | Symbolic Name | Function |
|---|---|---|
| DB2500 | Decoded M functions from NC | One-shot bit for every M function 0..99. Each bit is set by the NC for one PLC cycle when the M function arrives. |
| DB3200 | NC control / read-in disable | User-driven signals back to the NC. DB3200.DBX6.1 is the read-in disable used to gate the NC program execution until the PLC has finished processing the M function. |
For the 808D, M functions 0..99 are decoded into byte groups of 8 bits each inside DB2500. The byte/bit offset rule is:
- Byte 1000 = M0..M7, Byte 1001 = M8..M15, …, Byte 1006 = M48..M55.
Bit 0 of byte n = M(8·(n-1000)), bit 7 = M(8·(n-1000)+7). Therefore:
| Bit | Decoded M |
|---|---|
| DB2500.DBX1006.0 | M48 |
| DB2500.DBX1006.1 | M49 |
| DB2500.DBX1006.2 | M50 |
| DB2500.DBX1006.3 | M51 |
| DB2500.DBX1006.4 | M52 |
| DB2500.DBX1006.5 | M53 |
| DB2500.DBX1006.6 | M54 |
| DB2500.DBX1006.7 | M55 |
Each decoded bit is high for one OB1 scan when the M function is transferred by the NC, and the PLC is responsible for latching the action and acknowledging it through the read-in disable. Reference: Sinumerik 808D Programming and Operating Procedures for Milling.
3. Signal Path Analysis: DB2500 Decoding and DB3200 Gating
The M50/M51 sequence traverses the following signal chain in the integrated PLC of the 808D PPU141.1:
- NC interpolator transfers M50 to the PLC interface.
DB2500.DBX1006.2goes high for one OB1 cycle. - User ladder latches an internal flag
M50_LATCHand raisesDB3200.DBX6.1(NC_READDIS) to instruct the NC to stop reading further blocks until the M action is complete. - The PLC drives the physical output (for example, a clamp or a coolant valve), waits for the feedback contact to close, then drops
DB3200.DBX6.1to release the NC. - NC continues to the next block, transfers M51.
DB2500.DBX1006.3pulses high for one OB1 cycle, and the sequence repeats.
4. Root Cause: Read-In Disable Race Condition
The defect is a deterministic race between three timing events inside one OB1 cycle:
- Time t0: NC sets
DB2500.DBX1006.2(M50 decoded) and starts checkingDB3200.DBX6.1. - Time t1: PLC scan reads DB2500, sets
M50_LATCH, drives the output, but the read-in disable is being toggled in a different network, or in a sub-routine called with a conditional skip. - Time t2: Because the read-in disable is not held high across the full OB1, the NC never sees a stable high and continues to the next block.
DB2500.DBX1006.3(M51) pulses within the same scan or within the next.
Two implementation patterns are typically responsible for this on a 808D PPU141.1:
- The M-code decode and the read-in disable are placed in different sub-routines (SBR_x) and the second sub-routine is skipped because a previous read-in disable flag is still active from a different M function.
- The user is writing/resetting
DB3200.DBX6.1from a sub-routine that is called only when the corresponding M bit is high, and the M bit has already returned to 0 by the time the sub-routine runs.
The fact that G4 F0.01 or G4 F0.4 dwell inserted between the M lines in MDI fixes the symptom is a strong confirmation: the dwell forces the NC to pause long enough for the PLC to settle DB3200.DBX6.1 high before the next M function is transferred.
5. Solution 1 — MDI-Level Dwell Time (G4) Sequencing
Forcing the NC to insert a dwell between every M function is a valid but wasteful approach. Use it only as a smoke-test on the bench, not in production.
; MDI program with explicit dwell between consecutive M functions
M50
G4 F0.4 ; 0.4 second dwell (seconds, without decimal = milliseconds)
M51
G4 F0.4
M52
G4 F0.4
M53
...
6. Solution 2 — PLC Latch with On-Delay Timer Sequencing
The cleanest production fix is to keep the read-in disable asserted until both (a) the M action feedback is received and (b) a minimum inter-M dwell has elapsed. This guarantees that the NC sees a stable high on DB3200.DBX6.1 long enough that the next M function is never transferred inside the same scan.
Reference ladder logic (Network 1 — decode and latch M50):
// Network 1: Latch M50 from decoded bit
DB2500.DBX1006.2 M50_LATCH M50_LATCH
| | |
------| |-----------------| |-------( S )-|
| |
| M50_LATCH |
------|/|----------------------------+|
| |
| DB3200.DBX6.1 |
------| |----------------------------+|
Network 2 — hold the read-in disable for a minimum dwell after feedback:
// Network 2: Assert read-in disable until feedback AND 200 ms on-delay
M50_LATCH DB3200.DBX6.1
| |
------| |--------[ T37 K20 ]--------( S )-|
| | |
| | M50_FB |
| +---| |-------------|
| |
| DB3200.DBX6.1 |
------| |----------------------------( R )-|
| NOT M50_LATCH |
------|/|----[ T37 ]----------------------|
Where:
-
T37 K20is an on-delay timer of 200 ms (resolution 10 ms, preset 20). -
M50_FBis the discrete feedback input (clamp closed, valve reached pressure, etc.). - The reset branch is qualified by NOT M50_LATCH AND the timer having elapsed, ensuring
DB3200.DBX6.1is held for at least 200 ms regardless of how fast feedback arrives.
Repeat the same pattern for M51 (use DB2500.DBX1006.3, M51_LATCH, and a second timer, for example T38). Because the read-in disable is now held for a deterministic minimum, the NC never gets a chance to transfer M51 inside the same OB1 scan as M50.
7. Solution 3 — OB1 Centralized M-Code State Machine
If the ladder is fragmented across multiple sub-routines, centralize the M-code state machine into OB1 as a step sequencer. This eliminates the sub-routine skip problem entirely because every M bit is read at the start of every OB1 cycle.
Sample OB1 ladder (Network 1 — read M bits into edge flags):
// OB1 Network 1: Edge detect M bits from DB2500
DB2500.DBX1006.2 M50_EDGE
| |
------| |---[ ED ]---------( P )-|
| |
| DB2500.DBX1006.3 M51_EDGE
| | |
------| |----[ ED ]--------( P )-|
Network 2 — step counter for sequential M execution:
// OB1 Network 2: Step counter advances only when previous step is done
M50_DONE M_STEP
| |
------|/|---------------------( INCU )-|
| |
| M51_DONE |
+-------| |-------------+
Network 3 — current-step decoding:
// OB1 Network 3: When M_STEP = 0 expect M50, when = 1 expect M51
M_STEP M50_LATCH
| |
------| =0|-----------------( S )-|
| |
| M_STEP M51_LATCH
| | |
------| =1|----------------( S )-|
Network 4 — read-in disable while any latch is set:
// OB1 Network 4: Hold DB3200.DBX6.1 while any M_LATCH is active
M50_LATCH M51_LATCH DB3200.DBX6.1
| | |
------| |--------| |--------( S )-|
| |
| NOT M50_LATCH |
+--|/|-----------------|
| NOT M51_LATCH |
+--|/|----------------( R )-|
Now the read-in disable cannot drop until both M latches have been cleared by their respective feedback inputs, so the M50/M51 race condition is eliminated structurally.
8. Solution 4 — Hardware Interrupt-Driven M-Code Processing
For very tight cycle times (cycle time < 4 ms in a high-speed auxiliary application), use an interrupt OB (for example OB40, an S7-200/300-style hardware interrupt) triggered by the rising edge of a free digital input that is set by a hardware one-shot monostable. Inside OB40:
- Read
DB2500.DBX1006.2andDB2500.DBX1006.3directly. - Set the corresponding M_LATCH.
- Raise
DB3200.DBX6.1atomically with the latch set, both in the same STL network, so the read-in disable is asserted within microseconds of the M function arriving. - Clear the interrupt source so the next interrupt can fire.
Reference: Sinumerik 808D ADVANCED Commissioning Guide.
9. Reference STL Source for OB1 M-Code Sequencer
The following STL source compiles on the S7-200-compatible PLC programming tool used for the 808D PPU141.1 and implements Solution 3 with edge detection, sequential step advancement, and a single read-in disable flag.
// STL source - paste into OB1
NETWORK 1 // Edge detect M50 and M51 from DB2500
U DB2500.DBX1006.2
FP M50_EDGE_T
S M50_LATCH
U DB2500.DBX1006.3
FP M51_EDGE_T
S M51_LATCH
NETWORK 2 // Step sequencer: advance only when previous step finished
UN M50_DONE
SPB NEXT1
U M50_DONE
UN M51_DONE
L MW 100 // M_STEP
+ 1
T MW 100
NEXT1: NOP 0
NETWORK 3 // Decoding the current step
L MW 100 // M_STEP
L 0
==I // if M_STEP = 0
S M50_REQ // request M50
L MW 100
L 1
==I // if M_STEP = 1
S M51_REQ // request M51
NETWORK 4 // Acknowledge M50 when M_STEP = 0 AND M50_REQ set
U M50_REQ
U( M_STEP_0 // M_STEP = 0
)
S M50_LATCH
UN M50_FB
R M50_LATCH
S M50_DONE
NETWORK 5 // Acknowledge M51 when M_STEP = 1 AND M51_REQ set
U M51_REQ
U( M_STEP_1
)
S M51_LATCH
UN M51_FB
R M51_LATCH
S M51_DONE
NETWORK 6 // Read-in disable held while any latch is active
O M50_LATCH
O M51_LATCH
S DB3200.DBX6.1 // NC_READDIS = 1
UN M50_LATCH
UN M51_LATCH
R DB3200.DBX6.1 // NC_READDIS = 0
10. MDI Program Template for a 12-Code M Sequence
After applying Solution 2, 3, or 4, the MDI program can revert to a clean, dwell-free sequence:
; MDI block - sequential M functions, no artificial dwell
N10 M50
N20 M51
N30 M52
N40 M53
N50 M54
N60 M55
N70 M56
N80 M57
N90 M58
N100 M59
N110 M60
N120 M61
N130 M62
N140 M30 ; program end
Each M function is now sequenced entirely by the PLC state machine; the NC sees a stable read-in disable and never transfers the next M function before the previous one is acknowledged.
11. Commissioning and Verification Procedure
- Connect the PG/PC to the 808D PPU141.1 with the PLC programming tool as described in the Sinumerik 808D ADVANCED Commissioning Guide, section "PLC programming tool connection".
- Go online and force-watch the following tags:
DB2500.DBX1006.2,DB2500.DBX1006.3,DB3200.DBX6.1,M50_LATCH,M51_LATCH,M50_FB,M51_FB. - Run the MDI block from Section 10 in single-block mode. Confirm that
DB3200.DBX6.1rises within one OB1 cycle ofDB2500.DBX1006.2going high. - Confirm that
DB3200.DBX6.1remains high continuously across the M50 and M51 transitions, and drops only after both feedback signalsM50_FBandM51_FBhave been received. - Use the PLC programming tool status chart to record the cycle time stamp of every M bit. The delta between
DB2500.DBX1006.2falling andDB2500.DBX1006.3rising must be at least one full OB1 cycle (typically 4–10 ms) and must be > 0; if it is 0, the race condition is still present. - Run the full 12-code M sequence under normal production feed-hold override and verify the total cycle time matches the expected machine cycle time (no artificial dwell penalty).
- Force a fault on M50_FB and verify that the sequence halts at M50 and that the operator alarm is raised — this proves the read-in disable is genuinely being held by feedback, not by a hard-coded timer.
12. Troubleshooting Matrix
| Symptom | Likely Cause | Fix |
|---|---|---|
| M50 and M51 outputs actuate together | Read-in disable not held; OB1 sub-routine skip | Apply Solution 2 (timer) or Solution 3 (OB1 sequencer) |
| M50 fires but M51 is lost (no output) | Edge-detect of DB2500.DBX1006.3 missing the pulse |
Move M decoding to top of OB1, latch into internal flag |
| DB3200.DBX6.1 stuck high, machine holds | Reset branch never sees NOT M_LATCH | Add explicit feedback timeout (e.g., 5 s) to drop read-in disable and raise alarm |
| M functions fire correctly in MDI but not in a part program | Block search leaves DB3200.DBX6.1 in wrong state | Add reset of all M_LATCH flags and DB3200.DBX6.1 in OB100 (restart) |
| Adding G4 fixes the symptom but slows cycle | Confirms read-in disable race | Apply PLC-side fix; remove G4 in production |
13. Field Notes and Best Practices
- Always read
DB2500decoded M bits at the very start of OB1 and copy them into internal flags before any other logic runs. The decoded bits are valid for only one OB1 cycle and any conditional skip elsewhere in the program will lose them. - Pair every M_LATCH with a feedback timeout timer (typically 2–5 seconds) to drop the read-in disable and raise an operator alarm if the auxiliary action does not complete. This protects the machine from a frozen read-in disable that halts the NC indefinitely.
- Use distinct bits in DB3200 if your application needs more than one read-in disable zone.
DB3200.DBX6.1is the conventional choice for general-purpose M-function gating, but verify the assignment against the active 808D project file before forcing values. - Document the M-to-action mapping in the PLC program header. A clean lookup table (M50 = clamp close, M51 = coolant on, M52 = …) is invaluable during commissioning and during the inevitable 3 AM call from the shop floor.
- When porting 808D ladder to a Sinumerik 828D or 840D sl, the M-code address scheme is identical, so the same Solutions 2 and 3 apply without modification. The 808D PLC programming tool produces STL that the S7-200-compatible runtime can execute.
14. Frequently Asked Questions
Why are M50 and M51 firing at the same time on my 808D PPU141.1?
The PLC is not holding DB3200.DBX6.1 high long enough to gate the NC, so the NC transfers M51 into DB2500.DBX1006.3 in the same OB1 cycle as M50. Decode the M bits at the top of OB1, latch them into internal flags, and hold DB3200.DBX6.1 high until the feedback signal is received plus a minimum dwell of ~200 ms.
Can I control M-code execution without using the read-in disable bit?
Yes — by running the M-functions through an OB1-resident step sequencer that advances one step per acknowledged feedback. The step sequencer replaces the read-in disable as the synchronization mechanism, but in practice most projects still use DB3200.DBX6.1 together with the sequencer as a belt-and-suspenders safeguard.
Does G4 F0.4 between M codes fix the parallel execution permanently?
Yes, but it is a workaround, not a fix. A 0.4 s dwell is 400 ms of dead air, which becomes ~5 s of dead air across 12 M functions. Use G4 only to confirm the read-in disable race condition on the bench, then apply a PLC-side sequencer for production.
Where do I find the decoded M function bits in DB2500?
Byte 1000 = M0..M7, byte 1001 = M8..M15, and so on. M50 lives at DB2500.DBX1006.2 and M51 at DB2500.DBX1006.3. The full mapping table is documented in the Sinumerik 808D Programming and Operating Procedures for Milling manual.
Is the read-in disable at DB3200.DBX6.1 the same on 828D and 840D sl?
The address and meaning are identical. DB3200.DBX6.1 is the standard NC read-in disable bit in the Sinumerik PLC interface, and the OB1 M-code sequencer pattern described in this article ports directly to 828D and 840D sl projects without modification.