OPC UA开源库Open62541源码编译及Client客户端Server服务器端测试[一]

前言   

    

        1.Open62541 概述  

        2.Open62541 的功能  

        3.Open62541 的开发环境  

        4.Open62541 编译工具  

        5.Open62451源码下载

        6.Open62541源码编译

        7.Open62541 Server服务器端测试

        8.Open62541Client客户端测试

        Open62541 是一款开源的嵌入式系统开发手册,旨在帮助开发者快速掌握 Open62541 的开发技能。本文将从 Open62541 的概述、功能、开发环境、编程接口和应用案例五个方面进行介绍。

一、Open62541 概述  

        Open62541 是一款面向物联网、智能家居和工业控制等领域的嵌入式系统开发手册。它基于 Linux 内核,提供了丰富的硬件驱动和软件接口,方便开发者进行定制化开发。

二、Open62541 的功能  

        Open62541 具有以下主要功能:  

        1.实时操作系统:基于 Linux 内核,支持多任务、多线程,提供实时性能。  

        2.丰富的硬件驱动:支持多种常见硬件设备,如显示器、触摸屏、传感器等。  

        3.强大的网络支持:支持以太网、Wi-Fi、蓝牙等多种网络协议,方便接入互联网。  

        4.安全性:提供安全启动、安全传输等机制,保障系统安全。

三、Open62541 的开发环境  

        开发 Open62541 系统需要以下工具和环境:  

        1.开发板:需要一块支持 Open62541 的开发板,如 Raspberry Pi、树莓派等。  

        2.编辑器:可以使用任何文本编辑器,如 Notepad++、Visual Studio Code 等。  

        3.编译器:需要安装 GCC(GNU Compiler Collection)等编译工具。  

        4.调试器:可以使用 GDB(GNU Debugger)等调试工具。

四、Open62541编译工具

        1、Cmake gui。

        2、Visual Stu'di'o 2019。

        3、Python3。

五、Open62541源码下载

        1、官方网站


https://www.open62541.org/icon-default.png?t=N7T8https://www.open62541.org/        2、GitHub

https://github.com/open62541/open62541icon-default.png?t=N7T8https://github.com/open62541/open62541 

        3 、无法连接Open62541官网或者Github官网的解决办法。

        存在无法连接Open62541官网或者Github官网的解决办法主要是修改系统C:\Windows\System32\drivers\etc目录下的Hosts文件,在Hosts文件末尾加入如下代码

        #github
        140.82.112.4 github.com
        199.232.69.194 github.global.ssl.fastly.net

六、Open62541源码编译

        1、所需编译工具Cmake Gui,Visual Studio2019,Python3。

        2、编译过程

        (1)首先将下载后的源码解压到当前目录,并建立一个存放编译后目标文件的文件夹这里我们建立的文件夹名称为Open62541Build,如下图所示。

         (2)打开Cmake Gui配置文件路径如下图所示。

        (3)选择UA_ENABLE_AMALGAMATION选项为单独生产Open62541.h文件和Open62541.c文件,Cmakelist文件中有提到这一点。

        (4)编译目标环境配置为win32,Visual Studio 2019版本后进行编译,如下图所示。

        (5)编译完成后使用Visual Studio2019打开open62541.sln项目文件进行编译。目标环境选择Release Win32。

        (6)选择生产生成-->生成解决方案进行生成,如下所示。

        (7)编译完成后在目标文件夹下面可以看到Bin文件夹和Open62541.h文件和Open62541.c文件,如下图所示。

七、Open62541 Server服务器端测试

        1、打开Visual Studio 2019新建名为Open62541ServerDemo的控制台程序。增加Open62541.h和Open62541.c文件。

        2、项目属性连接器->输入->附加依赖项种增加WS2_32.Lib文件,不然编译会报错。如下图所示。

        3、Open62541ServerDemo.cpp文件中增加如下代码。

