From Friday, April 19th (11:00 PM CDT) through Saturday, April 20th (2:00 PM CDT), 2024, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

Example Code

OPC UA Shared Variable Server

Code and Documents

Attachment

Introduction

The OPC UA (Unified Architecture) standard has been introduced by the OPC foundation and offers some distinct advantages over the DA standard that we are most familiar with. A key advantage is that it is no longer built on COM technology which means we can run the server on platforms other than Windows, including Real-Time.

This example uses the OPC UA library, introduced to LabVIEW DSC module 2011 SP1, to automatically mirror selected shared variable libraries on a OPC UA server. This can be used as a drop in VI to add this functionality to a LabVIEW system.

Please note this is only example code and is released under the NI sample code license (See below). It has been developed and shared in LabVIEW 2011 as this is first version to officially support the OPC UA libraries.

Application Description

Start Up

A key part of this application is start up as this is where the connections get set up. The shared variables are scanned from the specified libraries (with the exclusion of the blacklist which is useful when working with scan engine IO). For each of these we create a synchronised tag object.

Following this we then build the structure of the OPC UA structure to mimic the SV structure. The array of objects is then put in to a data value reference (DVR). This allows us to access them in parallel loops.

Polling

The architecture then runs two loops to update between the two systems. The OPC UA updates are detected from a user event which the library fires when it detects an update (this again is actually done at a set interval). On detecting a change we identify which indexes in our object array this corresponds to and then update them apprpriately. The data value is given as a variant which greatly simplifies this piece of code.

For the Shared Variables (SVs) we have to poll the items periodically instead. The object contains the previously known value so we can check if this has changed or not (the DVR and shared objects means we can also track updates from the OPC UA server as well) and the OPC UA tag is updated if needed.

For this loop performance was very important so some diagnostic code was removed that tracked errors to a tag as dealing with strings was too slow. This is also why there is a single DVR containing an array of objects as opposed to an array of DVRs, meaning we have 1x the overhead of dereferencing, instead of Nx (the tradeoff is that the other loop is locked out of the DVR for longer).

Performance

The exact performance is going to depend on your poll rate and number of tags. At a polling rate of 500ms with 140 tags we saw an increase of CPU of around 12% on a 9025 cRIO controller. A similar test with 44 tags showed an increase of 2.66%.

Please feel free to try this and post any feedback you have on this page.

Objects

I have used a couple of classes and object oriented programming in this design. Why? It suited well, I either created clusters and VIs for each tag or an object. They are largely functionally (& performance) equivalent in this code (I am not using any features of object oriented code such as dynamic dispatching) but I much prefer the organisation that comes with the object oriented implementation over the clusters.

If you are unfamiliar with them the simplest way is to think of them as clusters combined with specific functions that can act on them.  In the project are the lvclass definitions which act as a library. The .ctl file will show you what data is stored in the object (looks a lot like a cluster ) and any VIs associated with accessing the data are also in the library.

License

The attached Code is provided As Is.  It has not been tested or validated as a product, for use in a deployed application or system, or for use in hazardous environments.  You assume all risks for use of the Code and use of the Code is subject to the Sample Code License Terms which can be found at: http://ni.com/samplecodelicense

James Mc
========
CLA and cRIO Fanatic
My writings on LabVIEW Development are at devs.wiresmithtech.com

Example code from the Example Code Exchange in the NI Community is licensed with the MIT license.

Comments
iCat
Member
Member
on

Does this OPC UA server support Alarm&Event and historical access?

James_McN
Active Participant Active Participant
Active Participant
on

This uses the OPC UA server included in DSC 2011 SP1 which does not include direct support for Alarms and Events. However you could use this idea to synchronise to shared variables on a Windows host which could have those abilities enabled.

James Mc
========
CLA and cRIO Fanatic
My writings on LabVIEW Development are at devs.wiresmithtech.com
NI-hilator
Member
Member
on

Will this run without the DSC module?

James_McN
Active Participant Active Participant
Active Participant
on

It needs either DSC or Real Time module for the OPC UA features. The shared variable access all use standard LabVIEW features so if you have only Real Time then it should all work fine as well.

James Mc
========
CLA and cRIO Fanatic
My writings on LabVIEW Development are at devs.wiresmithtech.com
NI-hilator
Member
Member
on

I have the Real time module.  When I did a mass compile it initially failed with the following "Search failed to find "NI_Real-Time Target Support.lvlib:RT Debug String.vi" previously from "<vilib>:\rtutility.llb\RT Debug String.vi".  After adding "...LabVIEW 2013\Targets\NI\RT\vi.lib" to my search path and did another mass compile, I got the following "Search failed to find "ni_opcua_base.dll" previously from "ni_opcua_base.dll".  I verified that OPC UA Client and Server APIs are installed on the target cRIO-9073.  When I deploy I still get the following error "LabVIEW:  Failed to load shared library ni_opcua_server.*:NIOPCUA_StartServer:C. Ensure that the library is present on the RT target. Use MAX to install NI software or FTP to transfer custom libraries to the RT target" As you know the 9073 is at the low end for available memory in the cRIO product line.  Can you tell me which minimum software needs to be loaded on the target to use the example?

James_McN
Active Participant Active Participant
Active Participant
on

That is likely to be because it is trying to compile for windows if it is missing the rtutility elements as well. Try opening it under an RT target and hold Ctrl+Shift and then hit the run button. This will compile the heirarchy for RT.

If you have the APIs installed to the cRIO that is all that should be required, it doesn't make sense why it is missing the DLL. You are also going to need the shared variable engine and variable client installed for that side of it. It sounds like something has gone wrong with the install on the RIO, you may need to try reinstalling the components. Also check if the shipping examples work, I expect they will have the same issue though.

