参考链接

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

  1. 介绍

open62541 是 OPC UA的一种实现方式(开源库),OPC UA 可用于PLC通信,可用于 PLC 跟 PC 之间进行通信。

  1. 使用vs2019编译

  1. 下载open62541源码

https://github.com/open62541/open62541.git
  1. 使用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行所示代码

再次点击生成解决方案,之后便生成所示三个文件

  1. 编写测试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")

之后运行程序,成功

  1. 编写测试OPC UA Client

  1. 初始化项目

按照服务端相同步骤配置客户端,客户端功能用于获取服务端的系统时间

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;
}
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