Qt 中 OPC UA 通讯实战

最近在项目中用到了opc ua通讯,主要就是客户的设备状态通过opc ua发布出来,我们通过读取定义好的Tag获取客户设备的实时运行状态,达到和我们自己设备联动的目的。

1.关于库的选择

我用的是qt框架编写的,Qt的OPC UA模块在qt5.11才提供,我用的是qt5.9.4,所以就要另谋出路了。在gpt上找到了open62541这个基于c语言的opc ua开源库,刚好同事也有Demo,就拿来用了,只有open62541.h和open62541.c两个文件,直接加到qt的项目工程即可。

2.open62541的使用

  • 创建客户端
cpp 复制代码
m_client = UA_Client_new();
UA_ClientConfig_setDefault(UA_Client_getConfig(m_client));

QByteArray url = "opc.tcp://127.0.0.1:49320";
UA_StatusCode rc = UA_Client_connect(m_client, url.constData());
qDebug() << "connect =" << UA_StatusCode_name(rc);
  • 读取bool量
cpp 复制代码
QByteArray name = "SJPLC.PLPLC.SJC_H5_RUN";
UA_NodeId nid = UA_NODEID_STRING_ALLOC(2, name.constData());

UA_Variant val; UA_Variant_init(&val);
UA_StatusCode rc = UA_Client_readValueAttribute(m_client, nid, &val);

if(rc == UA_STATUSCODE_GOOD && 
   val.type && val.type->typeIndex == UA_TYPES_BOOLEAN) {
    bool state = *(UA_Boolean*)val.data;
    qDebug() << "Value =" << state;
}
UA_NodeId_clear(&nid);
UA_Variant_clear(&val);
  • 断开连接
cpp 复制代码
UA_Client_disconnect(m_client);
UA_Client_delete(m_client);

3.常见问题

  1. BadNodeIdUnknown
    • 原因:NodeId 拼写不一致 / 命名空间索引(ns)错了。
    • 解决:在 UaExpert 找到对应的标签后仔细核对是否出现拼写错误,这个问题困扰了我2个多小时。
  2. BadSessionIdInvalid
    • 原因:会话超时或 SecureChannel 被服务器清掉。
    • 解决:做一个keep-alive功能,隔几秒钟读取一下标签(最省事也是最稳定的方案)

4.保活 (Keep-alive) 机制

OPC UA 和 Modbus 最大的区别之一:

  • Modbus 一问一答即可;
  • OPC UA 有 SecureChannel + Session,需要定期活跃,否则会话被回收。
    解决办法:
  • 定时轻量读:比如每 10~30 秒读一次 ServerStatus.CurrentTime (ns=0;i=2258)。
  • 调用心跳函数:在一些版本里是 UA_Client_runAsync() 或 UA_Client_run_iterate(),定时触发。
  • 订阅场景:必须跑心跳循环,否则收不到推送。
相关推荐
数据知道18 分钟前
claw-code 源码分析:大型移植的测试哲学——如何用 unittest 门禁守住「诚实未完成」的口碑?
开发语言·python·ai·claude code·claw code
小堃学编程27 分钟前
【项目实战】基于protobuf的发布订阅式消息队列(2)—— 线程池
java·开发语言
每日任务(希望进OD版)33 分钟前
线性DP、区间DP
开发语言·数据结构·c++·算法·动态规划
怨言.34 分钟前
Java内部类详解:从基础概念到实战应用(附案例)
java·开发语言
AC赳赳老秦34 分钟前
OpenClaw image-processing技能实操:批量抠图、图片尺寸调整,适配办公需求
开发语言·前端·人工智能·python·深度学习·机器学习·openclaw
XiYang-DING36 分钟前
【Java】 Java 集合框架
java·开发语言
charlie11451419136 分钟前
嵌入式C++教程实战之Linux下的单片机编程(9):HAL时钟使能 —— 不开时钟,外设就是一坨睡死的硅
linux·开发语言·c++·单片机·嵌入式硬件·c
diving deep41 分钟前
从零构建大模型--实操--搭建python环境
开发语言·python
We་ct42 分钟前
LeetCode 172. 阶乘后的零:从暴力到最优,拆解解题核心
开发语言·前端·javascript·算法·leetcode·typescript
沉淀粉条形变量1 小时前
rust 单例模式
开发语言·单例模式·rust