Marco Nie - Development https://blog.niekun.net/category/dev/ zh-CN Mon, 01 Jul 2024 10:17:13 +0800 Mon, 01 Jul 2024 10:17:13 +0800 使用虚拟环境 env 开发 python https://blog.niekun.net/archives/env-python.html https://blog.niekun.net/archives/env-python.html Mon, 01 Jul 2024 10:17:13 +0800 admin 使用虚拟环境进行Python开发有助于隔离项目的依赖,避免不同项目之间的库版本冲突。以下是如何创建和使用虚拟环境的详细步骤。

Python 3.3 及以上版本自带 venv 模块,可以直接使用。

使用 venv 创建虚拟环境

创建虚拟环境

在你的项目目录下,运行以下命令来创建一个虚拟环境,这将在项目目录下创建一个名为 myenv 的文件夹,其中包含虚拟环境的所有文件:

python -m venv myenv

激活虚拟环境

Windows:

myenv\Scripts\activate

macOS 和 Linux:

source myenv/bin/activate

安装依赖

在虚拟环境中,你可以使用 pip 来安装项目所需的库:

pip install requests

安装的库将只会影响当前虚拟环境,而不会影响系统的 Python 环境或其他项目。

冻结依赖

为了确保你的项目依赖可以在其他环境中重现,你可以使用以下命令将当前环境的依赖写入 requirements.txt 文件:

pip freeze > requirements.txt

requirements.txt 文件将包含所有当前环境中的安装包及其版本信息。

使用 requirements.txt 安装依赖

在新的环境中,你可以使用 requirements.txt 文件来安装所需的所有依赖:

pip install -r requirements.txt

退出虚拟环境

当你完成工作时,可以通过以下命令退出虚拟环境:

deactivate

使用虚拟环境进行Python开发可以有效地隔离项目依赖,避免版本冲突。通过创建和激活虚拟环境、安装依赖、冻结依赖并在新环境中重新安装依赖,可以确保你的项目在不同环境中具有一致的运行表现。

]]>
0 https://blog.niekun.net/archives/env-python.html#comments https://blog.niekun.net/feed/category/dev/archives/env-python.html
codesys enum 枚举数据类型单元的使用 https://blog.niekun.net/archives/codesys-enum.html https://blog.niekun.net/archives/codesys-enum.html Thu, 07 Mar 2024 08:21:07 +0800 admin 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 实例当前值对应属性名称字符串

]]>
0 https://blog.niekun.net/archives/codesys-enum.html#comments https://blog.niekun.net/feed/category/dev/archives/codesys-enum.html
codesys 常见编译及下载时报错解决方法 https://blog.niekun.net/archives/codesys.html https://blog.niekun.net/archives/codesys.html Wed, 06 Mar 2024 16:35:00 +0800 admin No source code available for this object

下载时出现此报警,原因是 task 任务中对 gou 的排序有问题,放在前面的 pou 中使用了后面 pou 才设定好的数据,需要重新排列 task 任务序列:
image.png

SMC_FB_CALLED_FROM_WRONG_TASK

mc_power mc_jog 等控制轴的功能块,一运行就报错 SMC_FB_CALLED_FROM_WRONG_TASK,可能是不同的 pou 放在了多个 task 任务中,循环中内部有了冲突,将所有的 pou 放在同一个 task 中就可以解决问题。

]]>
0 https://blog.niekun.net/archives/codesys.html#comments https://blog.niekun.net/feed/category/dev/archives/codesys.html
RTE runtime添加 ethercat master 的步骤 https://blog.niekun.net/archives/ethercat.html https://blog.niekun.net/archives/ethercat.html Fri, 23 Feb 2024 15:41:00 +0800 admin codesys 配置 rte runtime 添加 ethercat 组件的方法。

主要步骤为:

  • 安装 RTE runtime
  • 安装适配网卡驱动
  • 添加 ethercat master 设备

安装 RTE runtime

首先需要配置工控机啊 BIOS 设置,将一些超线程,电源管理等选项关掉:

  • 关闭超线程:
    image.png
  • 关闭BIOS 中激活的所有节能选项

    • Intel Speed Step动态节能技术
    • EIST智能降频
    • C-States省电模式
    • PowerNow动态调整CPU的工作频率和电压
    • Hibernation休眠
    • MWAIT
  • 停用可能导致系统管理中断的所有内容

    • BIOS self tests BIOS自检
    • USB Legacy Device Support 传统USB设备支持

    image.png

