CODESYS + UaExpert + Qt OPC UA 入门指南
本文档记录从零开始使用 CODESYS 编写 PLC 程序、通过 OPC UA 协议与 Qt 客户端通信的完整过程包含环境配置、程序开发、连接测试以及实际踩坑经历。主要难点在于免证书进行匿名登录CODESYS关于这个功能藏得太深了搞了很久T^T环境信息PLC 软件CODESYS Control Win V3 x64软 PLC运行于 WindowsOPC UA 客户端工具UaExpertUnified Automation开发环境Qt 5.15.2 open62541CentOS 7 虚拟机 / Windows 均可OPC UA 端口4840目录一、整体架构二、环境准备三、CODESYS PLC 程序开发四、启用 OPC UA Server五、用 UaExpert 连接测试六、Qt 客户端开发七、踩坑经历八、附录一、整体架构┌─────────────────────┐ OPC UA/TCP ┌─────────────────────┐ │ CODESYS Control │ ◄──────────────► │ Qt OPC UA Client │ │ Win V3 x64 │ port 4840 │ (open62541) │ │ (PLC UA Server) │ │ │ └─────────────────────┘ └─────────────────────┘ ▲ ▲ │ OPC UA/TCP │ ▼ │ ┌─────────────────────┐ │ │ UaExpert │ ◄──────────────────────────┘ │ (调试/验证用) │ 可选用于前期验证 NodeId └─────────────────────┘CODESYS既是 PLC 运行时执行梯形图逻辑又内置 OPC UA Server对外暴露变量UaExpert通用 OPC UA 客户端用于浏览节点、验证变量 NodeId是开发 Qt 客户端前的必备调试工具Qt 客户端基于 open62541 库开发的 GUI 程序连接 CODESYS 读写变量二、环境准备2.1 安装 CODESYS访问 https://store.codesys.com/codesys-control/ 下载CODESYS Control Win V3免费版含 SL 许可安装时勾选CODESYS Control Win V3 x6464 位软 PLC 运行时同时会安装CODESYS Development SystemIDE用于编写 PLC 程序CODESYS Development System 既是编程 IDE也用于下载/在线调试 PLC 程序。2.2 安装 UaExpert访问 https://www.unified-automation.com/downloads/opc-ua-clients.html下载UaExpert免费需注册账号2.3 Qt open62541 环境Qt 客户端依赖 open62541 开源 OPC UA 协议栈。环境搭建可参考同目录下的OPCUA_Demo_完整指南.md关键步骤组件说明Qt 5.15.2GUI 框架open62541 v1.5.xOPC UA C 协议栈编译为libopen62541.so.pro文件需添加LIBS -lopen62541三、CODESYS PLC 程序开发3.1 新建工程打开 CODESYS Development SystemFile → New Project选择Standard project设备选择CODESYS Control Win V3 x64编程语言选择Ladder Diagram (LD)或其他熟悉的语言3.2 定义变量在main程序PRG中声明 6 个变量PROGRAM main VAR Counter : INT : 0; // 计数器每周期 1 Temperature : REAL : 25.0; // 温度°C Pressure : REAL : 100.0; // 压力kPa Humidity : REAL : 60.0; // 湿度% TargetTemp : REAL : 22.0; // 目标温度可写入 DeviceMode : INT : 0; // 设备模式可写入 END_VAR⚠️注意 IEC 61131-3 数据类型与 OPC UA 类型的对应关系这是后续踩坑的根源IEC 61131-3 类型位宽对应 OPC UA 类型INT16 位有符号Int16DINT32 位有符号Int32REAL32 位浮点FloatLREAL64 位浮点DoubleINT在 IEC 61131-3 中是 16 位不是 C 语言的 32 位这点极易搞混。3.3 编写梯形图逻辑用梯形图LD实现控制逻辑Counter 每个扫描周期递增Temperature/Pressure/Humidity 模拟波动根据 DeviceMode 和 TargetTemp 进行简单控制。3.4 编译并下载到 PLCBuild → Compile编译检查语法在线登录Online → Login点击StartF5让 PLC 进入运行状态确认 PLC 状态指示灯为绿色RUNNING四、启用 OPC UA Server停止并登出后进行配置修改按照如图所示操作打开Opc UA服务。允许匿名登录否则需要配置证书会比较麻烦。配置完成后重新编译并登录启动。五、用 UaExpert 连接测试UaExpert 是开发 Qt 客户端前的关键一步——先用它确认 NodeId 和数据类型再写代码。5.1 添加服务器打开 UaExpert点击工具栏Add Server➕参考下图所示进行配置5.2 连接并浏览地址空间在左侧 Server 列表中双击刚添加的服务器连接成功后展开Address Space面板沿路径Objects → DeviceSet → CODESYS Control Win V3 x64 → ...逐级展开找到main下的 6 个变量节点5.3 拖拽变量到 Data Access View打开下方Data Access View标签页将 6 个变量从 Address Space 拖拽到 Data Access View即可实时看到变量值变化5.4 写入变量测试在 Data Access View 中选中TargetTemp或DeviceMode右键 →Write…输入新值确认写入观察 CODESYS 中变量是否更新通过 UaExpert 验证 NodeId 和数据类型无误后即可开始编写 Qt 客户端。补充CODESYS 暴露的变量 NodeId 采用字符串格式命名规则为|var|设备名.Application.POU名.变量名例如本项目的变量 NodeId 为变量NodeIdCounterns4;s|var|CODESYS Control Win V3 x64.Application.main.CounterTemperaturens4;s|var|CODESYS Control Win V3 x64.Application.main.TemperaturePressurens4;s|var|CODESYS Control Win V3 x64.Application.main.PressureHumidityns4;s|var|CODESYS Control Win V3 x64.Application.main.HumidityTargetTempns4;s|var|CODESYS Control Win V3 x64.Application.main.TargetTempDeviceModens4;s|var|CODESYS Control Win V3 x64.Application.main.DeviceModens4是 CODESYS 变量命名空间公共前缀BasePath为|var|CODESYS Control Win V3 x64.Application.main.六、Qt 客户端开发6.1 项目配置.pro文件关键配置QT core gui widgets CONFIG c11 LIBS -lopen625416.2 连接服务器m_clientUA_Client_new();UA_ClientConfig_setDefault(UA_Client_getConfig(m_client));QByteArray urlBaurl.toUtf8();UA_StatusCode retUA_Client_connect(m_client,urlBa.constData());// ret UA_STATUSCODE_GOOD 表示连接成功6.3 读取变量字符串 NodeIdCODESYS 变量用字符串 NodeId需用UA_NODEID_STRINGQByteArray banodeIdStr.toUtf8();UA_NodeId nodeIdUA_NODEID_STRING(ns,ba.data());UA_Variant value;UA_Variant_init(value);UA_StatusCode retUA_Client_readValueAttribute(m_client,nodeId,value);if(retUA_STATUSCODE_GOODUA_Variant_hasScalarType(value,UA_TYPES[UA_TYPES_FLOAT])){UA_Float v*(UA_Float*)value.data;// 使用 v ...}UA_Variant_clear(value);6.4 写入变量写入前需确认目标数据类型避免类型不匹配// 先读取确定类型再按实际类型写入UA_Variant cur;UA_Client_readValueAttribute(m_client,nodeId,cur);// 根据 cur.type 选择对应的 setScalarCopy ...UA_Variant_clear(cur);6.5 界面与运行客户端界面包含连接配置区URL、命名空间、BasePath自动变量读取区Counter / Temperature / Pressure / Humidity手动变量读写区TargetTemp / DeviceModeBrowse Address Space 按钮浏览服务器节点结构日志区运行流程输入 URLopc.tcp://PLC所在IP:4840设置 NS 4设置 BasePath |var|CODESYS Control Win V3 x64.Application.main.点击 Connect点击各 Read 按钮读取或 Read All 批量读取在 Set 输入框填值点 Write 写入 TargetTemp / DeviceMode七、踩坑经历以下是实际开发中遇到的问题按出现顺序记录。坑 1数据类型不匹配 — 读取 ERR、写入 BadTypeMismatch现象Temperature、Pressure、Humidity、TargetTempREAL 类型读写正常但Counter、DeviceModeINT 类型读取显示 ERR写入报BadTypeMismatch。原因CODESYS 的INT是IEC 61131-3 标准的 16 位整数对应 OPC UAInt16而 Qt 客户端代码按Int32读写。REAL 是 32 位 Float恰好匹配所以没问题。解决读取写一个variantToInt64辅助函数兼容 SByte / Byte / Int16 / UInt16 / Int32 / UInt32 / Int64 / UInt64 所有整数类型统一转为qint64返回。写入写入前先读取目标节点的当前值获取其实际 OPC UA 数据类型再用UA_Variant_setScalarCopy按实际类型写入。// 读取时兼容所有整数类型staticboolvariantToInt64(constUA_Variant*value,qint64*out){constUA_DataType*tvalue-type;if(tUA_TYPES[UA_TYPES_INT16]){*out*(UA_Int16*)value-data;returntrue;}if(tUA_TYPES[UA_TYPES_UINT16]){*out*(UA_UInt16*)value-data;returntrue;}if(tUA_TYPES[UA_TYPES_INT32]){*out*(UA_Int32*)value-data;returntrue;}// ... 其他类型returnfalse;}教训永远不要假设 PLC 变量的数据类型。IEC 61131-3 的INT≠ C 的int。用 UaExpert 先确认每个变量的实际 OPC UA 类型。坑 2浏览地址空间崩溃 —free(): invalid pointer现象点击 Browse Address Space 后浏览到第一个字符串 NodeId 的节点时崩溃控制台报*** Error in ...: free(): invalid pointer: 0x0000000002359828 ***原因UA_NODEID_STRING宏是浅拷贝nodeId.identifier.string.data指向QByteArray的内部缓冲区Qt 管理的内存。当UA_BrowseRequest_clear清理请求时调用UA_free()试图释放这个指针——但它是 Qt 分配的内存不是 UA 分配器分配的导致free()崩溃。关键点前 6 个被浏览的节点都是数字 NodeId如ns0;i85不涉及字符串指针所以不崩溃。第 7 个节点ns4;s|plc|CODESYS Control Win V3 x64是第一个字符串 NodeId一清理就炸。解决字符串 NodeId 必须用UA_STRING_ALLOC分配 UA 堆内存让UA_BrowseRequest_clear能正确释放// ❌ 错误指向 Qt 内存clear 时崩溃QByteArray strBacur.strId.toUtf8();nodeIdUA_NODEID_STRING(cur.ns,strBa.data());// ✅ 正确用 UA 分配器复制字符串QByteArray strBacur.strId.toUtf8();UA_String uaStrUA_STRING_ALLOC(strBa.constData());nodeIdUA_NODEID_STRING(cur.ns,(char*)uaStr.data);// uaStr 所有权交给 nodeId由 UA_BrowseRequest_clear 统一释放教训open62541 中凡是涉及字符串/字节串的 NodeId要注意内存所有权。UA_NODEID_STRING是浅拷贝UA_*_clear会尝试free字符串指针——必须确保该指针指向 UA 分配器分配的内存。坑 3编译错误 —const char*到char*的转换现象编译报错error: invalid conversion from const char* to char* [-fpermissive]原因UA_NODEID_STRING宏的第二个参数类型是char*而QByteArray::constData()返回const char*类型不匹配。解决改用QByteArray::data()它返回非 const 的char*// ❌ constData() 返回 const char*nodeIdUA_NODEID_STRING(ns,strBa.constData());// ✅ data() 返回 char*nodeIdUA_NODEID_STRING(ns,strBa.data());教训Qt 的QByteArray提供constData()const和data()非 const两个版本传给要求char*的 C 接口时用data()。坑 4程序崩溃后 UI 日志丢失现象程序崩溃后界面上的日志区被清空无法分析崩溃原因。原因日志只写到了QTextEdit控件内存中崩溃时进程异常终止控件内容来不及保存。解决调试阶段用宏同时输出到 UI 日志和控制台qDebug()控制台输出在崩溃后依然保留#defineBROWSE_LOG(msg)do{log(msg);qDebug().noquote()msg;}while(0)正式调试完成后已移除 qDebug 双输出恢复为简洁的log()调用。教训调试崩溃问题时日志必须输出到进程外控制台/文件不能只依赖进程内的 UI 控件。坑 5递归浏览导致栈溢出风险现象早期版本用递归实现地址空间浏览节点层级深时可能栈溢出崩溃。解决改用BFS 迭代QQueue队列并设置最大深度MAX_DEPTH3和最大节点数MAX_NODES300双保险避免无限递归。教训地址空间浏览优先用迭代而非递归PLC 服务器的节点树可能很深。八、附录8.1 变量清单变量名IEC 类型OPC UA 类型NodeId 后缀初始值读/写CounterINTInt16Counter0只读TemperatureREALFloatTemperature25.0只读PressureREALFloatPressure100.0只读HumidityREALFloatHumidity60.0只读TargetTempREALFloatTargetTemp22.0读/写DeviceModeINTInt16DeviceMode0读/写8.2 连接配置速查参数值URLopc.tcp://PLC_IP:4840Namespace (NS)4BasePath|var|CODESYS Control Win V3 x64.Application.main.8.3 常用 OPC UA 状态码状态码含义常见原因Good成功—BadTypeMismatch类型不匹配写入的数据类型与节点定义不符BadNodeIdUnknown节点不存在NodeId 字符串拼写错误BadConnectionClosed连接已关闭服务器断开或网络中断BadTimeout超时网络不通或服务器无响应8.4 IEC 61131-3 与 OPC UA / C 类型对照IEC 61131-3位宽OPC UAC/C (Qt)BOOL1BooleanboolSINT8 有符号SByteint8_tUSINT8 无符号Byteuint8_tINT16 有符号Int16int16_tUINT16 无符号UInt16uint16_tDINT32 有符号Int32int32_tUDINT32 无符号UInt32uint32_tREAL32 浮点FloatfloatLREAL64 浮点Doubledouble易错PLC 的INT 16 位不是 C 的int通常 32 位

