0
点赞
收藏
分享

微信扫一扫

Qt使用QOpcUa类

转角一扇门 2022-03-26 阅读 106
qt

目录

前言:

一:测试软件安装与使用

1.opc服务端程序:kepserverex 

2.opc客户端程序:uaexpert   提取码:0kpmuaexpert   提取码:

3.使用KEPServerv6进行OPC_UA的服务器搭建:服务器搭建

4. 使用KEPServerv6添加仿真:此链接第五步或者此链接前两步

5.通过uaexpert访问kepservere

二:Qt搭建客户端

总结:


前言:

        本文章介绍如何使用Qt搭建客户端并并和服务端完成简单的读写操作

一:测试软件安装与使用

1.opc服务端程序:kepserverex 

2.opc客户端程序:uaexpert   提取码:0kpm

3.使用KEPServerv6进行OPC_UA的服务器搭建:服务器搭建

4. 使用KEPServerv6添加仿真:此链接第五步或者此链接前两步

5.通过uaexpert访问kepservere

 (1)先给KEPServerv6添加仿真

(2)让uaexpert访问kepservere

​ 


 点击OK即可连接成功,然后按下面步骤找到对应节点的信息

​ 

双击s1得到下面方框中的信息,这里面包含节点的信息,其中NodeId用于后面Qt访问

​ 


二:Qt搭建客户端

1.打开Qt,并在.pro文件和.h文件中分别加入:

QT       += opcua

#include <QOpcUaClient>
#include <QOpcUaNode>
#include <QtOpcUa>
#include <QDebug>

2.在.ui文件里面加入三个按钮,并如下命名

 三个按钮的槽函数分别如下:

void MainWindow::on_btn_requestEndpoints_clicked()
{
client->requestEndpoints(QUrl("opc.tcp://127.0.0.1:49320"));
}

void MainWindow::on_btn_readnode_clicked()
{
node->readAttributes(QOpcUa::NodeAttribute::Value);
qDebug()<<"readnode"<<node->nodeId();
}

void MainWindow::on_btn_writeAttribute_clicked()
{
QOpcUa::NodeAttribute attribute ;
attribute = QOpcUa::NodeAttribute::Value;
QVariant var=12;
//node->writeAttribute(attribute,QString("ssss"),QOpcUa::Types::String);
node->writeAttribute(attribute,var);
}

3.创建QOpcUaClient对象,官方例子如下

QOpcUaProvider provider;
if (provider.availableBackends().isEmpty())
return;
QOpcUaClient *client = provider.createClient(provider.availableBackends()[0]);
if (!client)
return;
// Connect to the stateChanged signal. Compatible slots of QObjects can be used instead of a lambda.
QObject::connect(client, &QOpcUaClient::stateChanged, [client](QOpcUaClient::ClientState state) {
qDebug() << "Client state changed:" << state;
if (state == QOpcUaClient::ClientState::Connected) {
QOpcUaNode *node = client->node("ns=0;i=84");
if (node)
qDebug() << "A node object has been created";
}
});
QObject::connect(client, &QOpcUaClient::endpointsRequestFinished,
[client](QList<QOpcUaEndpointDescription> endpoints) {
qDebug() << "Endpoints returned:" << endpoints.count();
if (endpoints.size())
client->connectToEndpoint(endpoints.first()); // Connect to the first endpoint in the list
});
client->requestEndpoints(QUrl("opc.tcp://127.0.0.1:4840")); // Request a list of endpoints from the server

创建 QOpcUaClient 使用 QOpcUaProvider , request a list of endpoints from the server using requestEndpoints 和调用 connectToEndpoint () to connect to one of the available endpoints. After the connection is established, a QOpcUaNode object for the root node is requested.

接下来按官方例子创建QOpcUaClient对象,并连接到服务器

(1)在.h文件中输入下面代码

public slots:

void on_btn_requestEndpoints_clicked();
void on_btn_readnode_clicked();
void on_btn_writeAttribute_clicked();

void SLOT_endpointsRequestFinished (QVector<QOpcUa::QEndpointDescription> endpoints , QOpcUa::UaStatusCode statusCode);
void SLOT_attributeRead ( QOpcUa::NodeAttributes attributes );
void SLOT_stateChanged (QOpcUaClient::ClientState state );

private:

Ui::MainWindow *ui;
QOpcUaClient *client;
QOpcUaProvider* provider;
QOpcUaNode* node;

(2)创建QOpcUaClient对象,并像例子中一样连接槽

provider = new QOpcUaProvider(this);
client = provider->createClient(QString("open62541"));
connect(client,&QOpcUaClient::endpointsRequestFinished,this,&MainWindow::SLOT_endpointsRequestFinished);
connect(client,&QOpcUaClient::stateChanged,this,&MainWindow::SLOT_stateChanged);

(3)按下按钮requestEndpoints,如果请求成功会跳到槽函数SLOT_endpointsRequestFinished

void MainWindow::SLOT_endpointsRequestFinished(QVector<QOpcUa::QEndpointDescription> endpoints, QOpcUa::UaStatusCode statusCode)
{
qDebug()<<endpoints.at(0).endpointUrl();
qDebug()<<statusCode;
qDebug() << "Endpoints returned:" << endpoints.count();
qDebug()<<endpoints.size();
if (endpoints.size())
client->connectToEndpoint(endpoints.at(0).endpointUrl()); // Connect to the first endpoint in the list
}

