下面介绍 DIN 66025 标准下编写 codesys CNC 程序的一些基本规则。

结构

基本格式如下:

% MyProgram
N10 G01 X100 Y100 F100  (comment)
N20 M8 G01 Z40 F20
N30 G03 X-100 R200 F100
N40 SubPrg{5}

规则:

  • 以 % 标记程序头名称,也可以不写
  • 每行代码都是一个 block,每个 block 都需要以 block number 开头,如:N10
  • 一行只能定义一个 G 代码,G90 G01 需要单独两行写
  • M 代码可以和 G 代码一行
  • 小括号 () 中可以定义注释
  • 子程序传递参数用大括号 {} 定义

可用 G代码可以查询:DIN 66025 Fundamentals

暂停

语法:

N10 G4 T5  (停留5秒)

M 功能

当 cnc 程序中编写一个 M 功能时,如 M8,在 SMC_Interpolator 功能块中的 wM 会输出调用的 M 功能编号 8,同时会在此功能块等待输入确认信号 bAcknMtrue 并且清空 wM 信号,在此期间插补器会停留在原地等待。

如果需要在执行 M 功能的时候不中断当前正在进行的插补器动作,需要设置并执行 SMC_PreAcknowledgeM 功能块。但是如果M功能有传递参数 K L 等则不可激活此预完成功能,否则传递参数POU接收不到。

注意 M 功能编号中 65533–65535 是内部保留的,其他都是可以自定义的,包括 M30

如要执行下面 cnc 程序:

N15 G1 X10 F100
N20 M8
N21 G1 X50 F100
N30 M30

POU 代码加入如下:

VAR
    fbIpo       : SMC_Interpolator;   //插补器功能块
    fbPreAckM     : SM3_CNC.SMC_PreAcknowledgeMFunction;  //M 功能预完成功能  可不中断插补器动作  如果M功能有传递参数 则不可激活此功能
END_VAR

***************************************

IF fbIpo.wM = 30 THEN
    fbIpo(bAcknM:=TRUE);   //执行玩动作后触发完成信号
END_IF

fbPreAckM(bEnable:=TRUE,iM:=8,poqDataIn:=fbCheckVel.poqDataOut);  //激活指定M功能预完成  如果M功能有传递参数 则不可激活此功能
IF fbIpo.wM = 8 THEN
    gVars.lrR3 := 5;       //M功能需要执行的动作
    fbIpo(bAcknM:=TRUE);   //执行玩动作后触发完成信号
END_IF

可以在 CNC 程序调用 M 功能时定义传递参数,供POU使用,使用关键词 K L 即可。同时需要定义 SMC_GetMParameters 功能块获取到参数值,这里需要注意此功能块必须和 SMC_Interpolator 处于同一周期中,否则可能读取失败,建议同 SMC_Interpolator 定义在一个 POU 中。

带传递参数的 M 功能 CNC 程序示例如下:

N20 M8 K7

以上示例 POU 修改如下:

VAR
    fbIpo          : SMC_Interpolator;   //插补器功能块
    //fbPreAckM    : SMC_PreAcknowledgeMFunction; //屏蔽

    fbGetMPara    : SMC_GetMParameters;
END_VAR

***************************************

//fbPreAckM(bEnable:=TRUE,iM:=8,poqDataIn:=fbCheckVel.poqDataOut);  //屏蔽
IF fbIpo.wM = 8 THEN
    gVars.lrR3 := fbGetMPara.dK;;    //读取到 K 传递参数的数据
    fbIpo(bAcknM:=TRUE);             //执行玩动作后触发完成信号
END_IF

fbGetMPara(Interpolator:=fbIpo,bEnable:=TRUE);

跳转

有两种跳转方法,第一种是引用行号来跳转,可以定义从某一个程序段跳转到另一个程序段以及跳转的循环次数。第二种是通过自定义标记位来跳转,可以不用管行号,缺点是只能向后跳转以及不可循环跳转。

行号跳转语法:

G20 L K

L 定义需要跳转到的指定行号,K 定义跳转循环次数,当为 0 时停止跳转。当不写 K 时系统会模式使用内部变量计数。此功能需要配合赋值命令 G36 G37 使用。