相关新闻

百度网盘提取码智能获取工具完整实战指南

百度网盘提取码智能获取工具完整实战指南

百度网盘提取码智能获取工具完整实战指南 【免费下载链接】baidupankey 在线查询网盘提取码(维护中 rm repo) 项目地址: https://gitcode.com/gh_mirrors/ba/baidupankey 还在为百度网盘资源下载时的提取码而烦恼吗?baidupankey作为一…

2026/7/30 7:33:12 阅读更多 →
从 PHP 到 AI + Golang,程序员自救转型手记(四十):基类改造

从 PHP 到 AI + Golang,程序员自救转型手记(四十):基类改造

这是一个系列 Blog,作者将以一个 PHP 全栈工程师的身份,利用 AI 工具(claude code、codex、deepseek、豆包等):从零开始学习 golang 语言,并最终完成 ai-go-admin(github | gitee)开…

2026/7/30 7:33:12 阅读更多 →
5个常用的网页制作软件和建站系统,省时又省力!

5个常用的网页制作软件和建站系统,省时又省力!

当你想建立一个网站和站群时,你会需要一款强大且便于使用的网页制作软件或建站工具。在这篇文章中,我们将为你推荐5款常用的网页制作软件或建站系统,帮助你在网页制作中省时又省力! 1. PageAdmin PageAdmin是一款国产企业级网站…

