Beckhoff TC3 TE2000 HMI:如何通过参数在用户控件中调用PLC方法
问题背景
在Beckhoff TC3 TE2000 HMI环境中创建带按钮的用户控件,目标是从实例化的控件中调用PLC方法。已通过带HMI访问pragma的DUT将所需数据关联到用户控件实例参数,显式指定方法路径的调用可正常运行:
TcHmi.Symbol.readEx2("%s%factoryPLC.MAIN.fbRobot::fbEM01_Robot::fbCM04_Compressor::M_Start%/s%", function (data) { console.log(data); });
但通过控件参数间接调用以支持多实例时失败:
TcHmi.Symbol.readEx2("%pp%cmData::M_Start%/pp%", function (data) { console.log(data); });
触发错误:
Object { error: 2030, value: undefined, details: {…} } details: Object { code: 2030, message: "E_SYMBOL_INVALID_PATH", reason: '%pp%UserControl1_8::cmData::M_Start%/pp%: Failed to read value by path because the token: "M_Start" does not exist below path: "UserControl1_8::cmData" in current value.', … }
手册语句解读
Beckhoff Infosys手册中的这句话:
Methods must always be called explicitly and cannot be used as a control attribute. Note that calling a method from the HMI results in the execution of PLC code.
其中cannot be used as a control attribute的实际含义是:不能将PLC方法直接绑定为用户控件的属性参数。HMI在解析控件实例参数时,只会识别数据类型的变量(比如DUT实例),无法直接解析参数路径中的方法节点,所以你没法通过%pp%cmData::M_Start%/pp%这种方式间接指向PLC方法。
可行间接调用方案
方案1:传递完整方法符号路径作为控件参数
- 放弃绑定DUT实例到控件参数,改为添加一个字符串类型的控件参数(比如命名为
MethodFullPath) - 实例化控件时,直接填入目标PLC方法的完整全局符号路径(例如
%s%factoryPLC.MAIN.fbRobot::fbEM01_Robot::fbCM04_Compressor::M_Start%/s%) - 控件内部直接使用该参数调用方法:
// 获取控件参数中的完整方法路径 const methodPath = this.getAttribute("MethodFullPath"); TcHmi.Symbol.readEx2(methodPath, function (data) { console.log(data); });
方案2:传递DUT路径+手动拼接方法名
如果必须保留DUT实例参数传递,可以在控件内部手动拼接完整方法路径:
// 获取控件参数中的DUT相对路径 const dutRelativePath = "%pp%cmData%/pp%"; // 转换为全局符号路径并拼接方法名 TcHmi.Symbol.getSymbolPath(dutRelativePath, function (pathResult) { if (!pathResult.error) { const fullMethodPath = `${pathResult.value}::M_Start`; TcHmi.Symbol.readEx2(fullMethodPath, function (data) { console.log(data); }); } });
该方案利用TcHmi.Symbol.getSymbolPath将控件参数的相对路径转换为全局符号路径,再拼接方法名后调用。
方案3:通过DUT传递方法路径字符串
在PLC的DUT中新增一个字符串类型变量(比如MethodStartPath),在PLC代码中预先赋值为该DUT实例下M_Start方法的完整符号路径,然后将DUT绑定到控件参数。控件内部读取该字符串变量的值,再调用方法:
// 先读取DUT中的方法路径变量 TcHmi.Symbol.readEx2("%pp%cmData.MethodStartPath%/pp%", function (pathData) { if (!pathData.error) { // 使用读取到的路径调用方法 TcHmi.Symbol.readEx2(pathData.value, function (data) { console.log(data); }); } });
此方案需要在PLC层预先维护方法路径,适合需要批量管理多个方法的场景。
内容的提问来源于stack exchange,提问作者wouters

