You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过C++ ADS代码调用TwinCAT ST中Function块内的方法?

在C++中通过ADS库调用FB_CALCULATOR的TestMethod方法

C++ ADS库没有像C#那样封装直接调用FB方法的高层函数,但可以通过符号寻址结合ADS读写操作实现,核心逻辑是写入方法的触发位来执行调用;若方法需要参数或返回值,只需先读写对应的FB输入/输出变量,再触发方法即可。

完整代码示例

#include <windows.h>
#include <iostream>
#include "AdsLib.h"

int main() {
    // 初始化ADS库
    AdsLibInit();

    // 配置PLC的ADS地址
    AmsAddr plcAddr;
    // 设置本地设备NetId(根据你的PC/设备实际NetId修改)
    AdsSetLocalAddress(AmsNetId{1, 2, 3, 4, 1, 1});
    // 设置PLC的NetId(替换为你的PLC实际NetId)
    AdsGetNetIdFromStr(plcAddr.netId, "192.168.0.1.1.1");
    plcAddr.port = 851; // PLC运行时默认端口

    // 建立ADS连接
    long errCode = AdsConnect(&plcAddr);
    if (errCode != 0) {
        std::cout << "ADS连接失败,错误码: " << errCode << std::endl;
        AdsLibExit();
        return 1;
    }

    // --------------------------
    // 1. 无参数方法调用示例
    // --------------------------
    const char* methodSymbol = "MAIN.fbCalc.TestMethod"; // 替换为你的FB方法符号路径
    BOOL trigger = TRUE;
    errCode = AdsWriteSymbol(&plcAddr, methodSymbol, &trigger, sizeof(trigger), ADST_BOOL);
    if (errCode != 0) {
        std::cout << "调用无参数方法失败,错误码: " << errCode << std::endl;
        goto cleanup;
    }

    // 可选:若方法依赖上升沿触发,写完TRUE后延迟写入FALSE避免重复执行
    Sleep(100);
    trigger = FALSE;
    AdsWriteSymbol(&plcAddr, methodSymbol, &trigger, sizeof(trigger), ADST_BOOL);

    // --------------------------
    // 2. 带参数+读取返回值示例
    // --------------------------
    const char* inputParamSymbol = "MAIN.fbCalc.InputValue"; // FB输入参数符号路径
    int inputVal = 200;
    errCode = AdsWriteSymbol(&plcAddr, inputParamSymbol, &inputVal, sizeof(inputVal), ADST_DINT);
    if (errCode != 0) {
        std::cout << "写入输入参数失败,错误码: " << errCode << std::endl;
        goto cleanup;
    }

    // 触发方法
    trigger = TRUE;
    errCode = AdsWriteSymbol(&plcAddr, methodSymbol, &trigger, sizeof(trigger), ADST_BOOL);
    if (errCode != 0) {
        std::cout << "调用带参数方法失败,错误码: " << errCode << std::endl;
        goto cleanup;
    }
    Sleep(100);
    trigger = FALSE;
    AdsWriteSymbol(&plcAddr, methodSymbol, &trigger, sizeof(trigger), ADST_BOOL);

    // 读取方法执行结果(FB输出参数)
    const char* outputResultSymbol = "MAIN.fbCalc.OutputResult";
    int resultVal;
    errCode = AdsReadSymbol(&plcAddr, outputResultSymbol, &resultVal, sizeof(resultVal), ADST_DINT);
    if (errCode == 0) {
        std::cout << "方法执行结果: " << resultVal << std::endl;
    } else {
        std::cout << "读取结果失败,错误码: " << errCode << std::endl;
    }

cleanup:
    // 断开连接并清理ADS库
    AdsDisconnect(&plcAddr);
    AdsLibExit();
    return 0;
}

关键注意事项

  • 符号路径准确性:从TwinCAT的Symbol Explorer中复制FB实例、方法、参数的完整符号路径,确保拼写和层级正确。
  • ADS库链接:编译时需链接对应平台的ADS库(32位用AdsLib.lib,64位用AdsLibx64.lib),并包含头文件AdsLib.h。
  • 触发逻辑:部分FB方法依赖上升沿触发,因此写入TRUE后需延迟写入FALSE,避免多次执行。
  • 权限与网络:确保本地设备与PLC在同一网段,或配置正确的ADS路由,同时PLC允许外部ADS访问。

内容的提问来源于stack exchange,提问作者Sourabh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.09 11:20:54