然后就可以安装 RTE,官网下载需要的 runtime 安装包,注意区分 x86 还是 x64 设备。我下载的是 **CODESYS Control RTE SL (×86Windows 实时)。

官网下载地址:http://store.codesys.cn/codesys/store/index.html

在工控机上解压并安装需要的 RTE runtime,基本都是直接下一步即可,期间注意选择带不带 softmotion:
image.png

Control RTE 文件路径:C:\Program Files\CODESYS\CODESYS Control RTE3
Control 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/8110
  • Realtek 8169 (CmpRTL8169Mpd)
  • Realtek 8169/810, RTL8111B / RTL8111D
  • Intel® EtherExpressPro1000 (CmpEt1000Drv) --- All gigabit adapters from Intel
  • Intel EtherExpress PRO/100 (CmpEt100Drv) --- All 100 Mbit adapters from Intel

一般情况下 intel 的千兆网卡都可以安装 CmpEt1000Drv 驱动。

首先进入设备管理器,选择需要更新 codesys 驱动的网卡,右键选择更新驱动:
image.png

选择从本地查找驱动程序:
image.png

选择从磁盘安装,从 RTE 文件路径找到对应的驱动目录并安装:
image.png
image.png

右键选择 plc configuration:
image.png

在 components manager 中在最后一个空行中填入安装的驱动名称,这里我填的是 CmpEt1000Drv:
image.png

确定并重启 plc 即可完成网卡驱动的安装及配置。

添加 ethercat master

在codesys 开发项目中进行以下操作。

  • 建立一个支持 softmotion 的设备
  • 添加 ethercat master softmotion 主站 (会自动添加 ethercat_task 任务 不可删除)
  • 扫描并连接到控制器
  • 配置 ethercat master 网卡,RTE 版 runtime 需要选择适配 codesys 的网卡
    image.png
    image.png
  • 下载程序到控制器,如果上面没有在 components manager 中添加网卡组件的话,这里下载会报错
  • 退出登录 扫描从站并添加
    image.png
    image.png
  • 如果设备描述文件没有在系统内置库中 需要手动导入描述文件然后才能扫描识别
    image.png
    image.png
    image.png
  • 给扫描到的从站添加 cia402 轴
    image.png
  • 配置电子齿轮比
    image.png

以上就是 RTE runtime 版添加 ethercat master 主站的简单方法。

参考链接:

Control RTE SL and profinet connections

]]>
0 https://blog.niekun.net/archives/ethercat.html#comments https://blog.niekun.net/feed/category/dev/archives/ethercat.html
Siemens 系统计算精度设置影响程序运行问题 https://blog.niekun.net/archives/2858.html https://blog.niekun.net/archives/2858.html Wed, 18 Oct 2023 17:13:10 +0800 admin 最近的工作中遇到使用带刀具的轨迹运动中,由于轨迹是通过1000多个离散点构成的,每个点之间距离很短,由于 sinumerik one 系统默认的线性计算精度是每毫米 1000 各单位,导致刀具轨迹报错提示可能有碰撞危险。通过提高系统计算精度可以解决此问题。

相关系统变量:

  • 通用机床数据 10200 线性位置的计算精度
  • 通用机床数据 10210 角位置的计算精度

sinumerik one 及 840D sl 系统以上参数默认值为 1000,828D 系统默认值为 1000000。

]]>
0 https://blog.niekun.net/archives/2858.html#comments https://blog.niekun.net/feed/category/dev/archives/2858.html
codesys 使用占位符定义界面变量显示格式 https://blog.niekun.net/archives/2857.html https://blog.niekun.net/archives/2857.html Fri, 22 Sep 2023 10:33:00 +0800 admin 在编程中我们会使用各种类型的变量进行逻辑运算,不同类型其默认数据精度取值不一样,比如浮点型变量文本占位符为 %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

]]>
0 https://blog.niekun.net/archives/2857.html#comments https://blog.niekun.net/feed/category/dev/archives/2857.html
codesys 定义重启可保持型变量 https://blog.niekun.net/archives/2840.html https://blog.niekun.net/archives/2840.html Fri, 18 Aug 2023 14:09:00 +0800 admin 无论是在 gvl 或者 pou 中都可以定义变量,默认情况下这些变量在系统重启后数据都会丢失。某些情况下我们希望变量值可以保持,系统重启后原数据也不丢失。可以在变量定义块中通过关键词 RETAINPERSISTENT 来实现。

