如何在未知运行项目时通过ADS-DLL获取TwinCAT EtherCAT主站NetId
获取TwinCAT EtherCAT主站AmsNetId(无需修改项目/ADS-DLL实现)
方案1:读取TwinCAT系统符号(最可靠)
TwinCAT Runtime自带固定系统符号,无论项目配置如何,都能通过ADS直接读取这些符号获取EtherCAT主站的AmsNetId:
- 先连接到已知的PLC Runtime AmsNetId(默认端口851)
- 用ADS-DLL的
AdsSyncReadWriteReq获取系统符号句柄,再通过AdsSyncReadReq读取对应值:- TwinCAT 3使用符号:
TcSystemInfo.EtherCAT[0].AmsNetId([0]对应第一个主站,多主站可循环遍历索引) - TwinCAT 2使用符号:
EtherCAT.Master[1].AmsNetId(索引从1开始)
- TwinCAT 3使用符号:
C++代码示例:
#include <adsdll.h> #include <cstdio> int main() { // 打开ADS端口 if (AdsPortOpen() != 0) { printf("ADS端口打开失败\n"); return 1; } AmsAddr plcAddr; // 替换为你已知的PLC Runtime AmsNetId plcAddr.netId = {192, 168, 1, 10, 1, 1}; plcAddr.port = 851; // 默认PLC ADS端口 AdsSymbolEntry symEntry; const char* symName = "TcSystemInfo.EtherCAT[0].AmsNetId"; // 获取符号句柄 long err = AdsSyncReadWriteReq(&plcAddr, ADSIGRP_SYM_HNDBYNAME, 0, sizeof(symEntry), &symEntry, strlen(symName) + 1, symName); if (err != 0) { printf("获取符号句柄失败,错误码:%ld\n", err); AdsPortClose(); return 1; } AmsNetId ecMasterNetId; // 读取AmsNetId值 err = AdsSyncReadReq(&plcAddr, ADSIGRP_SYM_VALBYHND, symEntry.handle, sizeof(AmsNetId), &ecMasterNetId); if (err != 0) { printf("读取AmsNetId失败,错误码:%ld\n", err); // 释放符号句柄 AdsSyncWriteReq(&plcAddr, ADSIGRP_SYM_RELEASEHND, 0, 0, nullptr, sizeof(symEntry.handle), &symEntry.handle); AdsPortClose(); return 1; } // 打印结果 printf("EtherCAT主站AmsNetId: %d.%d.%d.%d.%d.%d\n", ecMasterNetId.b[0], ecMasterNetId.b[1], ecMasterNetId.b[2], ecMasterNetId.b[3], ecMasterNetId.b[4], ecMasterNetId.b[5]); // 清理资源 AdsSyncWriteReq(&plcAddr, ADSIGRP_SYM_RELEASEHND, 0, 0, nullptr, sizeof(symEntry.handle), &symEntry.handle); AdsPortClose(); return 0; }
方案2:遍历ADS设备列表
如果系统符号读取异常(比如旧版本TwinCAT),可以遍历所有注册的ADS设备:
- 调用
AdsSyncReadReq读取ADSIGRP_DEVICE_DATA组,获取所有设备的信息 - 筛选设备名称包含
EtherCAT或EC-Master的条目,对应的AmsNetId即为EtherCAT主站地址
注意:此方法需处理多主站场景,需逐个检查设备信息。
重要提示
- 确保PLC的851端口可访问,客户端拥有ADS读写权限
- 多主站场景下,需循环遍历索引(TwinCAT3从0开始,TwinCAT2从1开始)
- 全程无需修改PLC项目,所有操作依赖ADS-DLL标准函数及TwinCAT自身暴露的系统信息
内容的提问来源于stack exchange,提问作者LaraTv
相关产品推荐
相关产品推荐

