本篇介绍opc,opc客户端,实现一个opc客户端读取bool和写入bool的demo,这是基本得数据读取写入的访问。
OPC 客户端是一种利用OPC(OLE for Process Control)协议与 OPC 服务器进行通信的软件应用程序。
功能特点
OPC 协议采用客户端 - 服务器(C/S)架构,该架构由以下部分组成:
OPC 协议基于 COM/DCOM(Component Object Model/Distributed Component Object Model)技术来实现分布式通信,也有基于 OPC UA(Unified Architecture)标准的实现,下面是这两种实现的具体介绍:
OPC 协议支持多种数据访问方式,以满足不同的应用场景需求:
OPC 协议的实现涉及以下核心组件:
OPC 客户端与服务器之间的通信一般遵循以下流程:
void OpcClientManager::slot_readBool(int ns, int i)
{
// 读取服务器数据
UA_Variant value;
UA_Variant_init(&value);
/*
方式1:数字ID(ns=2;i=1234)
UA_NodeId nodeId = UA_NODEID_NUMERIC(2, 1234);
方式2:字符串ID(ns=1;s=MyVariable)
UA_NodeId nodeId = UA_NODEID_STRING(1, (char*)"MyVariable");
方式3:从字符串解析(用于调试)
UA_NodeId nodeId;
UA_NodeId_fromString(UA_STRING("ns=1;i=1001"), &nodeId);
*/
UA_StatusCode statusCode = UA_Client_readValueAttribute(_pUAClient, UA_NODEID_NUMERIC(ns, i), &value);
if( statusCode == UA_STATUSCODE_GOOD
&& UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_BOOLEAN]))
{
LOG << value.data;
emit signal_readBool(true, ns, i, *(UA_Boolean *)value.data);
}else{
LOG << QString("Failed to UA_Client_readValueAttribute ns=%1,i=%2, statusCode: 0x%3")
.arg(ns)
.arg(i)
.arg(statusCode, 8, 16, QChar('0'));
emit signal_readBool(false, ns, i, false);
}
}
void OpcClientManager::slot_writeBool(int ns, int i, bool b)
{
// 读取服务器数据
UA_Variant value;
UA_Variant_init(&value);
UA_Boolean booleanValue = b; // 要写入的布尔值
UA_Variant_setScalar(&value, &booleanValue, &UA_TYPES[UA_TYPES_BOOLEAN]);
/*
方式1:数字ID(ns=2;i=1234)
UA_NodeId nodeId = UA_NODEID_NUMERIC(2, 1234);
方式2:字符串ID(ns=1;s=MyVariable)
UA_NodeId nodeId = UA_NODEID_STRING(1, (char*)"MyVariable");
方式3:从字符串解析(用于调试)
UA_NodeId nodeId;
UA_NodeId_fromString(UA_STRING("ns=1;i=1001"), &nodeId);
*/
UA_StatusCode statusCode = UA_Client_writeValueAttribute(_pUAClient, UA_NODEID_NUMERIC(ns, i), &value);
if(statusCode == UA_STATUSCODE_GOOD)
{
emit signal_writeBool(true, ns, i, b);
}else{
LOG << QString("Failed to UA_Client_readValueAttribute ns=%1,i=%2, statusCode: 0x%3")
.arg(ns)
.arg(i)
.arg(statusCode, 8, 16, QChar('0'));
emit signal_writeBool(false, ns, i, b);
}
}
读取bool总是false,这是使用代码读取值。
打印调试输出:
检查opc服务器:
确认上面2个是一致的。
十有八九是nodeId错了,继续:
修改调试代码:
测试结果:
所以是方式错了,总结就是有三种表达方式:
nodeId输入错误,需要构成:
读取值一直为true
指针指向的数据,而不是直接数据
修改为:
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文系转载,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。