(4)跳到该槽函数后,会让创建的客户端对象连接到服务器,如果连接成功,会跳到槽函数SLOT_stateChanged

void MainWindow::SLOT_stateChanged(QOpcUaClient::ClientState state)
{
qDebug() << "Client state changed:" << state;
if (state == QOpcUaClient::ClientState::Connected) {
//QOpcUaNode定义
node = client->node("ns=2;s=my.plc.s1");
if (node)
qDebug() << "A node object has been created";
}
connect(node,&QOpcUaNode::attributeRead,this,&MainWindow::SLOT_attributeRead);

}

当创建的客户端对象连接到服务端之后,会进入到这个槽函数中,在这里面定义一个节点,其中节点的名字为在uaexpert中得到的nodeid,然后连接槽,如果读到节点属性后,就转到槽,官方创建节点例子如下

QOpcUaNode *rootNode; // Created before, see QOpcUaClient documentation.
// Connect to the attributeRead signal. Compatible slots of QObjects can be used instead of a lambda.
QObject::connect(rootNode, &QOpcUaNode::attributeRead, [rootNode, client](QOpcUa::NodeAttributes attr) {
qDebug() << "Signal for attributes:" << attr;
if (rootNode->attributeError(QOpcUa::NodeAttribute::BrowseName) != QOpcUa::UaStatusCode::Good) {
qDebug() << "Failed to read attribute:" << rootNode->attributeError(QOpcUa::NodeAttribute::BrowseName);
client->disconnectFromEndpoint();
}
qDebug() << "Browse name:" << rootNode->attribute(QOpcUa::NodeAttribute::BrowseName).value<QOpcUaQualifiedName>().name();
});
rootNode->readAttributes(QOpcUa::NodeAttribute::BrowseName); // Start a read operation for the node's BrowseName attribute.

 这里面定义的节点没有赋值,我在操作的时候提示错误,所以我上面提前定义的时候就赋值了

(5)按下按钮readnode,转到槽SLOT_attributeRead,开始读节点内容

void MainWindow::SLOT_attributeRead(QOpcUa::NodeAttributes attributes)
{
qDebug() << "Signal for attributes:" << attributes;
qDebug()<<"value:"<<node->attribute(QOpcUa::NodeAttribute::Value);
}

节点的属性很多,在按钮readnode中,读的是Value,因此这里输出的就是Value,如果读的是其他值,这里可以得到其他值。(初值可以在KEPServerv6的客户端中更改)

(6)按下按钮writeAttribute,就可以对节点写入所定义的属性,这里属性可以参考:属性

总结:

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);

provider = new QOpcUaProvider(this);
//if (provider.availableBackends().isEmpty())
client = provider->createClient(QString("open62541"));

connect(client,&QOpcUaClient::endpointsRequestFinished,this,&MainWindow::SLOT_endpointsRequestFinished);
connect(client,&QOpcUaClient::stateChanged,this,&MainWindow::SLOT_stateChanged);
}

MainWindow::~MainWindow()
{
delete ui;
}


void MainWindow::on_btn_requestEndpoints_clicked()
{
client->requestEndpoints(QUrl("opc.tcp://127.0.0.1:49320"));
}

void MainWindow::on_btn_readnode_clicked()
{
node->readAttributes(QOpcUa::NodeAttribute::Value);
qDebug()<<"readnode"<<node->nodeId();
}

void MainWindow::on_btn_writeAttribute_clicked()
{
QOpcUa::NodeAttribute attribute ;
attribute = QOpcUa::NodeAttribute::Value;
QVariant var=12;
//node->writeAttribute(attribute,QString("ssss"),QOpcUa::Types::String);
node->writeAttribute(attribute,var);
}

void MainWindow::SLOT_endpointsRequestFinished(QVector<QOpcUa::QEndpointDescription> endpoints, QOpcUa::UaStatusCode statusCode)
{
qDebug()<<endpoints.at(0).endpointUrl();
//qDebug() <<endpoints.first().endpointUrl();
qDebug()<<statusCode;
qDebug() << "Endpoints returned:" << endpoints.count();
qDebug()<<endpoints.size();
if (endpoints.size())
client->connectToEndpoint(endpoints.at(0).endpointUrl()); // Connect to the first endpoint in the list
}

void MainWindow::SLOT_attributeRead(QOpcUa::NodeAttributes attributes)
{
qDebug() << "Signal for attributes:" << attributes;
// if (node->attributeError(QOpcUa::NodeAttribute::BrowseName) != QOpcUa::UaStatusCode::Good) {
// qDebug() << "Failed to read attribute:" << node->attributeError(QOpcUa::NodeAttribute::BrowseName);
// client->disconnectFromEndpoint();
// }
//qDebug() << "Browse name:" << node->attribute(QOpcUa::NodeAttribute::BrowseName).value<QOpcUa::QQualifiedName>().name();
qDebug()<<"value:"<<node->attribute(QOpcUa::NodeAttribute::Value);

}

void MainWindow::SLOT_stateChanged(QOpcUaClient::ClientState state)
{
qDebug() << "Client state changed:" << state;
if (state == QOpcUaClient::ClientState::Connected) {
//QOpcUaNode定义
node = client->node("ns=2;s=my.plc.s1");
if (node)
qDebug() << "A node object has been created";
}
connect(node,&QOpcUaNode::attributeRead,this,&MainWindow::SLOT_attributeRead);

}



举报

相关推荐

0 条评论