VS2015+Qt+OpenCV+open62541 development process (05_VS2015 uses OPCUA open62541 to read and write PLC data through Kepware)

The computer needs to install Kepware software. The version used in this experiment is KEPServerEX 6.3 (you need to purchase an authorization after installation, but there is a trial period for a period of time, which will not affect the experiment)

As an OPC UA server, Kepsever establishes communication with PLC, and writes OPC UA client in VS2015 to communicate with Kepsever server, so as to read and write the tag value of PLC.

To use open62541, you need to obtain relevant source files and header files first. The acquisition process is more complicated. Here is a reference to the tutorials posted by others on the Internet.

Reference article link: https://www.cnblogs.com/eatfishcat/p/11147242.html

According to the above article, copy the generated open62541.h and open62541.c to the project folder

In addition, the required lib package is also required: WS2_32.Lib (the library used for opcua communication, opcua uses socket communication, this library needs to be used), add #pragma comment(lib,”ws2_32.lib”) statement, some articles It is said that the ws2_32.lib file or ws2_32.dll needs to be added to the project resources, which seems to have little effect

The code is connected to the previous one, there are a lot of comment paragraphs, don’t mind)

// test01.cpp : Defines the entry point for the console application.

#include "open62541.h" //open62541 header file, opcua open source library file
#pragma comment(lib,"ws2_32.lib") //The library used for opcua communication, opcua uses socket communication, this library needs to be used

#include "stdafx.h"
#include <iostream>
#include<windows.h> //Use Sleep(1000) delay function header file
#include <stdio.h>
#include <process.h>
#include <conio.h>
#include "string.h"

//#include <opencv2/opencv.hpp> //opencv header file
//#include<opencv2/core.hpp>
//#include <opencv2/imgproc.hpp>
//#include<opencv2/highgui.hpp>
//#include <opencv2/videoio.hpp>

using namespace std; //use namespace
//using namespace cv;

/*declare global variables*/
//VideoCapture capture;
UA_Client *client = UA_Client_new(); //opcua client structure, used to communicate with PLC
UA_StatusCode status; //Used to store the status feedback after the opcua client executes the operation
/*main function*/
int main()
{
/*Mat img;
Mat hsv;
Mat hsvsplit[3];
cv::namedWindow("test", WINDOW_FREERATIO);
cv::namedWindow("test1", WINDOW_FREERATIO);
cv::namedWindow("test2", WINDOW_FREERATIO);
cv::namedWindow("test3", WINDOW_FREERATIO);
cv::namedWindow("test4", WINDOW_FREERATIO);*/

client = UA_Client_new(); //create opcua client
UA_ClientConfig_setDefault(UA_Client_getConfig(client)); //Set the client as the default configuration
status = UA_Client_connect(client, "opc.tcp://127.0.0.1:49320"); //Connect to the server, connect to KEPServer here, the URL can be viewed by right-clicking the KEPServer software on the taskbar and selecting "OPC UA Configuration"
//Judge the connection status of the opcua client
if (status != UA_STATUSCODE_GOOD)
{
cout << "Connect OPC UA Sever Failed" << endl;
return 0;
}
else
{
cout << "Connect OPC UA Sever Successful" << endl;
}

//
//capture = VideoCapture(0); //Open the camera
//capture.set(CAP_PROP_FRAME_WIDTH, 2448); // Set image width
//capture.set(CAP_PROP_FRAME_HEIGHT, 2048); // set image height
//capture.set(CAP_PROP_FPS, 5); // set frame rate
//if (!capture.isOpened())
//{
// cout << "open camera failed." << endl;
// capture. release();
// return 0;
//}

//
//capture >> img; //Read a frame in the video stream and write it into img
//cv::cvtColor(img, hsv, COLOR_BGR2HSV);
//cv::split(hsv, hsvsplit);

//cv::imshow("test", img); //Display a picture in the window
//cv::imshow("test1", hsv);
//cv::imshow("test2", hsvsplit[0]);
//cv::imshow("test3", hsvsplit[1]);
//cv::imshow("test4", hsvsplit[2]);

//cv::waitKey(0); //wait for the keyboard to be pressed, and then execute the following program
//destroyAllWindows();
//capture. release();
UA_Client_delete(client); //Release opcua client
return 0;
}

Add the OPC UA header file and the statement connecting to the server to the main program, there are 120 errors in debugging, the reason is that the location of the header file is wrong, and there are duplicate definitions

Put the header file statement at the top, and there are still 26 errors in debugging and compiling. The reason is that the x64 platform selected for debugging can use the x86 platform. This problem has not been solved, because the opencv4.5.4 used must be 64-bit, but we will use the Qt framework later, and the Qt framework is cross-platform, which should eliminate such errors.

Debug platform switched to x86

Put the header file on the top, comment out the opencv related statements, and only keep the connection to the Kepsever server statement. After debugging, it is found that the server connection failed

Need to change Kepsever related OPC UA configuration

Right-click the Kepsever icon on the task bar in the lower right corner of the computer, click OPC UA Configuration – Security Policy and click “None”

Project properties in Kepsever software – OPC UA – allow anonymous login point “Yes”

After configuration, re-initialize the kepsever runtime, and then debug and run in VS, showing that the connection is successful

Add PLC tag points in Kepsever, try to use VS programming to read and write the “channel 1. device 1. mark 2” tag established by default in kepsever for testing

It was found that the reading failed because the label name in VS cannot be in Chinese

Create the channel label by yourself for testing, “test.test.OPC_test”, since there is no actual connection to the PLC, the channel establishment selects Simulator simulation

Change the tag point of reading and writing of the VS program to “test.test.OPC_test”, the operation is successful, and the operation can be read and written

Test code:

// test01.cpp : Defines the entry point for the console application.

