Resolving SINUMERIK 840D sl Alarm 12640 in EXTCALL

David Krause11 min read
Other TopicSiemensTroubleshooting
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

Alarm 12640 appears intermittently when a SINUMERIK 840D sl executes a large NC program from external storage, even though the same program runs after loading it into NC memory. The effective correction is to keep streamed CAM motion sequential and move IF...ENDIF, FOR...ENDFOR, file operations, and reusable tool logic into loaded subprograms or user cycles.

Alarm identity and failure boundary

12640 Channel %1 Block %2 nesting conflict in control structures means that the interpreter has reached an invalid control-structure state. The normal causes are an open structure that never reaches its closing statement, a closing statement without the corresponding opening statement, or mismatched structure types. A minimal mismatch is:

LOOP
ENDIF
ENDLOOP

The displayed block identifies where the interpreter detects the inconsistent state. It need not identify the statement that created it. In the affected application, alarm locations included N174 and N178, while another occurrence pointed to N87. Removing the surrounding block allowed execution, but that result alone did not distinguish a syntax defect from an external-loading limitation.

Observation Engineering meaning Next test
Alarm follows a specific closing block Opening, closing, or branch structure may be mismatched earlier Audit the complete program
Top-level block also fails Deep visible nesting is not the only possible cause Compare local and external execution
Removing WRITE changes the result The preceding statement affects the failure boundary; it is not automatically the root cause Test the write result and a constant string

Check 1: confirm the diagnostic display shows alarm 12640, its channel, and its block number. Expect the recorded block to provide a repeatable inspection boundary, not necessarily the defective statement.

Complete control-structure audit

Audit the entire executable program before changing its architecture. A partial listing cannot prove structural balance. The affected file was 14 MB, and its posted beginning did not contain M17, M30, or RET because the termination lay outside the excerpt.

  1. Match every IF with one ENDIF. Place ELSE inside that pair.
  2. Match every FOR with one ENDFOR, and every LOOP with one ENDLOOP.
  3. Check branch targets and conditional paths. A structure can be textually present yet become invalid when execution enters or leaves it through a jump.
  4. Inspect the statements before the displayed alarm block, then expand the inspection back to the start of the active routine.
  5. Confirm that the main program or subprogram reaches its appropriate termination statement.

Commenting out a complete IF...ENDIF or FOR...ENDFOR pair proves only that the removed execution path participates in the failure. It does not prove that the pair was unbalanced. In this case, apparently balanced top-level blocks could fail externally and execute locally.

Check 2: count and type-match every opening and closing statement across the complete routine. Expect zero unmatched structures and a valid M17, M30, or RET at the applicable program boundary.

Active nesting-depth check

For the IF structures described for this configuration, the active nesting limit is eight levels. A file can contain more than eight textual levels if its runtime path never activates them simultaneously. The conflict occurs when execution attempts to enter the ninth active level.

Count runtime nesting, not indentation alone. Follow each possible branch and record how many control structures remain open at every statement. Include enclosing structures inherited from the calling context where applicable. A visually top-level block that fails with no other active structures directs the diagnosis away from the eight-level limit and toward the execution method.

  1. Mark the entry and exit of each control structure.
  2. Trace the actual path taken by the failing data set.
  3. Increment the active-depth count at each opening statement and decrement it at its matching close.
  4. Refactor any path that attempts to activate level nine.

Check 3: expect the maximum active IF depth to be eight or fewer. If the failing block is at the top level, record an active depth of one and continue with the local-versus-external comparison.

Local and external execution comparison

The decisive test is to run identical NC content by both execution paths. The affected programs generated by the same postprocessor ran correctly in most cases, but the intermittent alarm appeared only when a program was processed from external storage. Loading that program into NC memory eliminated the alarm. A controller restart did not correct the externally executed structure, and STOPRE did not change the result.

The term external execution here means that program data remains outside NC memory and is read sequentially during execution, including a main program run directly from a network location. This is distinct from the EXTERN language declaration used with parameterized PROC subprograms that are not in a cycle directory. EXTCALL is the external-subprogram execution mechanism relevant to streamed program data.

Test Expected result in this fault pattern Decision
Run from external storage 12640 occurs at or after a control block Record alarm block and preceding statements
Load identical file into NC memory Program passes the same location Treat external loading as the differentiator
Add STOPRE No correction Do not use preprocessing stop as the remedy
Restart without restructuring Fault remains possible Correct program placement and structure