James Mc
========
CLA and cRIO Fanatic
My writings on LabVIEW Development are at devs.wiresmithtech.com
NI-hilator
Member
Member
on

I formated and reinstalled the software to the crio target. Now it is erroring as follows: "Deploying NI OPC UA Server.lvlib:Stop.viNI OPC UA Server.lvlib:Stop.vi loaded with errors on the target and was closed. LabVIEW:  Failed to load shared library ni_opcua_server.*:NIOPCUA_StopServer:C. Ensure that the library is present on the RT target. Use MAX to install NI software or FTP to transfer custom libraries to the RT target"

When I press Ctrl-Shift Run, nothing visibly happens, I'm guessing it compiles in in the background because the "dirty" asterisk shows up in the title bar. I checked with an ftp tool that following are in the ni-rt/system folder: ni_opcua_base.out, ni_opcua_client.out, ni_opcua_server.out, ni_opcua_uastack.out. 

The OPC US Demo example project has the same error.

NIMAX _software OPC UA Test.PNG

James_McN
Active Participant Active Participant
Active Participant
on

You are right about the compile, it isn't very obvious it is doing anything!

It seems odd, it appears you do have everything installed correctly so to be frank I have no idea why it is still failing to load that library. If possible I would connect a serial cable to the console out of the target to see if it is spitting any errors out there. Otherwise I would suggest getting in touch with your support branch and opening a service request to investigate further as something is not quite right...

James Mc
========
CLA and cRIO Fanatic
My writings on LabVIEW Development are at devs.wiresmithtech.com
NI-hilator
Member
Member
on

James, in the readme.html file, section "Running this Project When an OPC UA Server and OPC UA Client Are on Different Machines" Step 3 & 4 mentions copying and renaming certificate files Server Demo Certificate.der and Client Demo Certificate.der.  I couldn't find these files in the zip that is posted here. I finally found multiple of each them under C:\\username\AppData, c:\Program Data\National Instruments\certstor along with a file called "Default OPC UA.der" file.  Which location I should be copying from and which files?  Do I use and rename the default .der file? Thanks!

Ooops... that readme is from the OPC UA Demo project in the NI Example Finder.

NI-hilator
Member
Member
on

James, can you tell me where ni_opcua_base.dll is located on your computer?  Is this something that should have been in the zip file you posted?

James_McN
Active Participant Active Participant
Active Participant
on

No it is nothing I have created, I presume it should be part of the standard OPC UA install. This example just uses the standard OPC UA API for all of it's access.

James Mc
========
CLA and cRIO Fanatic
My writings on LabVIEW Development are at devs.wiresmithtech.com
NI-hilator
Member
Member
on

Looks like a memory space issue on the crio-9073.  Stripped out some installed software and got passed the deployment error. 

I now get an Error -1950678941 at Read Variable With Timeout in Sinchronised Tag.lvclass:Update From Shared Varable.vi  This is the error description: "Error -1950678941 occurred at an unidentified location Possible reason(s):  LabVIEW:  An empty string is not a valid URL.  If you want to reference the root container within a variable engine, you need to specify the path explicitly using one of the following URL formats: "[Variable Engine]://[Host Name]", "[Variable Engine]:", or "/"."

I suppose I am getting this error because I am selecting my target's IO module in the Variable Browser, i.e. "ni.var.psp://xxx.xxx.xxx.xxx/Mod6" rather than a shared variable? Is this allowed?

YanYuan
NI Employee (retired)
on

The example server was written to only access the network-published shared variable (PSP variable), as "Read Variable With Timeout.vi" can only read network-published shared variable. You will need to use VI APIs under "Data Communication>>Shared Variable>>I/O Variable" to read/write I/O Variables and the URL is like "ni.var.io://xxx.xxx.xxx.xxx/Mod6/AI0".  Anyway, this is not something related to OPC UA APIs.

James_McN
Active Participant Active Participant
Active Participant
on

I would take a look and see what is happening in scan for tags.vi. YanYuan is right that we can't access the variables through ni.var.io but as long as network publishing is turned on it should be possible to access it through a psp variable as you have described and I have done this before.

In scan for variables probe the children wire and see what comes off, if these are blank then it may be you need to remove or add the '/' on the end (I can't remember which off the top of my head).

James Mc
========
CLA and cRIO Fanatic
My writings on LabVIEW Development are at devs.wiresmithtech.com
NI-hilator
Member
Member
on

Yan and James - thanks for the tip. 

Why is the Run-time Engine for Web Services required on the target cRIO?

YanYuan
NI Employee (retired)
on

Run-time Engine for Web Service is required by any NI Web Services on the target cRIO. In your case, NI System Configuration is the component depending on that as there are some Web Services involved to allow you configure the target RIO remotely.

NI-hilator
Member
Member
on

Hmmm... In Max Add/Remove Software, even without NI System Configuration selected, the Run-time Engine for Web Services only gets automatically selected (due to dependency I assume) when one of either OPC UA Server API or OPC UA Client API is selected.  It doesn't seem to have any dependency on NI System Configuration i.e. the Run-time Engine for Web Services does not automatically get checked when it is checked first.  I hate to belabor this observation - just trying to save memory on my 9073.  Thanks for your input.

adityakarthik
Member
Member
on

I am at the very start of using Labview as HMI for working on PLC programs. I successfully created tags for a simple test plc program and addressed tag to the front panel switches and LED indicators. When I hit PUSH button on front panel window screen I can see the change of output in OPC client but I see no change in the state of LED indicator.( the output is Boolean). I see output only in meter or tank indicator (converted output to an integer value). Even though I, have given correct data socket address to the LED indicator but the change of state remains off all the time.

Contributors