#include "open62541.h" //open62541 header file, opcua open source library file
#pragma comment(lib,"ws2_32.lib") //The library used for opcua communication, opcua uses socket communication, this library needs to be used

#include "stdafx.h"
#include <iostream>
#include<windows.h> //Use Sleep(1000) delay function header file
#include <stdio.h>
#include <process.h>
#include <conio.h>
#include "string.h"

//#include <opencv2/opencv.hpp> //opencv header file
//#include<opencv2/core.hpp>
//#include <opencv2/imgproc.hpp>
//#include<opencv2/highgui.hpp>
//#include <opencv2/videoio.hpp>



using namespace std; //use namespace
//using namespace cv;

/*declare global variables*/
//VideoCapture capture;
UA_Client *client = UA_Client_new(); //opcua client structure, used to communicate with PLC
UA_StatusCode status; //Used to store the status feedback after the opcua client executes the operation
/*main function*/
int main()
{
/*Mat img;
Mat hsv;
Mat hsvsplit[3];
cv::namedWindow("test", WINDOW_FREERATIO);
cv::namedWindow("test1", WINDOW_FREERATIO);
cv::namedWindow("test2", WINDOW_FREERATIO);
cv::namedWindow("test3", WINDOW_FREERATIO);
cv::namedWindow("test4", WINDOW_FREERATIO);*/

client = UA_Client_new(); //create opcua client
UA_ClientConfig_setDefault(UA_Client_getConfig(client)); //Set the client as the default configuration
status = UA_Client_connect(client, "opc.tcp://127.0.0.1:49320"); //Connect to the server, connect to KEPServer here, the URL can be viewed by right-clicking the KEPServer software on the taskbar and selecting "OPC UA Configuration"
//Judge the connection status of the opcua client
if (status != UA_STATUSCODE_GOOD)
{
cout << "Connect OPC UA Sever Failed" << endl;
return 0;
}
else
{
cout << "Connect OPC UA Sever Successful" << endl;
}

UA_Variant value; //opcua variable type
UA_Variant_init( & amp;value); //Initialization, note that the value of value.data cannot be read directly after initialization, which will cause memory pointer errors, and value.data must be read or assigned through opcua
long OPC_test=5;
status = UA_Client_readValueAttribute(client, UA_NODEID_STRING(2, "test.test.OPC_test"), & amp;value);
if (status != UA_STATUSCODE_GOOD)
{
cout << "OPC UA read Failed" << endl;
return 0;
}
else
{
cout << "OPC UA read Successful" << endl;
}
OPC_test = *(UA_UInt32*)value.data;
cout << "OPC_test original value:" << OPC_test<< endl;

OPC_test = OPC_test + 1;
UA_Variant_setScalar( & amp;value, & amp;OPC_test, & amp;UA_TYPES[UA_TYPES_UINT32]); //Write the test result variable into the OPCUA variable
status = UA_Client_writeValueAttribute(client, UA_NODEID_STRING(2, "test.test.OPC_test"), & amp;value); //write the test result value to PLC
if (status != UA_STATUSCODE_GOOD)
{
cout << "OPC UA write Failed" << endl;
return 0;
}
else
{
cout << "OPC UA write Successful" << endl;
}

status = UA_Client_readValueAttribute(client, UA_NODEID_STRING(2, "test.test.OPC_test"), & amp;value);
if (status != UA_STATUSCODE_GOOD)
{
cout << "OPC UA read Failed" << endl;
return 0;
}
else
{
cout << "OPC UA read Successful" << endl;
}
OPC_test = *(UA_UInt32*)value.data;
cout << "OPC_test changed:" << OPC_test << endl;

//
//capture = VideoCapture(0); //Open the camera
//capture.set(CAP_PROP_FRAME_WIDTH, 2448); // Set image width
//capture.set(CAP_PROP_FRAME_HEIGHT, 2048); // set image height
//capture.set(CAP_PROP_FPS, 5); // set frame rate
//if (!capture.isOpened())
//{
// cout << "open camera failed." << endl;
// capture. release();
// return 0;
//}


//
//capture >> img; //Read a frame in the video stream and write it into img
//cv::cvtColor(img, hsv, COLOR_BGR2HSV);
//cv::split(hsv, hsvsplit);

//cv::imshow("test", img); //Display a picture in the window
//cv::imshow("test1", hsv);
//cv::imshow("test2", hsvsplit[0]);
//cv::imshow("test3", hsvsplit[1]);
//cv::imshow("test4", hsvsplit[2]);

//cv::waitKey(0); //wait for the keyboard to be pressed, and then execute the following program
//destroyAllWindows();
//capture. release();
UA_Client_delete(client); //Release opcua client
return 0;
}

1. Read the test point for display

2. Add 1 to the variable and write to the test point

3. Read the test point again for display

Summarize:

1. open62541 is an OPC UA open source code. Although generating source files and header files requires downloading source code and cmake, it is cumbersome to use, but it only needs to be used once, and can be used directly after generation, once and for all

2. If you choose the x64 platform in VS, an error will be reported. If you choose the x86 platform, it can be used. It should be that the library related to ws2_32.lib does not support 64 bits. It has not been solved at present. Continue the following experiments to see if it can be solved after using Qt

3. Before doing the OPC UA communication experiment, I also tried OPC DA to read and write the OPC server successfully, but the code of DA is cumbersome, and the environment configuration is also cumbersome. Here, I will abandon DA and choose UA.

4. The security policy of kepsever and the permission of anonymous login need to be configured. If not configured, the code for security verification should be added. It is not used here, so the security policy should be reduced to the minimum directly.

5. The middle point name of kepsever read in VS cannot have Chinese

6. The variable established in VS corresponds to the data type of the read OPC point