Skip to main content

Subprograms

Function: Call of a subprogram

Frequently recurring tasks, such as pocket milling, hole drilling, and tool changing, can be swapped out to G code subprograms and called from there. During a call, parameters can be passed to the subprogram. The data types BOOL, LREAL, and STRING are permitted for this purpose.

Tip

If you use subprograms, then you need to use the function blocks SMC_ReadNCFile2 and SMC_NCInterpreter instead of SMC_ReadNCFile and SMC_NCDecoder.

Tip

Subprograms work in the online decoder only (not in the CNC editor).

Each subprogram is stored in a separate file. These files are saved in one or more subdirectories on the controller. The file names have to be written in lowercase, have the file extension .cnc, and correspond to the name of the subprogram. Example: Subprogram name "Drill" -> file name drill.cnc.

Important

Note that the file name of the subprogram has to be written in lowercase.

The SMC_ReadNCFile2 POU has an input aSubProgramDirs : ARRAY[0..4] OF STRING(174). Up to five subdirectories can be specified beyond this. They are scanned in the given order. If there are subprograms with the same name in multiple directories, then the subprogram is found that has the directory with the lowest index in the array. The subprogram name is converted to lowercase.

Example 47. Example
aSubProgramDirs = ['subprograms/user', 'subprograms/system', '']

The subprogram DrillA1 is scanned first in the file subprograms/user/drilla1.cnc. If this file does not exist, then the search continues in subprograms/system/drilla1.cnc.



It is possible to call subprograms indirectly by means of a variable (more precisely, by means of an expression of type STRING).  The expression (and therefore also any lookup of variables) is evaluated – generally in the case when using variables in the G code – at the time of the preprocessing when the interpreter reaches the line. In this case, the type checking of the arguments is done only when the interpreter has reached the line and not already during parsing, as is the case with static calls.

Tip

Subprograms cannot be created offline in the CNC editor.

Maximum nesting depth of subprogram calls

  • Before version 4.18.0.0: The maximum nesting depth of subprogram calls is limited to 14.

  • Version 4.18.0.0 and higher: The nesting depth is now limited only by the memory. The maximum value can be changed using the library parameter SMC_CNC_LibParams.MAX_SUBPROGRAM_NESTING_DEPTH.

Syntax for the call

Subprogram calls are special blocks in the G code that consist of a block number and a call only. No additional words are permitted. Moreover, there is a dynamic call in which the name of the subprogram is still unknown when parsing and is prepared (for example, by an IEC variable).

N<SentenceNo> <Name> <BracketOpen> <ActualParamList> <BracketClosed>
N<SentenceNo> DYNCALL <BracketOpen> <SubNameExp> [, <ActualParamListNotEmpty]  <BracketClosed>

<SubNameExp> : An expression with exactly one value of type STRING
<ActualParamList> ::= Empty | <ActualParamListNotEmpty>
<ActualParamListNotEmpty> ::= <ActualParamValue> | <ActualParamValue>, <ActualParamListNotEmpty>

<Name>

Valid IEC identifier with minimum 3 and maximum 80 characters. It has to correspond to the file name (without extension) where the subprogram is defined. Uppercase or lowercase does not matter for subprogram names. The characters [a-zA-Z0-9_] are permitted.

The following keywords are invalid as names: SUBPROGRAM, RETURN, END_SUBPROGRAM, RESTORE_MODES, BOOL, LREAL, STRING, LET, DYNCALL, IF, ELSE, END_IF, CASE, END_CASE, FOR,END_FOR, WHILE, END_WHILE, REPEAT, UNTIL, END_REPEAT.

<ActualParamList>

There has to be exactly the same number of parameter values specified as the subprogram defines (see "Syntax for the declaration"). The type of each parameter value has to agree with the declaration.

<BracketOpen>/<BracketClosed>

For reasons of compatibility, braces are used instead of parentheses in default settings for SMC_ReadNCFile2 and subprogram calls and declarations. Parentheses are valid in G code for comments.

The function block SMC_ReadNCFile2 has a mode (bParenthesesAsComments input) where parentheses are not comments. Instead, multiline comments are opened with (* and closed with *). In this new mode, both braces and parentheses can be used for subprogram calls and declarations.

<ActualParamValue>