#include <signal.h>
#include <stdlib.h>#include "open62541.h"UA_Boolean running = true;static void stopHandler(int sign) {UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "received ctrl-c");running = false;
}static void addLocalizedTextVariable(UA_Server* server, char* name)
{/* Define the attribute of the myInteger variable node */UA_VariableAttributes attr = UA_VariableAttributes_default;UA_LocalizedText orig = UA_LOCALIZEDTEXT((char*)"en-US", "hello");UA_Variant_setScalar(&attr.value, &orig, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);attr.description = UA_LOCALIZEDTEXT("en-US", name);attr.displayName = UA_LOCALIZEDTEXT("en-US", name);attr.dataType = UA_TYPES[UA_TYPES_LOCALIZEDTEXT].typeId;attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE;/* Add the variable node to the information model */UA_NodeId myNodeId = UA_NODEID_STRING(1,name);UA_QualifiedName myName = UA_QUALIFIEDNAME(1, name);UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0,UA_NS0ID_OBJECTSFOLDER);UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);UA_Server_addVariableNode(server, myNodeId, parentNodeId, parentReferenceNodeId, myName,UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), attr, NULL, NULL);
}static void addUInt32Variable(UA_Server* server, char* name)
{/* Define the attribute of the myInteger variable node */UA_VariableAttributes attr = UA_VariableAttributes_default;UA_UInt32 orig = 100;UA_Variant_setScalar(&attr.value, &orig, &UA_TYPES[UA_TYPES_UINT32]);attr.description = UA_LOCALIZEDTEXT("en-US", name);attr.displayName = UA_LOCALIZEDTEXT("en-US", name);attr.dataType = UA_TYPES[UA_TYPES_UINT32].typeId;attr.accessLevel = UA_ACCESSLEVELMASK_READ | UA_ACCESSLEVELMASK_WRITE;/* Add the variable node to the information model */UA_NodeId myNodeId = UA_NODEID_STRING(1, name);UA_QualifiedName myName = UA_QUALIFIEDNAME(1, name);UA_NodeId parentNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_OBJECTSFOLDER);UA_NodeId parentReferenceNodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_ORGANIZES);UA_Server_addVariableNode(server, myNodeId, parentNodeId, parentReferenceNodeId, myName,UA_NODEID_NUMERIC(0, UA_NS0ID_BASEDATAVARIABLETYPE), attr, NULL, NULL);
}int main(void)
{signal(SIGINT, stopHandler);signal(SIGTERM, stopHandler);UA_Server* server = UA_Server_new();UA_ServerConfig_setDefault(UA_Server_getConfig(server));addLocalizedTextVariable(server, "info1");addLocalizedTextVariable(server, "info2");addLocalizedTextVariable(server, "info3");addUInt32Variable(server, "uint1");addUInt32Variable(server, "uint2");addUInt32Variable(server, "uint3");UA_StatusCode retval = UA_Server_run(server, &running);UA_Server_delete(server);return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}

        4、运行Server项目。可以看到服务器建立成功地址为opc.tcp://DESKTOP-14CFB38:4840

         5、UaExpert连接服务器,在UaExpert中添加服务器如下图所示。

        6、连接成功后将变量增加到数据视图中进行监控。

8、Open62541Client客户端测试

        1、客户端和服务器端一样都是建立控制台项目,增加Open62541.h和Open62541.c文件项目属性附加依赖库中增加WS2_32.Lib文件,如下图所示。

        2、Open62541ClientDemo.cpp文件中增加如下代码。

