Marco Nie - CODESYS https://blog.niekun.net/category/codesys/ codesys enum 枚举数据类型单元的使用 https://blog.niekun.net/archives/codesys-enum.html 2024-03-07T08:21:07+08:00 enum 类型的 dut 可以定义一组属性及其值,调用的时候可以方便的通过写其属性名称得到属性的值,也可以获取到属性本身的名称。下面举一个例子说明:{attribute 'qualified_only'} // 必须先写类型名称再写属性名称 (例如 eColor.Red) // {attribute 'strict'} //取消 'strict' 以允许转换 UDINT 数据类型 {attribute 'to_string'} // 运行字符串转换 (例如 TO_STRING(eColor.Red) = 'Red') TYPE eColor : ( Red := 16#FFFF0000, Green := 16#FF00FF00, Blue := 16#FF0000FF Yellow := 16#FFFFFF00, ) UDINT; // 声明 UDINT 作为 int 整形类型 END_TYPE // 定义一些变量 ColorVar1 : eColor; ColorVar2 : eColor; ColorName : STRING; ColorValue : UDINT; ColorVar1 := eColor.Green; // ColorVar1 = 16#FF00FF00 ColorName := TO_STRING(ColorVar1); // ColorName = 'Green'; ColorValue := TO_UDINT(ColorVar1); // ColorValue = 16#FF00FF00 ColorVar2 := 16#FF00FF00; // ColorVar2.Green ColorName := TO_STRING(ColorVar2); // ColorName = 'Green'; ColorValue := TO_UDINT(ColorVar2); // ColorValue = 16#FF00FF00 ColorVar1 := ColorVar2 OR eColor.Red; // 按位相与得到 Yellow=16#FFFFFF00 ColorName := TO_STRING(ColorVar1); // ColorName = 'Yellow'; ColorValue := TO_UDINT(ColorVar1); // ColorValue = 16#FFFFFF00以上示例列举了常用的 enum 类型可进行的数据交互方式。eColor.Green 可以获取enum类型属性的值,并可以赋值给其他对应 enum 实例TO_STRING(ColorVar1) 可以转换获取 enum 实例当前值对应属性名称字符串 codesys 常见编译及下载时报错解决方法 https://blog.niekun.net/archives/codesys.html 2024-03-06T16:35:00+08:00 No source code available for this object下载时出现此报警,原因是 task 任务中对 gou 的排序有问题,放在前面的 pou 中使用了后面 pou 才设定好的数据,需要重新排列 task 任务序列:SMC_FB_CALLED_FROM_WRONG_TASKmc_power mc_jog 等控制轴的功能块,一运行就报错 SMC_FB_CALLED_FROM_WRONG_TASK,可能是不同的 pou 放在了多个 task 任务中,循环中内部有了冲突,将所有的 pou 放在同一个 task 中就可以解决问题。 RTE runtime添加 ethercat master 的步骤 https://blog.niekun.net/archives/ethercat.html 2024-02-23T15:41:00+08:00 codesys 配置 rte runtime 添加 ethercat 组件的方法。主要步骤为:安装 RTE runtime安装适配网卡驱动添加 ethercat master 设备安装 RTE runtime首先需要配置工控机啊 BIOS 设置,将一些超线程,电源管理等选项关掉:关闭超线程:关闭BIOS 中激活的所有节能选项Intel Speed Step动态节能技术EIST智能降频C-States省电模式PowerNow动态调整CPU的工作频率和电压Hibernation休眠MWAIT停用可能导致系统管理中断的所有内容BIOS self tests BIOS自检USB Legacy Device Support 传统USB设备支持然后就可以安装 RTE,官网下载需要的 runtime 安装包,注意区分 x86 还是 x64 设备。我下载的是 **CODESYS Control RTE SL (×86Windows 实时)。官网下载地址:http://store.codesys.cn/codesys/store/index.html在工控机上解压并安装需要的 RTE runtime,基本都是直接下一步即可,期间注意选择带不带 softmotion:Control RTE 文件路径:C:\Program Files\CODESYS\CODESYS Control RTE3Control RTE 安装路径:C:\ProgramData\CODESYS\CODESYSControlRTEV3网卡驱动支持的网卡:Systems with Windows and CODESYS Control RTE (Real-time SoftPLC):Realtek® 8139 (CmpRTL81x9Mpd)Realtek RTL8139 and compatible Ethernet-Controller, as well 8100/8110Realtek 8169 (CmpRTL8169Mpd)Realtek 8169/810, RTL8111B / RTL8111DIntel® EtherExpressPro1000 (CmpEt1000Drv) --- All gigabit adapters from IntelIntel EtherExpress PRO/100 (CmpEt100Drv) --- All 100 Mbit adapters from Intel一般情况下 intel 的千兆网卡都可以安装 CmpEt1000Drv 驱动。首先进入设备管理器,选择需要更新 codesys 驱动的网卡,右键选择更新驱动:选择从本地查找驱动程序:选择从磁盘安装,从 RTE 文件路径找到对应的驱动目录并安装:右键选择 plc configuration:在 components manager 中在最后一个空行中填入安装的驱动名称,这里我填的是 CmpEt1000Drv:确定并重启 plc 即可完成网卡驱动的安装及配置。添加 ethercat master在codesys 开发项目中进行以下操作。建立一个支持 softmotion 的设备添加 ethercat master softmotion 主站 (会自动添加 ethercat_task 任务 不可删除)扫描并连接到控制器配置 ethercat master 网卡,RTE 版 runtime 需要选择适配 codesys 的网卡下载程序到控制器,如果上面没有在 components manager 中添加网卡组件的话,这里下载会报错退出登录 扫描从站并添加如果设备描述文件没有在系统内置库中 需要手动导入描述文件然后才能扫描识别给扫描到的从站添加 cia402 轴配置电子齿轮比以上就是 RTE runtime 版添加 ethercat master 主站的简单方法。参考链接:Control RTE SL and profinet connections codesys 使用占位符定义界面变量显示格式 https://blog.niekun.net/archives/2857.html 2023-09-22T10:33:00+08:00 在编程中我们会使用各种类型的变量进行逻辑运算,不同类型其默认数据精度取值不一样,比如浮点型变量文本占位符为 %f 默认小数位数 6 位,但实际只想显示 3 位小数,此时就需要将界面变量的占位符进行设置以满足需求。int 整型语法:% <标记> <最小显示数字个数> <类型> 标记:定义数据显示模式,可选项:- 当定义最小显示数字个数时 居左显示,+ 显示数据正负号,0 当定义最小显示数字个数时空缺位显示 0最小显示数字个数:定义最少占据几个数字空间,默认数据位数不够时留空类型:显示数据类型,如:d十进制, b二进制, o八进制, x十六进制示例:%-5d:最小显示位数5位,且居左对齐显示,例如数据值为123时:`123 ` %+d:显示数据正负号,例如数据值为123时:`+123` %05d:最小显示位数5位,且空缺位显示0,例如数据值为234时:`00234` %08b:显示8位数的二进制模式,例如数据值为255时:`11111111` %04x:显示4位数的十六进制模式,例如数据值为15时:`000f`float 浮点型语法:% <标记> <最小显示数字个数> . <精度> f 标记:定义数据显示模式,可选项:- 当定义最小显示数字个数时 居左显示,+ 显示数据正负号,0 当定义最小显示数字个数时空缺位显示 0最小显示数字个数:定义最少占据几个数字空间,包括小数位,默认数据位数不够时留空,不定义时默认为 %1.6f精度:小数位的显示精度示例:%-12.9f:显示12位数字 9位小数,且居左显示 %+6.3f:显示6位数字3位小数,且显示正负号标记 %06.3f:显示6位数字3位小数,且空缺位补0显示时间类型语法:%t[ <text> <time in unit> <text> ] 示例:// 定义一个时间变量并给其赋值 ltTimeSpan : LTIME := LTIME#1D2H3M4S5MS6US7NS; 在一个 label 中定义: text variable 设置:PLC_PRG.ltTimeSpan text 占位符设置:Time span: %t[d] d 输出结果:Time span: 1 d可用的占位符:%t[d] 天,%t[dd] 两位数字的天,%t[H] 小时,%t[HH] 两位数字小时,%t[m]分钟,%t[mm] 两位数分钟,%t[s] 秒,%t[ss] 两位数秒。也可以组合起来使用:TEXT 占位符设置:%t[Value: dd-HH:mm:ss:ms:us:ns] 输出结果:Value: 01-02:03:04:005:006:007如果不定义 label 的 text variable 属性,则会输出系统当前时间。日期类型语法:%t[ <date and time unit> ] 和时间类型类似的用法,下面举例说明://定义一个 date 类型变量 dateBy : DATE := DATE#2021-02-12; 在一个 label 中定义: text variable 设置:PLC_PRG.dateBy text 占位符设置:Date: %t[yyyy-MM-dd dddd] 输出结果:Date: 2/12/2021 Friday可用占位符:%t[yyyy] 年,%t[yy] 两位数年,%t[y]一位数年,%t[MMMM] 英文月份,%t[MMM]英文简写月份,%t[MM]月份,%t[ddddd] 一周的第几天,%t[dddd]英文周几,%t[dd]一个月的第几天,%t[jjj]一年中的第几天,如果不定义 label 的 text variable 属性,则会输出系统当前日期。字符语法:%s 参考链接Placeholders with Format Definition codesys 定义重启可保持型变量 https://blog.niekun.net/archives/2840.html 2023-08-18T14:09:00+08:00 无论是在 gvl 或者 pou 中都可以定义变量,默认情况下这些变量在系统重启后数据都会丢失。某些情况下我们希望变量值可以保持,系统重启后原数据也不丢失。可以在变量定义块中通过关键词 RETAIN 和 PERSISTENT 来实现。注意 PERSISTENT 类型变量必须定义在单独的 Persistent Variables 类型 object 才能生效。而不是通常的 GVL object。RETAINRETAIN 可以在热重启后保持数据:In a POU: VAR RETAIN iRem1 : INT; END_VAR ******************* In a GVL: VAR_GLOBAL RETAIN gvarRem1 : INT; END_VAR以下情况下 RETAIN 数据会被重置:the command Reset originthe command Reset cold (as opposed to persistent variables)a repeated program downloadPERSISTENT首先需要新建 Persistent Variables 类型 object 会放在 task 子目录下:然后会自动创建 VAR_GLOBAL PERSISTENT RETAIN 类型全局变量文件。PERSISTENT 可以在热重启和冷重启后保持数据:VAR_GLOBAL PERSISTENT iVarPers1 : DINT; bVarPers : BOOL; PLC_PRG.PERS: INT; END_VAR以下情况下 PERSISTENT 数据会被重置:the command Reset origin从 CODESYS V3.3.0.1 开始声明一个 VAR_GLOBAL PERSISTENT 等效于 VAR_GLOBAL PERSISTENT RETAIN or VAR_GLOBAL RETAIN PERSISTENT。以下是各种变量定义模式下数据保持情况: after online commandVARVAR RETAINVAR PERSISTENTReset warm xxCold reset xReset origin Download xOnline Changexxx参考链接Remanent Variables - RETAIN, PERSISTENTREMANENT VARIABLES: RETAIN VS PERSISTENT RETAIN codesys 中使用 DIN 66025 标准编写 CNC 程序 https://blog.niekun.net/archives/2835.html 2023-08-16T15:33:00+08:00 下面介绍 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,同时会在此功能块等待输入确认信号 bAcknM 为 true 并且清空 wM 信号,在此期间插补器会停留在原地等待。如果需要在执行 M 功能的时候不中断当前正在进行的插补器动作,需要设置并执行 SMC_PreAcknowledgeM 功能块。但是如果M功能有传递参数 K L 等则不可激活此预完成功能,否则传递参数POU接收不到。注意 M 功能编号中 65533–65535 是内部保留的,其他都是可以自定义的,包括 M30。如要执行下面 cnc 程序:N15 G1 X10 F100 N20 M8 N21 G1 X50 F100 N30 M30POU 代码加入如下: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 KL 定义需要跳转到的指定行号,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$ F300G36 可以给变量赋值,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_ReadNCFile2 和 SMC_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_ReadNCFile2 和 SMC_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支持的运算符号如下:支持的运算功能如下:本地局部变量上面介绍了如何定义全局变量,需要在 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 codesys 运行时调用外部G代码文件的编程路径 https://blog.niekun.net/archives/2833.html 2023-08-15T10:12:00+08:00 在下载到真实设备上和 simulation 模式时,调试时需要引用的路径是不一样的。不管是哪种模式下,codesys 本身运行的一个容器环境根目录是如下:PlcLogic 文件夹是 POU 运行的根目录,所有 G 代码文件的索引都是以此目录为根目录的。在程序中定义路径地址的时候只需要写 POU 根目录的子路径即可。simulation 模拟在电脑上进行运动控制模拟时,如果需要调用外部G代码程序,模拟环境下的程序运行根目录为 C:\ProgramData\CODESYS\Simulation\PlcLogic\。将G代码程序文件放入上述目录下使用即可调用,如:strFileName : STRING(120) := 'NCReadFromFile.txt';一般可以新建一个子路径 _cnc 将程序都放入其中:strFileName : STRING(120) := '_cnc/NCReadFromFile.txt';注意每次重启 codesys IDE 会重置 C:\ProgramData\CODESYS\Simulation\PlcLogic\ 目录,需要重新复制程序进来。真实设备首先需要知道工控机安装的是什么类型的控制器:information 菜单下可以查看当前控制器类型:windows 下 codesys runtime 安装路径为:C:\ProgramData\CODESYS,目录中包含所有已经安装的各种类型的控制器,每个控制器类型都有其单独目录:进入需要的控制器目录后,就可以看到运行 codesys 的容器文件夹了:这个文件夹就是 codesys 在控制器上的运行环境,只需要将 G 文件放入 PlcLogic 文件夹下,同时 POU 中路径只需要定义此根路径的子目录即可。也可以通过 IDE 在线传输文件到控制器指定目录: codesys 项目修改依赖库的版本 https://blog.niekun.net/archives/2829.html 2023-08-15T08:08:54+08:00 打开一个别人的项目后编译,发现出现 The library "caa behaviour model, 3.5.19.0 (caa technical workgroup)" was created with the unknown compiler version "3.5.16.30" 的报错:但是我已经选择下载了缺失的库了,查询后发现是我的 codesys 版本过高,下载的对应库版本也高,而项目之前创建的时候可能是基于低版本库的,需要手动切换回对应版本的库即可。library manager 下选择 placeholders 定位到报错的那个库:双击后显示版本菜单,选择对应低版本的选项:再次编译报错就会消失。