如何用PyADS获取TwinCAT系统中STRUCT/FB内的所有变量?
解决PyADS获取TwinCAT PLC嵌套变量(STRUCT/FB成员)的问题
默认的get_all_symbols()仅返回顶层变量,要获取MAIN内STRUCT或FB的嵌套变量,需要递归遍历符号的子结构——PyADS的Symbol对象自带children属性,可访问其嵌套的成员变量。
实现步骤
- 编写递归函数,遍历所有顶层符号及其子符号
- 对每个符号尝试读取值,处理可能的异常
- 保留原有的CSV导出功能
修改后的完整代码
import pyads import csv AMSNETID = '.....' def traverse_symbols(symbol, parent_name=""): """递归遍历单个符号及其子符号,生成完整变量名和符号对象""" # 生成完整变量名(处理顶层和嵌套情况) full_name = f"{parent_name}.{symbol.name}" if parent_name else symbol.name yield full_name, symbol # 如果当前符号有子成员,递归遍历 if hasattr(symbol, 'children') and symbol.children: for child in symbol.children: yield from traverse_symbols(child, full_name) plc = pyads.Connection(AMSNETID, pyads.PORT_TC3PLC1) plc.open() print(f"Connected?: {plc.is_open}") print(f"Local Address? : {plc.get_local_address()}") # 获取所有顶层符号 top_symbols = plc.get_all_symbols() with open('names.csv', 'w', newline='') as csvfile: fieldnames = ['Name', 'Value', 'Comment'] writer = csv.DictWriter(csvfile, fieldnames=fieldnames) writer.writeheader() # 遍历所有顶层符号,再递归遍历嵌套子符号 for top_s in top_symbols: for full_name, s in traverse_symbols(top_s): try: # 读取变量值 value = s.read() writer.writerow({ 'Name': full_name, 'Value': value, 'Comment': s.comment or '' }) print(f"{full_name} : {value} // {s.comment or ''}") except Exception as e: print(f"{full_name} : Failed - {str(e)}") plc.close()
关键说明
- 递归遍历逻辑:
traverse_symbols函数会逐层解析符号的children属性,自动生成类似MAIN.fb_path.i_xTest的完整变量名,适配PLC代码变更后的新变量 - 异常处理优化:保留错误捕获并输出具体异常信息,便于排查变量不可读、权限不足等问题
- CSV导出兼容:保持原有的导出格式,同时包含嵌套变量的完整名称和注释
注意事项
- 确保PLC中的FB实例、STRUCT变量已正确实例化,且当前连接具备变量访问权限
- 对于数组、指针等特殊类型变量,可能需要额外添加类型判断和读取逻辑
- 若符号无
children属性,建议升级PyADS到最新稳定版本(部分旧版本不支持子符号遍历)
内容的提问来源于stack exchange,提问作者BV_62
相关产品推荐
相关产品推荐