使用内部变量计数示例:

N00 G36 D5              (设置内部变量初始为5 变量值为0时跳转关闭)
N10 G91                 (增量模式)
N20 G01 X10 Y10 F100    (每个循环移动的距离)
N30 G37 D-1             (给内部变量值减1)
N40 G20 L20             (内部变量值没到0时返回继续循环 N20)

使用自定义变量计数的示例:

N00 G36 O$R1$ D5        (设置变量R1初始为5 变量值为0时跳转关闭)
N10 G91                 (增量模式)
N20 G01 X10 Y10 F100    (每个循环移动的距离)
N30 G37 O$R1$ D-1       (给变量R1值减1)
N40 G20 L20 K$R1$       (变量R1值没到0时返回继续循环 N20)

G36 命令给变量赋值,G37 命令修改变量值。

此跳转命令有局限性,不可嵌套跳转,不可设置 K 值为常数,如:K2 写法是错误的。

自定义标记跳转:

N00 G20 L?4              (定义需要跳转到标记 4 只能索引到此程序后的标记  如果没有找到标记则程序停在此处)
N05 L!5                  (定义标记位置5)
N10 G1 X100 F100
N20 G1 Y100 L!4 F100     (定义标记位置4)

L? 定义需要跳转到的目标标记,L! 定义目标标记位。索引数字可以是任意整数,目标标记 L! 可以和 G 代码一行也可以单独一行定义。

使用自定义标记跳转时需要注意只能跳转到后面的程序行。

移动速度

可以通过 F 控制轴移动速度,E 控制加速度及减速度。

示例:

N10 G01 X100 Y50 F100 E10 E-20

注意 E 后面设置负数就是设置减速度。

全局自定义变量

支持定义自定义全局变量并在 cnc 程序中使用,通过 G36 G37 给变量赋值。

首先需要在 GVL 中对变量进行定义:

{attribute 'qualified_only'}
VAR_GLOBAL CONSTANT
    wVarsCount            : WORD:= 5;
END_VAR

VAR_GLOBAL
    lrR1                            : LREAL := 0;
    lrR2                            : LREAL := 0;
    lrR3                            : LREAL := 0;
    
    strVar1                         : STRING;
    
    lrSpeed                         : SM3_CNC.SMC_M_PARAMETERS; // M functions custom transfer parameter
    
    astVar                : ARRAY[0..wVarsCount-1] OF SMC_SingleVar := [
                                                    (strVarName := 'R1', pAdr := ADR(lrR1), eVarType := SMC_VARTYPE.SMC_TYPE_LREAL),
                                                    (strVarName := 'R2', pAdr := ADR(lrR2), eVarType := SMC_VARTYPE.SMC_TYPE_LREAL),
                                                    (strVarName := 'R3', pAdr := ADR(lrR3), eVarType := SMC_VARTYPE.SMC_TYPE_LREAL),
                                                    (strVarName := 'STR1', pAdr := ADR(strVar1), eVarType := SMC_VARTYPE.SMC_TYPE_STRING),
                                                    (strVarName := 'SPeed', pAdr := ADR(lrSpeed), eVarType := SMC_VARTYPE.SMC_TYPE_USERDEF)
                                                    ];
    
    stVarList            : SMC_VARLIST := (wNumberVars := wVarsCount, psvVarList := ADR(astVar));
END_VAR

然后再 POU 中的 SMC_ReadNCFile2 功能块指定 SMC_VARLIST 地址:

VAR
    fbReadFile    : SMC_ReadNCFile2;
END_VAR

************************************

fbReadFile(pvl := ADR(gVars.stVarList));

变量类型支持 int lreal string 等各种类型,cnc 程序中使用 GVL 里 strVarName 定义的名称。不支持定义 array 数组类型变量

cnc 程序调用语法:

$<Variablenname>$

通过 $ 包围变量名称即可,示例如下:

N50 G01 Y50 + $R2$ F300

G36 可以给变量赋值,G37 可以修改变量值:

N00 G36 O$R1$ D5        (设置变量R1初始为5)
N10 G37 O$R1$ D-1       (给变量R1值减1)