Check 4: expect byte-for-byte equivalent program logic to pass from NC memory and fail only during external execution. If both paths fail at the same point, return to syntax, nesting depth, and runtime data checks.

Sequential external-loading constraints

An externally stored file is supplied to the NC interpreter as a sequential stream. Control structures require the interpreter to maintain state across their full span, while loops and branches can require execution behavior that conflicts with a stream intended for forward, sequential consumption. Large CAM files intensify this architectural mismatch because high-level logic, jumps, cycles, file operations, and motion are interleaved across a long input stream.

A short IF...ENDIF can also encounter the same class of failure; visible block length is not the governing property. The relevant boundary is whether the interpreter can maintain the required control context while external blocks are being delivered. This explains why identical postprocessor structure can work in most files and fail at particular block placement or data combinations.

Removing a loop changes the interpreter state and the stream position at which later statements arrive. It can therefore suppress the alarm even when the loop delimiters are balanced. The stable design rule is to reserve external execution for sequential contour motion and place high-level language elements in NC-resident routines.

Check 5: inspect the externally executed region. Expect a forward, sequential CAM path without FOR, IF, jumps, cycle definitions, or file-management logic after refactoring.

Statement-level isolation around WRITE

One repeatable case displayed the alarm at N178, but commenting the WRITE statement at N175 allowed the program to run. Earlier tests similarly passed after blocks near N168-N174 or N85-N87 were removed. Treat this as a diagnostic boundary: the interpreter reports the control conflict after processing the preceding operation.

  1. Retain the original externally executed file and record the alarm location.
  2. Replace the array-derived WRITE payload with a constant test string while leaving the surrounding control structure unchanged.
  3. Read the error variable supplied to WRITE immediately after the operation. A nonzero result directs troubleshooting toward the destination, path, data, or file operation.
  4. Run the same logic from NC memory. If it passes locally, move the write operation and its enclosing loop into a resident cycle.
  5. Restore the production payload only after the resident cycle passes with the constant string.

Do not classify WRITE as defective merely because removing it suppresses 12640. The command can alter when the streamed interpreter reaches a control boundary, and its own result must be checked separately.

Check 6: expect the WRITE error variable to report a successful operation in the resident-cycle test, and expect external contour execution to contain no file-writing loop.

NC-resident program architecture

Separate orchestration from bulk contour data. Keep the main program and callable logic in the NC program structure, then stream only the large CAM-generated contour sections. A practical placement model is:

Program content Placement Allowed role
Main program Workpiece WPD directory Calls resident logic and external contours
Workpiece subprogram Same WPD directory Workpiece-specific decisions
General subprogram SPF directory Reusable callable logic
Manufacturer or user cycle Applicable cycle directory Parameterized high-level logic
Large CAM contour External storage Sequential motion with high-level language, jumps, and cycles removed

Tool lookup, tool creation, measurement-state counting, magazine-state counting, and file generation recur across programs and belong in a user cycle. This reduces the postprocessor to a stable call interface. A later implementation change then applies to existing NC programs as long as the call signature remains unchanged.

Check 7: expect the main program to contain a short cycle call and the external file to contain the large sequential contour. Search the external file and expect no relocated control or file-management statements.

User-cycle interface and parameter semantics

Create a subprogram with a PROC declaration. The name in the declaration must match the program name. The demonstrated cycle was CUS.DIR/TOOLINIT.SPF with this interface:

PROC TOOLINIT(VAR STRING[24] BEZEICHNER[],
 VAR BOOL WRK[], VAR INT TYP[], VAR REAL DIA[],
 VAR REAL PITCH[], VAR INT SCHNEIDE[],
 INT ANZAHL_WZG) DISPLOF SBLOF

VAR selects call by reference: writes made by the cycle affect the caller's parameter. Parameters without VAR use call by value, so changes inside the cycle do not alter the caller. Arrays must be passed by reference. In this interface, the six arrays use VAR, while ANZAHL_WZG is a scalar input passed by value.

Call the cycle from the main program with the matching parameter order:

N145 TOOLINIT(BEZEICHNER, WRK, TYP, DIA,
 PITCH, SCHNEIDE, ANZAHL_WZG)

Using the same variable names as the former main-program logic permits the existing loops to be moved with minimal internal changes. Parameter order and data types still form the callable contract; names alone do not validate the interface.

