User-Specific G-Code Functions
The CNC11_CustomFunctions.project
sample project is located in the installation directory of CODESYS under ..\CODESYS SoftMotion\Examples
.
This example shows how to create your own functions for use in expressions in G-code.
For more information about expressions and functions in G-code, see: Expressions. There you will find a list of all operators and functions supported by default.
The example defines the SEL operator from IEC 61131-3 so that it can also be used in G-code.
Structure of the application
As usual for CNC applications, the application consists of path processing (CNC_PreparePath
program) and interpolation (CNC
program). Because the interpolation does not differ from the other examples, the topic will not be discussed further here.
Path processing is called cyclically every 20 ms in the low-priority PathTask
. The interpolation is called cyclically every 4 ms in the high-priority MotionTask
. The background task VISU_TASK
is defined for the visualization.
In the visualization, you can start processing the G-code and set the value of the variable $LONGLINE$
. The G-code and the movement of the machine (3D gantry) are displayed on the right side of the visualization.
The G-code
CNC
LET #WIDTH : LREAL N10 G36 O#WIDTH D SEL($LONGLINE$, 40, 110) N20 F50 E100 E-100 N30 G01 X#WIDTH Y#WIDTH Z#WIDTH/2 N40 Y-#WIDTH N50 X-#WIDTH Z-#WIDTH/2 N60 Y#WIDTH N70 X0 Y0 Z0
Line 1: Declaration of the local variable #WIDTH
of type LREAL
.
Line 2, Block N10: Assignment of the value of SEL($LONGLINE$, 40, 110)
to the variable #WIDTH
. If the value of the PLC variable $LONGLINE$
is TRUE
, then the value of the expression is 110; otherwise it is 40.
In the following lines, a rectangle with additional movement in the Z-direction is traversed; the length of one side of the rectangle is 2*#WIDTH
.
Implementation of the SEL
function

To create a user-defined function, you need to write a function block which implements the SMC_NC_IFunction
interface.
For more information, see: SMC_NC_IFunction.
GetSignature
. The return type, the count, and the types of the arguments of the function are returned here. In this example, theSEL
function returns a value of typeT_OTHER
and has 3 arguments of typeT_BOOL
,T_OTHER
, andT_OTHER
.T_OTHER
stands for any type (eitherT_BOOL
,T_LREAL
, orT_STRING
]. All 3 occurrences ofT_OTHER
must have the same type.METHOD GetSignature VAR_OUTPUT resultType : SMC_GVar_Type; nNumArguments : UDINT; pType : POINTER TO SMC_GVar_Type; END_VAR VAR argTypes : ARRAY[0..2] OF SMC_GVar_Type := [SMC_GVar_Type.T_BOOL, SMC_GVar_Type.T_OTHER, SMC_GVar_Type.T_OTHER]; END_VAR resultType := SMC_GVAR_Type.T_OTHER; nNumArguments := 3; pType := ADR(argTypes);
Call
: This method is called when the G-code is being processed. The arguments are passed via thepa
input. The expressionpa[0].argValue.bValue
is used to access the Boolean value of the first argument. Depending on the type of the second argumentpa[1].argType
, the result is the return valueresult.argType
and the branching into a CASE statement.METHOD Call VAR_IN_OUT result : SMC_NC_GArgument; END_VAR VAR_INPUT pa : POINTER TO SMC_NC_GArgument; END_VA RVAR_OUTPUT eError : SMC_ERROR; END_VAR VAR g : BOOL; END_VAR g := pa[0].argValue.bValue; result.argType := pa[1].argType; CASE result.argType OF SMC_GVAR_Type.T_BOOL: result.argValue.bValue := SEL(g, pa[1].argValue.bValue, pa[2].argValue.bValue); SMC_GVAR_Type.T_STRING: result.argValue.sValue := SEL(g, pa[1].argValue.sValue, pa[2].argValue.sValue); SMC_GVAR_Type.T_LREAL: result.argValue.fValue := SEL(g, pa[1].argValue.fValue, pa[2].argValue.fValue); ELSE eError := SMC_INVALID_PARAMETER; END_CASE
Configuration of SMC_ReadNCFile2
An instance of the CNC_Sel
function block is created in the GVL_CNCFunctions
global variable list.
An array aCNCFunctions
of length 1 is initialized with the name and instance of the function block. This array is then linked in the table funTable
of type SMC_NC_GFunctionTable
.
aCNCFunctions : ARRAY[0..0] OF SMC_NC_GFunction := [(stName:= 'SEL', iFunc:= GVL_CNCFunctions.g_Sel)]; funTable : SMC_NC_GFunctionTable := (numFunctions:= 1, pFunction:= ADR(aCNCFunctions)) ;
Finally, this table is passed to the SMC_ReadNCFile2
function block:
rncf2 : SMC_ReadNCFile2 := (bParenthesesAsComments:= FALSE); [...] rncf2( bExecute:= TRUE, sFileName:= sFileName, pCustomFunTable:= ADR(funTable), pvl:= ADR(varList));
Commissioning
Build the application and download it to a controller.
Start the application, switch to the visualization, and press
Start
. You can use theLongline
radio button to set the value of the variable$LONGLINE$
in the G-code toTRUE
orFALSE
.