#include <stdlib.h>
#include <stdio.h>
#include "open62541.h"static UA_StatusCode multiRead(UA_Client* client)
{const int arraySize = 6;UA_ReadValueId itemArray[arraySize];for (int i = 0; i < arraySize; ++i){UA_ReadValueId_init(&itemArray[i]);itemArray[i].attributeId = UA_ATTRIBUTEID_VALUE;}itemArray[0].nodeId = UA_NODEID_STRING(1, "info1");itemArray[1].nodeId = UA_NODEID_STRING(1, "info2");itemArray[2].nodeId = UA_NODEID_STRING(1, "info3");itemArray[3].nodeId = UA_NODEID_STRING(1, "uint1");itemArray[4].nodeId = UA_NODEID_STRING(1, "uint2");itemArray[5].nodeId = UA_NODEID_STRING(1, "uint3");UA_ReadRequest request;UA_ReadRequest_init(&request);request.nodesToRead = &itemArray[0];request.nodesToReadSize = arraySize;UA_ReadResponse response = UA_Client_Service_read(client, request);UA_StatusCode retStatusArray[arraySize];UA_StatusCode retval = response.responseHeader.serviceResult;if (retval == UA_STATUSCODE_GOOD){if (response.resultsSize == arraySize){for (int i = 0; i < arraySize; ++i){retStatusArray[i] = response.results[i].status;}}else{UA_ReadResponse_clear(&response);return UA_STATUSCODE_BADUNEXPECTEDERROR;}}for (int i = 0; i < arraySize; ++i){if (retStatusArray[i] == UA_STATUSCODE_GOOD){UA_DataValue res = response.results[i];if (!res.hasValue) // no value{UA_ReadResponse_clear(&response);return UA_STATUSCODE_BADUNEXPECTEDERROR;}UA_Variant out;memcpy(&out, &res.value, sizeof(UA_Variant));UA_Variant_init(&res.value);if (out.type == &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]){UA_LocalizedText* ptr = (UA_LocalizedText*)out.data;printf("Text: %.*s\n", ptr->text.length, ptr->text.data);}else if (out.type == &UA_TYPES[UA_TYPES_UINT32]){UA_UInt32* ptr = (UA_UInt32*)out.data;printf("UInt32 Value: %d\n", *ptr);}}}UA_ReadResponse_clear(&response);return UA_STATUSCODE_GOOD;
}UA_StatusCode multiWrite(UA_Client* client, UA_UInt32 Index)
{const int arraySize = 6;UA_WriteValue wValueArray[arraySize];for (int i = 0; i < arraySize; ++i){UA_WriteValue_init(&wValueArray[i]);wValueArray[i].attributeId = UA_ATTRIBUTEID_VALUE;}wValueArray[0].nodeId = UA_NODEID_STRING(1, "info1");wValueArray[1].nodeId = UA_NODEID_STRING(1, "info2");wValueArray[2].nodeId = UA_NODEID_STRING(1, "info3");wValueArray[3].nodeId = UA_NODEID_STRING(1, "uint1");wValueArray[4].nodeId = UA_NODEID_STRING(1, "uint2");wValueArray[5].nodeId = UA_NODEID_STRING(1, "uint3");UA_Variant infoVar;UA_LocalizedText info1Value = UA_LOCALIZEDTEXT("en-US", "world1");UA_Variant_init(&infoVar);UA_Variant_setScalar(&infoVar, &info1Value, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);wValueArray[0].value.value = infoVar;wValueArray[0].value.hasValue = true;UA_LocalizedText info2Value = UA_LOCALIZEDTEXT("en-US", "world2");UA_Variant_init(&infoVar);UA_Variant_setScalar(&infoVar, &info2Value, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);wValueArray[1].value.value = infoVar;wValueArray[1].value.hasValue = true;UA_LocalizedText info3Value = UA_LOCALIZEDTEXT("en-US", "world3");UA_Variant_init(&infoVar);UA_Variant_setScalar(&infoVar, &info3Value, &UA_TYPES[UA_TYPES_LOCALIZEDTEXT]);wValueArray[2].value.value = infoVar;wValueArray[2].value.hasValue = true;UA_UInt32 uint1Value = 101+Index;UA_Variant_init(&infoVar);UA_Variant_setScalar(&infoVar, &uint1Value, &UA_TYPES[UA_TYPES_UINT32]);wValueArray[3].value.value = infoVar;wValueArray[3].value.hasValue = true;UA_UInt32 uint2Value = 102+Index;UA_Variant_init(&infoVar);UA_Variant_setScalar(&infoVar, &uint2Value, &UA_TYPES[UA_TYPES_UINT32]);wValueArray[4].value.value = infoVar;wValueArray[4].value.hasValue = true;UA_UInt32 uint3Value = 103+Index;UA_Variant_init(&infoVar);UA_Variant_setScalar(&infoVar, &uint3Value, &UA_TYPES[UA_TYPES_UINT32]);wValueArray[5].value.value = infoVar;wValueArray[5].value.hasValue = true;UA_WriteRequest wReq;UA_WriteRequest_init(&wReq);wReq.nodesToWrite = &wValueArray[0];wReq.nodesToWriteSize = arraySize;UA_WriteResponse wResp = UA_Client_Service_write(client, wReq);UA_StatusCode retval = wResp.responseHeader.serviceResult;if (retval == UA_STATUSCODE_GOOD) {if (wResp.resultsSize == 1)retval = wResp.results[0];elseretval = UA_STATUSCODE_BADUNEXPECTEDERROR;}UA_WriteResponse_clear(&wResp);return retval;}int main(void)
{UA_UInt32 mIndex;mIndex = 0;UA_Client* client = UA_Client_new();UA_ClientConfig_setDefault(UA_Client_getConfig(client));UA_StatusCode retval = UA_Client_connect(client, "opc.tcp://localhost:4840");if (retval != UA_STATUSCODE_GOOD) {UA_Client_delete(client);return (int)retval;}while (1){printf("---- Before write ---- \n");multiRead(client);printf("\n\n");multiWrite(client, mIndex);printf("---- After write ---- \n");multiRead(client);mIndex++;}UA_Client_delete(client); /* Disconnects the client internally */return EXIT_SUCCESS;
}

         3、运行客户端程序进行测试。使用UaExpert进行监控如下图所示。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/414520.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

c# 自定义 滑块TrackBar

辛苦半天做出来的&#xff0c;如果觉得好用&#xff0c;记得点赞 效果图如下&#xff1a; 具体操作&#xff1a; 1 、添加代码&#xff08;代码在下面&#xff09;&#xff0c;重新生成下整个工程&#xff0c;在工具栏中就出现控件&#xff0c;将控件拖到窗体中 2、只需要调整…

分享 GitHub 上的敏感词汇工具类:sensitive-word

&#x1f604; 19年之后由于某些原因断更了三年&#xff0c;23年重新扬帆起航&#xff0c;推出更多优质博文&#xff0c;希望大家多多支持&#xff5e; &#x1f337; 古之立大事者&#xff0c;不惟有超世之才&#xff0c;亦必有坚忍不拔之志 &#x1f390; 个人CSND主页——Mi…

6.3.5编辑视频

6.3.5编辑视频 除了上面的功能外&#xff0c;Camtasia4还能进行简单的视频编辑工作&#xff0c;如媒体的剪辑、连接、画中画等。 下面我们就利用Camtasia4的强大功能来实现一个画中画效果&#xff0c;在具体操作之前&#xff0c;需要准备好两个视频文件&#xff0c;一个作为主…

Python使用HTTP代理实现网络请求的调试和日志记录

在Python中&#xff0c;使用HTTP代理可以实现网络请求的调试和日志记录。通过HTTP代理&#xff0c;我们可以拦截、修改或记录网络请求和响应的数据&#xff0c;以便更好地了解和调试网络请求。 下面是一个使用Python和httplib2库实现HTTP代理的示例&#xff0c;同时对请求和响…

费斯托工具如何借助CRM为业务赋能?

对于“以客户为中心”的企业来说&#xff0c;要提升企业业绩&#xff0c;就要确保与客户在营销、销售、服务每一个环节上的交互都顺利、高效&#xff0c;而CRM系统正是承载这些功能的数字化工具。从图特斯工具系统技术&#xff08;上海&#xff09;有限公司&#xff08;简称“费…

计数排序归并排序(递归版本非递归版本)

1.计数排序 计数排序是一种非比较排序算法&#xff0c;其核心思想是通过统计每个元素出现的次数&#xff0c;然后根据统计结果将元素按照顺序放置在输出数组中。 以下是计数排序的逻辑思想&#xff08;C语言版&#xff09;&#xff1a; 1. 首先&#xff0c;遍历待排序的数组&am…

[足式机器人]Part2 Dr. CAN学习笔记- Kalman Filter卡尔曼滤波器Ch05-3+4

本文仅供学习使用 本文参考&#xff1a; B站&#xff1a;DR_CAN Dr. CAN学习笔记 - Kalman Filter卡尔曼滤波器 Ch05-34 3. Step by step : Deriation of Kalmen Gain 卡尔曼增益/因数 详细推导4. Priori/Posterrori error Covariance Martix 误差协方差矩阵 3. Step by step :…

Spring Boot - 利用Resilience4j-Circuitbreaker实现断路器模式_防止级联故障

文章目录 PreResilience4j概述Resilience4j官方地址Resilience4j-Circuitbreaker应用场景微服务演示Address servicePOMModelRepositoryServiceControllerData InitProperties测试 Order serviceModelRepositoryServiceSet UpProperties测试 探究断路器调用order-service API 2…

Java网络编程——UDP通信原理

一、TCP和UDP概述 传输层通常以TCP和UDP协议来控制端点与端点的通信 TCPUDP协议名称传输控制协议用户数据包协议是否连接面向连接的协议。数据必须要建立连接无连接的协议&#xff0c;每个数据报中都给出完整的地址信息&#xff0c;因此不需要事先建立发送方和接受方的连接是…

leetcode 013二维区域和检索---矩阵不可变

给定一个二维矩阵 matrix&#xff0c;以下类型的多个请求&#xff1a; 计算其子矩形范围内元素的总和&#xff0c;该子矩阵的左上角为 (row1, col1) &#xff0c;右下角为 (row2, col2) 。 实现 NumMatrix 类&#xff1a; NumMatrix(int[][] matrix) 给定整数矩阵 matrix 进…

jrebel IDEA 热部署

1 下载 2022.4.1 JRebel and XRebel - IntelliJ IDEs Plugin | Marketplace 2 选择下载好的zip 离线安装IDEA 插件 重启IDEA 3 打开 [Preference -> JRebel & XRebel] 菜单&#xff0c;输入 GUID address 为 https://jrebel.qekang.com/1e67ec1b-122f-4708-87d…

买家福音:亚马逊鲲鹏系统全自动操作助你轻松搞定一切

我一直以来都是亚马逊的忠实用户&#xff0c;但是最近我发现了一款真正令人惊叹的工具&#xff0c;改变了我在平台上的经验。我想分享一下我的感受&#xff0c;最近&#xff0c;我得知并尝试了亚马逊鲲鹏系统&#xff0c;简直是为买家账号管理量身定制的利器。在我账号过多时&a…