Check 8: expect the loaded program name and PROC TOOLINIT name to match, all arrays to include VAR, and the call at N145 to pass seven arguments in the declared order.

Cycle execution and deployment behavior

DISPLOF suppresses display of the cycle's internal blocks, leaving the display on the calling block. SBLOF disables single-block stopping inside the cycle, so execution continues to M17 or SBLON even when single-block mode is active at the machine. Use these modifiers deliberately: they change commissioning visibility and operator stepping behavior.

The demonstrated resident logic deletes the old hand-tool file, iterates from zero through ANZAHL_WZG - 1, locates or creates tools, writes tool data, counts unmeasured and hand tools, writes names to the file, and returns with M17. Its structural outline is:

DEF INT ERROR, HH
DELETE(ERROR, "/_N_WKS_DIR/_N_HANDWZG_SPF")
FOR HH = 0 TO ANZAHL_WZG - 1
  ; resident tool and WRITE logic
ENDFOR
M17

After first creating the cycle, load it and restart the machine. Subsequent changes to the program body take effect immediately. A change to the PROC line requires another restart because it changes the registered interface. During commissioning, omit SBLOF if block-by-block observation is required, then restore the intended execution modifier after testing.

Check 9: after loading and restarting, expect the call to resolve without an interface error and the cycle to return at M17. After a body-only edit, expect the new behavior immediately; after a PROC edit, expect it only after restart.

Program-count and path constraints

The NC directory structure is flat and predefined except for the workpiece-directory arrangement. For the configurations described, the standard number of programs stored in the NC on MMC100.2 or PCU20, or loaded on MMC103 or PCU50, is limited to 100 independently of free memory. User and manufacturer cycles contribute to that count. Read the controller's program inventory to determine how its installed Siemens cycles are treated.

The complete path—including filename and separators—has a maximum length of 128 bytes. Cycle extraction therefore trades one very large generated file for additional managed program objects. The successful restructuring used ten cycles; if program count becomes restrictive, related functions can share one cycle with a selector parameter. Keep each selected branch bounded and count its active IF depth before combining routines.

  1. Inventory loaded main programs, subprograms, user cycles, and manufacturer cycles.
  2. Count each new cycle before deployment against the 100-program configuration limit.
  3. Count path bytes for every external and resident file, including separators and filename.
  4. Keep every resulting path at or below 128 bytes.

Check 10: expect the loaded-program inventory to remain within 100 for the listed configurations and every complete path to measure no more than 128 bytes.

End-to-end commissioning verification

  1. Load the main program, subprograms, and user cycles into their selected NC directories.
  2. Restart after creating a cycle or changing a PROC declaration.
  3. Run the cycle with test data and check its WRITE error result, tool-data changes, counters, generated file, and return at M17.
  4. Run the same main program with the large contour supplied from external storage.
  5. Pass the former alarm blocks, including the regions corresponding to N87, N174, and N178 where applicable.
  6. Repeat with each data set that previously produced intermittent behavior. Confirm that single-block and display behavior match the selected SBLOF and DISPLOF modifiers.
  7. Regenerate a program from the revised postprocessor and verify that it emits the resident-cycle call instead of copying the high-level loop into the external stream.

The refactored installation initially exposed a separate missing-block-end syntax error. After that syntax defect was corrected, alarm 12640 no longer appeared, and the postprocessor became smaller because the reusable implementation resided in ten cycles.

Check 11: expect repeated external runs to complete past every former alarm location with no 12640, successful cycle outputs, a normal M17 return, and no high-level loop copied back into the generated external contour.

Frequently asked questions

Can I leave IF and FOR blocks in an external SINUMERIK program?

Use external files for sequential CAM contour motion. Move IF...ENDIF, FOR...ENDFOR, jumps, cycles, and file operations into an NC-resident subprogram or user cycle when external execution produces 12640.

Does STOPRE clear SINUMERIK alarm 12640?

STOPRE did not correct this external-loading fault, and restarting without restructuring also provided no remedy. Compare the same file in NC memory, then separate resident logic from streamed contour data.

Does moving the logic to a user cycle fix external runs?

Yes for the documented fault pattern: after the logic was moved into resident cycles and a missing-block-end error was corrected, 12640 stopped recurring. Final verification is repeated external execution past every former alarm block while checking successful cycle output and the return at M17.

Back to blog