2026/7/30 7:33:12 阅读更多 →

最新新闻

PyTorch版本升级全攻略:从环境诊断到安全验证的工程实践

PyTorch版本升级全攻略:从环境诊断到安全验证的工程实践

1. 项目概述:为什么升级PyTorch是个技术活 最近在折腾一个老项目的模型推理,发现原本跑得好好的代码突然报了个 RuntimeError: "addmm_impl_cpu_" not implemented for Half 。排查了一圈,问题根源直指PyTorch版本——项目用的是…

2026/7/30 7:42:16 阅读更多 →
【深度学习新浪潮】科学研发智能体2025-2026年度技术进展分析

【深度学习新浪潮】科学研发智能体2025-2026年度技术进展分析

标签:#人工智能 #AI4S #科研智能体 #AgenticAI #科学发现 分类:人工智能 > 深度学习 难度:⭐⭐⭐⭐ 前言 2025年,AI for Science(AI4S)领域发生了一场静默但深刻的范式跃迁:科研智能体(Scientific Research Agent)从"高级工具"进化为能够参与科研推理、…

2026/7/30 7:42:15 阅读更多 →
KKCE(快快测):网站测速实战从性能诊断到体验优化

KKCE(快快测):网站测速实战从性能诊断到体验优化

很多开发者都有过这样的经历:本地开发环境丝滑流畅,代码提交后信心满满地上线,结果监控报警群却炸了锅。用户反馈页面加载转圈不停,跳出率飙升,转化数据断崖式下跌。这时候再去查日志,往往发现服务器响应时…