N20 G36 O$STR1$ D'NAME'              (设置字符串变量初始)
N30 G37 O$STR1$ D'=MARCO'            (给字符串变量值添加字符)

如果需要重启可保持型变量,需要将变量单独定义在 Persistent Variables 类型 object 中,具体参考:codesys 定义重启可保持型变量

子程序

子程序调用支持无参数和带参数传递的模式,传递参数类型支持:BOOL, LREAL, 和 STRING,且必须使用 SMC_ReadNCFile2SMC_NCInterpreter 来解码程序。子程序文件扩展名必须是 .cnc

子程序存储路径需要在 SMC_ReadNCFile2 中指定,支持定义4个目录作为子程序索引:

VAR
    aSubProgramDirs    : ARRAY[0..4] OF STRING[174]  := ['_cnc', ''];
    fbReadFile         : SMC_ReadNCFile2;
END_VAR

****************************

fbReadFile(aSubProgramDirs := aSubProgramDirs);

子程序框架语法如下:

SUBPROGRAM SUB_PROG_1{#VAR1:LREAL,#VAR2:STRING}
N20 G01 X#VAR1 Y#VAR1 F100
END_SUBPROGRAM

如果有传递参数则需要写在大括号 {} 中定义。井号 # 表示定义的局部变量名称,可在子程序中使用。

子程序调用方式如下:

SUB_PROG_1{}                    (无传递参数的子程序调用)
N55 SUB_PROG_1{$R3$,'ABC'}      (有传递参数的子程序调用)

SMC_NCInterpreter 功能块中的 aActivePrograms : ARRAY[0..9] OF STRING 存储程序级嵌套,aActivePrograms[0] 存储当前运行程序名称,aActivePrograms[1] 存储即将调用的子程序名称。

数学表达式

想要支持更多的计数表达式,必须使用 SMC_ReadNCFile2SMC_NCInterpreter 来解码程序。

常用的加减乘除三角函数都是支持的,注意需要使用大括号 {} 来控制计算层级。给变量赋值还是需要使用 G36 G37 实现。

示例如下:

N00 G36 O$STR1$ D CONCAT{'NAME','=MARCO'}           (链接两个字符串)
N35 G36 O$R1$ D SIN{30/180*PI}                      (三角函数单位为弧度, PI 表示 3.1415926)
N36 G36 O$R2$ D SQRT{$R1$} * 3
N40 G01 X 100 / 3 * 2

支持的运算符号如下:
2023-08-17T03:09:32.png

支持的运算功能如下:
2023-08-17T03:10:20.png

本地局部变量

上面介绍了如何定义全局变量,需要在 POU 中定义然后才能在 cnc 程序中使用。也可以定义在程序内部使用的局部变量,每个子程序内最多可以定义 21 个局部变量。

使用关键词 LET 定义变量,主程序中必须定义在程序最开头,子程序中必须定义在子程序名称下一行,不需要写 N 行号。

定义语法如下:

LET <FormalParam> [:= <InitialValue>]

<FormalParam> ::= <ParamName> : <ParamType>
<ParamName>   ::= #[a-zA-Z0-9_]+

<ParamType> ::= LREAL | BOOL | STRING ; 字符串最大255字节

示例如下:

%VAR_TEST
LET #VAR1 : LREAL
LET #VAR2 : LREAL := 3
LET #VAR3 : LREAL := #VAR2 - 1
LET #VAR4 : BOOL := #VAR1 > #VAR2
LET #VAR5 : STRING

N00 G36 O#VAR5 D'TEST'
N05 G36 O$STR1$ D#VAR5
N10 X#VAR2 +100 Y#VAR3 +50 F100

N55 SUB_PROG_1{$R3$,'ABC'}
SUBPROGRAM SUB_PROG_1{#VAR1:LREAL,#VAR2:STRING}
LET #AAA : LREAL := 10
N10 G91
N20 G01 X#VAR1 + #AAA Y#VAR1 F100
END_SUBPROGRAM

以上就是 codesys 中使用 DIN 66025 标准编写 CNC 程序的基本语法及功能讲解,更多功能参考:CNC Language in DIN 66025

标签:无

1 条评论

  1. ahxinny ahxinny

    很好。不过做起来好像很烦

你的评论