Variable, literal, or any expressions

Example

N10 SUB1()
N20 DRILL(10.0)
N30 SUB2(5, "Text", 2.5)
N40 G36 O#SUBNAME  D'DRILL'    % Indirect call via local variable
N40 DYNCALL(#SUBNAME, 2)       % equivalent to N40 DRILL(2)
N50 DYNCALL($SUBNAME$, 2, 4)   % Indirect call via IEC variable

Syntax for the declaration

A subprogram has to be saved in a separate file. The first line (neither empty nor a comment line) has to contain the declaration of the subprogram. The following syntax applies:

SUBPROGRAM <Name> <BracketOpen> <FormalParamList> <BracketClosed> <RESTORE_OPT>
<Inhalt Unterprogramm>
END_SUBPROGRAM

<FormalParamList> ::= Empty | <FormalParamListNotEmpty>
<FormalParamListNoEmpty> ::= <FormalParam> | <FormalParam> , <FormalParamListNotEmpty>
<FormalParam> ::= <ParamName> : <ParamType>
<ParamName>   ::= #[a-zA-Z0-9_]+

<ParamType> ::= LREAL | BOOL | STRING ; String with a maximum length of 255 bytes
<RESTORE_OPT> ::= RESTORE_MODES

<ParamName>

The length of the name may be a maximum of 80 characters (not including the prefix #).

RESTORE_MODES

If this keyword is specified, then the following modal states are restored when returning to the calling program (set to the value that it had at the call):

  • Active G code

  • Relative/Absolute mode (G90/G91, G98/G99)

  • Circular plane and 2D/3D mode

  • Decoder coordinate system (including scaling)

  • Feed rates (path and additional axes), rapid traverse rate, maximum accelerations and decelerations (path and additional axes)

  • Feature flags and general parameters (G38)

  • Tool radius (D word)

  • Tool offsets (G43)

  • S profile (S word)

The following modal states are not restored:

  • Current position of the decoder/interpreter as well as the current cardinal spline state The position includes the entire structure SMC_POSINFO (i.e., X, Y, Z, the orientation, and all additional axes).

  • State (on/off) of the path preprocessing POUs (G40-G43, G50-G52, G60-G61, G70-G71)

  • Modulo setting of the additional axes (PA, PB, …)

Note: Regardless of this keyword, the implicit counter variables (G36, G37) are restored when returning from the subprogram to the calling program.

Examples

SUBPROGRAM SUB1()                 ; no formal parameters
SUBPROGRAM DRILL(#depth : LREAL)
SUBPROGRAM SUB2(#a : LREAL, #b : STRING, #c : LREAL)
SUBPROGRAM SRM1() RESTORE_MODES

Syntax for the return

The return is done either at the end of the subprogram text (before the END_SUBPROGRAM) or explicitly with the following syntax: N<block number> RETURN.

Using the formal parameters in the subprogram

The values of the formal parameters can be accessed in the subprogram by #<ParamName>.

The number of formal parameters is limited to 21.

Example 48. Example
SUBPROGRAM SUB(#Param1 : LREAL)
N10 G01 X#Param1


Display of the call stack

The interpreter (SMC_NCInterpreter) has an output that contains the 10 top active programs/subprograms: aActivePrograms : ARRAY[0..9] OF STRING. The first entry (aActivePrograms[0]) is the currently interpreted program/subprogram. The second entry (aActivePrograms[1]) is the calling program/subprogram and so on. If there is no calling program, then the corresponding string is empty.

The call stack can also be displayed at interpolation time. The SMC_DisplayNCCallstack POU shows the active programs/subprograms in the same format as the interpreter, only later (namely when the movement is run). In doing so, the interpreter output CallstackInfo (SMC_NCCallstackInfo) and the interpolator are passed to it as VAR_IN_OUT variables. SMC_NCCallstackInfo stores all call stack changes, including the corresponding SMC_GeoInfo object number, in a ring buffer. At this time, this restricts the number of storable call stack changes between the interpretation time and the interpolation time to 128. Because the ring buffer does not meet multitasking criteria, SMC_DisplayNCCallstack has to be called from the interpreter task.

The sample program CNC Example 07: Using Expressions and Subprograms shows an example of the display of the call stack at interpolation time.