open62541学习(1)-windows
open62541 是 OPC UA的一种实现方式(开源库),OPC UA 可用于PLC通信,可用于 PLC 跟 PC 之间进行通信。
参考链接
https://blog.csdn.net/whahu1989/article/details/104563226
https://www.cnblogs.com/chenzibai/p/16834824.html
MSDN:
https://www.cnblogs.com/xue0708/p/10168016.html
介绍
open62541 是 OPC UA的一种实现方式(开源库),OPC UA 可用于PLC通信,可用于 PLC 跟 PC 之间进行通信。
使用vs2019编译
下载open62541源码
https://github.com/open62541/open62541.git
使用cmake进行编译
打开cmake-gui,source code行填写open62541源码路径,build路径在源码里面新建一个就行,然后点击configure
根据自己的需求选择合适的VS版本,然后选择默认的compilers,之后点击finish
ps:如果出现 python3未找到并报错如图所示
则点击add entry新建一个变量,并在value中添加自己python3的路径,可以通过cmd查询已有的python环境安装路径,完成之后再次点击configure
py -0p
再次点击后还是出现大片红色,此时只需勾选UA_ENABLE_AMALGAMATION即可,再次点击configure
configure完成之后,没有报红了,此时需要点击Generate,再选择右边的Open Project即可通过自己的vs打开该工程
效果如下,随后点击生成解决方案
接着报错编码格式有误,然后点击报错的文件(open62541.c),添加17行所示代码
再次点击生成解决方案,之后便生成所示三个文件
编写测试OPC UA Server
1.初始化项目
打开vs新建一个项目,在工程中将open62541.h和.c文件拷贝过来,然后添加一个.cpp文件
如下:
在回到vs中,添加现有项,将.c和.h添加进来,如下
test1.cpp
// server.c
/* This work is licensed under a Creative Commons CCZero 1.0 Universal License.
* See http://creativecommons.org/publicdomain/zero/1.0/ for more information. */
#include "open62541.h"
#include <signal.h>
#include <stdlib.h>
UA_Boolean running = true;
static void stopHandler(int sign) {
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_SERVER, "received ctrl-c");
running = false;
}
int main(void)
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData); // 使用Winsock 2.2版本
signal(SIGINT, stopHandler);
signal(SIGTERM, stopHandler);
UA_Server* server = UA_Server_new();
UA_ServerConfig_setDefault(UA_Server_getConfig(server));
UA_StatusCode retval = UA_Server_run(server, &running);
UA_Server_delete(server);
return retval == UA_STATUSCODE_GOOD ? EXIT_SUCCESS : EXIT_FAILURE;
}
2.问题解决
在代码中添加所示代码
#pragma comment(lib,"ws2_32.lib")
还有报错, error LNK2019: 无法解析的外部符号 __imp__if_nametoindex@4,函数 _setupListenMulticastIPv6 中引用了该符号
在代码中添加所示代码
#pragma comment(lib, "Iphlpapi.lib")
之后运行程序,成功
编写测试OPC UA Client
初始化项目
按照服务端相同步骤配置客户端,客户端功能用于获取服务端的系统时间
client.cpp
// client.c,功能主要是从server那里获取时间
#include <stdlib.h>
#include "open62541.h"
#pragma comment(lib,"ws2_32.lib")
#pragma comment(lib, "Iphlpapi.lib")
int main(void)
{
WSADATA wsaData;
WSAStartup(MAKEWORD(2, 2), &wsaData); // 使用Winsock 2.2版本
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;
}
/* Read the value attribute of the node. UA_Client_readValueAttribute is a
* wrapper for the raw read service available as UA_Client_Service_read. */
UA_Variant value; /* Variants can hold scalar values and arrays of any type */
UA_Variant_init(&value);
/* NodeId of the variable holding the current time */
const UA_NodeId nodeId = UA_NODEID_NUMERIC(0, UA_NS0ID_SERVER_SERVERSTATUS_CURRENTTIME);
retval = UA_Client_readValueAttribute(client, nodeId, &value);
if (retval == UA_STATUSCODE_GOOD && UA_Variant_hasScalarType(&value, &UA_TYPES[UA_TYPES_DATETIME]))
{
UA_DateTime raw_date = *(UA_DateTime*)value.data;
UA_DateTimeStruct dts = UA_DateTime_toStruct(raw_date);
UA_LOG_INFO(UA_Log_Stdout, UA_LOGCATEGORY_USERLAND, "date is: %u-%u-%u %u:%u:%u.%03u\n",
dts.day, dts.month, dts.year, dts.hour, dts.min, dts.sec, dts.milliSec);
}
/* Clean up */
UA_Variant_clear(&value);
UA_Client_delete(client); /* Disconnects the client internally */
system("pause"); // 防止控制台一闪而过
return EXIT_SUCCESS;
}
更多推荐
所有评论(0)