注意 PERSISTENT 类型变量必须定义在单独的 Persistent Variables 类型 object 才能生效。而不是通常的 GVL object。

RETAIN

RETAIN 可以在热重启后保持数据:

In a POU:

VAR RETAIN
 iRem1 : INT;
END_VAR

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

In a GVL:

VAR_GLOBAL RETAIN
 gvarRem1 : INT;
END_VAR

以下情况下 RETAIN 数据会被重置:

  • the command Reset origin
  • the command Reset cold (as opposed to persistent variables)
  • a repeated program download

PERSISTENT

首先需要新建 Persistent Variables 类型 object 会放在 task 子目录下:
2023-08-24T00:59:33.png

然后会自动创建 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 PERSISTENT
Reset warm xx
Cold reset x
Reset origin
Download x
Online Changexxx

参考链接

Remanent Variables - RETAIN, PERSISTENT
REMANENT VARIABLES: RETAIN VS PERSISTENT RETAIN

]]>
0 https://blog.niekun.net/archives/2840.html#comments https://blog.niekun.net/feed/category/dev/archives/2840.html
codesys 中使用 DIN 66025 标准编写 CNC 程序 https://blog.niekun.net/archives/2835.html https://blog.niekun.net/archives/2835.html Wed, 16 Aug 2023 15:33:00 +0800 admin 下面介绍 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 https://blog.niekun.net/archives/2835.html#comments https://blog.niekun.net/feed/category/dev/archives/2835.html
codesys 运行时调用外部G代码文件的编程路径 https://blog.niekun.net/archives/2833.html https://blog.niekun.net/archives/2833.html Tue, 15 Aug 2023 10:12:00 +0800 admin 在下载到真实设备上和 simulation 模式时,调试时需要引用的路径是不一样的。

不管是哪种模式下,codesys 本身运行的一个容器环境根目录是如下:
2023-08-23T07:03:29.png

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\ 目录,需要重新复制程序进来。

真实设备

首先需要知道工控机安装的是什么类型的控制器:
2023-08-23T07:18:32.png

information 菜单下可以查看当前控制器类型:
2023-08-23T07:20:03.png

windows 下 codesys runtime 安装路径为:C:\ProgramData\CODESYS,目录中包含所有已经安装的各种类型的控制器,每个控制器类型都有其单独目录:
2023-08-23T07:21:48.png

进入需要的控制器目录后,就可以看到运行 codesys 的容器文件夹了:
2023-08-23T07:22:46.png

这个文件夹就是 codesys 在控制器上的运行环境,

只需要将 G 文件放入 PlcLogic 文件夹下,同时 POU 中路径只需要定义此根路径的子目录即可。

也可以通过 IDE 在线传输文件到控制器指定目录:
2023-08-23T07:25:20.png

]]>
0 https://blog.niekun.net/archives/2833.html#comments https://blog.niekun.net/feed/category/dev/archives/2833.html
codesys 项目修改依赖库的版本 https://blog.niekun.net/archives/2829.html https://blog.niekun.net/archives/2829.html Tue, 15 Aug 2023 08:08:54 +0800 admin 打开一个别人的项目后编译,发现出现 The library "caa behaviour model, 3.5.19.0 (caa technical workgroup)" was created with the unknown compiler version "3.5.16.30" 的报错:
2023-08-15T00:04:07.png

但是我已经选择下载了缺失的库了,查询后发现是我的 codesys 版本过高,下载的对应库版本也高,而项目之前创建的时候可能是基于低版本库的,需要手动切换回对应版本的库即可。

library manager 下选择 placeholders 定位到报错的那个库:
2023-08-15T00:06:21.png

双击后显示版本菜单,选择对应低版本的选项:
2023-08-15T00:08:09.png

再次编译报错就会消失。

]]>
0 https://blog.niekun.net/archives/2829.html#comments https://blog.niekun.net/feed/category/dev/archives/2829.html