2026/7/30 7:42:15 阅读更多 →
简易音乐1:Web音频技术与AI驱动的音乐创作平台

简易音乐1:Web音频技术与AI驱动的音乐创作平台

1. 项目背景与核心价值 "简易音乐1"这个项目名称看似简单,却蕴含着对音乐创作民主化的深刻思考。作为一个长期关注音乐科技融合的从业者,我亲历了从专业录音棚到手机APP的音乐制作演变过程。这个项目本质上是要解决一个核心矛盾:如…

2026/7/30 7:42:15 阅读更多 →
Spring AI实现多模型动态切换与统一接口设计

Spring AI实现多模型动态切换与统一接口设计

1. 项目背景与核心价值 在AI应用开发领域,模型碎片化已成为开发者面临的主要痛点。不同厂商的AI模型(如OpenAI的GPT-4o、阿里的通义千问)有着各自的API规范、参数格式和计费方式,这导致三个典型问题: 切换成本高 &am…

2026/7/30 7:42:15 阅读更多 →
TypeScript 7.0架构优化与性能提升深度解析

TypeScript 7.0架构优化与性能提升深度解析

TypeScript 7.0 的发布标志着这门语言在性能和架构上迈出了重要一步。虽然官方并未完全用 Go 语言重写编译器,但通过底层架构优化和编译策略改进,确实实现了显著的性能提升。对于长期受限于大型项目编译速度的开发者来说,这些改进意味着更快的…

2026/7/30 7:41:14 阅读更多 →

日新闻

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:13 阅读更多 →
如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南

如何3步掌握Video Download Helper:网页视频下载的完整实战指南 【免费下载链接】VideoDownloadHelper Chrome Extension to Help Download Video for Some Video Sites. 项目地址: https://gitcode.com/gh_mirrors/vi/VideoDownloadHelper 你是否曾经在浏览…

2026/7/30 0:00:13 阅读更多 →
“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

“双减”后首个AI备课压力测试报告:覆盖32所中小学的176节AI辅助课,暴露4大隐性增负节点

更多请点击: https://intelliparadigm.com 第一章:AI 教师备课辅助 AI 教师备课辅助系统正逐步成为教育数字化转型的核心支撑工具,它并非替代教师,而是通过语义理解、知识图谱与多模态生成能力,将教师从重复性劳动中解…

2026/7/30 0:00:13 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/29 22:18:20 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/29 15:00:03 阅读更多 →

月新闻