Online Forums
Technical support is provided through Support Forums below. Anybody can view them; you need to Register/Login to our site (see links in upper right corner) in order to Post questions. You do not have to be a licensed user of our product.
Please read Rules for forum posts before reporting your issue or asking a question. OPC Labs team is actively monitoring the forums, and replies as soon as possible. Various technical information can also be found in our Knowledge Base. For your convenience, we have also assembled a Frequently Asked Questions page.
Do not use the Contact page for technical issues.
QuickOPC.Net Slow
Please Log in or Create an account to join the conversation.
- Peter Siegel
- Visitor
Please Log in or Create an account to join the conversation.
Please Log in or Create an account to join the conversation.
- Peter Siegel
- Visitor
I tried you sample and it is fast enough, however when using the OPC Server included in WinCC with a SPS S7300, it is again 1500 ms for one cycle.
But I think that could be a serverside Problem.
Please Log in or Create an account to join the conversation.
using OpcLabs.EasyOpc;
using OpcLabs.EasyOpc.DataAccess;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace _20100929
{
class Program
{
static void Main(string[] args)
{
string OPCServerID = "OPCLabs.KitServer";
string dataPoint_Name = "Simulation.Register_I1";
int dataPoint_SendValue = 123;
string markerFromID = "Simulation.Random";
string markerToID = "Simulation.Register_BOOL";
EasyDAClient.ClientParameters.TopicProcessingIntervalTimeout = 10;
var easyDAClient = new EasyDAClient();
easyDAClient.HoldPeriods.TopicRead = 24 * 60 * 60 * 1000;
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
watch.Reset();
watch.Start();
Console.Out.WriteLine("Preparing...");
easyDAClient.ReadMultipleItemValues(new DAItemArguments[] {
new DAItemArguments("", OPCServerID, dataPoint_Name),
new DAItemArguments("", OPCServerID, markerFromID),
new DAItemArguments("", OPCServerID, markerToID)
});
Console.Out.WriteLine("Prepare: " + watch.ElapsedMilliseconds);
Console.Out.WriteLine("Sleeping...");
Thread.Sleep(5 * 1000);
watch.Reset();
watch.Start();
Console.Out.WriteLine("Sending...");
OperationResult[] result = easyDAClient.WriteMultipleItemValues(new DAItemValueArguments[] {
new DAItemValueArguments("", OPCServerID, dataPoint_Name, dataPoint_SendValue),
new DAItemValueArguments("", OPCServerID, markerFromID, VarType.Bool, false, null),
new DAItemValueArguments("", OPCServerID, markerToID, VarType.Bool, true, null)
});
Console.Out.WriteLine("Send: " + watch.ElapsedMilliseconds);
//Wait for Event Marker released confirmation
Console.Out.WriteLine("Waiting...");
int count = 0;
bool read = false;
do
{
count++;
object val = easyDAClient.ReadItemValue("", OPCServerID, markerFromID, VarType.Bool);
if ((val != null) && (Convert.ToBoolean(val)))
read = true;
if (!read) Thread.Sleep(10);
} while (!read);
read = false;
Console.Out.WriteLine("Write Total: " + watch.ElapsedMilliseconds);
watch.Stop();
}
}
}
The main issue here is that in order to read from or write to an OPC Data Access server, a sequence of steps has to happen internally - this includes things like creating the server object (which in turn may start the server), adding an OPC group to it, add item to the group, etc. All these things take time, but have to be done only once. QuickOPC has a built-in intelligence that performs all these steps for you. Unfortunately what you have measured is this worst case - first time you write, it indeed does take time. If you have simply repeated the statement that does the initial write, you will see that second time it is much faster (I have done and measured that).
In most applications, you do know upfront that you will need to do such time-critical operation you are asking for, and which OPC items will be involved. In such case, you can trick QuickOPC to do all the preparation tasks beforehand - somewhere in your application initalization code, for example. This is what the part of code marked as "Preparing...." does. You can then do other things as you wish. QuickOPC will "hold" the items for certain amount time, which you can increase: In my example, I have (quite arbitrarily) said
easyDAClient.HoldPeriods.TopicRead = 24 * 60 * 60 * 1000;
which causes QuickOPC to keep the preparation tasks ready for 1 day.
After this "preparation" is done, you can do the actual writing, and it will be done much faster already. There is another way to increase the speed even more, which is done by the line
EasyDAClient.ClientParameters.TopicProcessingIntervalTimeout = 10;
This causes faster internal request "consumption" (the default, slower value is good for scenarios where there is high amount of items, and used from multiple threads).
The remainder of your performance issue - the time you need to loop until the desired value is read - may have to do with how fast the target OPC server and its underlying system work, so there is nothing to be influenced in the application code or the QuickOPC component. It may also be better to replace the loop with a subscription to an item changed event - this allows faster eaction while preventing the CPU overload - and I would be happy to help you with this too, however the actual performance gain doesn't seem to be critical in this case.
With the modified code, here is what I have measured on our test computer:
Preparing...
Prepare: 802
Sleeping...
Sending...
Send: 21
Waiting...
Write Total: 64
So, if you "prepare" upfront, you can get down to 64 milliseconds, well below your required 250 milliseconds. The time toi "prepare" (around 800 milliseconds) still seems a bit long to me, and I will have a look at it further, however I do not expect it to be a problem since it is a one-time operation.
20100929.zip
Please Log in or Create an account to join the conversation.
Hello!
We are currently evaluating Your OPC.Net client. using this test case:
System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
watch.Reset();
watch.Start();
/*
easyDAClient.WriteItemValue("", OPCServerID, dataPoint.Name, dataPoint.SendValue);
easyDAClient.WriteItemValue("", OPCServerID, markerFromID, false);
easyDAClient.WriteItemValue("", OPCServerID, markerToID, true);
*/
List items = new List();
DAItemValueArguments myValue = new DAItemValueArguments("", OPCServerID, dataPoint.Name, dataPoint.SendValue);
items.Add(myValue);
DAItemValueArguments markerFromIDValue = new DAItemValueArguments("", OPCServerID, markerFromID,VarType.Bool, false,null);
items.Add(myValue);
DAItemValueArguments markerToIDValue = new DAItemValueArguments("", OPCServerID, markerToID, VarType.Bool, true, null);
items.Add(myValue);
OperationResult[] result = easyDAClient.WriteMultipleItemValues(items.ToArray());
Console.Out.WriteLine("Send:" + watch.ElapsedMilliseconds + "\n");
//Wait for Event Marker released confirmation
int count = 0;
do
{
count++;
object val = easyDAClient.ReadItemValue("", OPCServerID, markerFromID, VarType.Bool);
if ((val != null) && (Convert.ToBoolean(val)))
read = true;
if (!read) Thread.Sleep(10);
} while (!read);
// easyDAClient.WriteItemValue("", OPCServerID, markerFromID, false);
read = false;
written = false;
Console.Out.WriteLine("Write Total:"+watch.ElapsedMilliseconds+"\n");
watch.Stop();
}
QuickOPC.net needs:
Send:1523 (Writing 3 Values)
Write Total:1981 ( + reading one Value)
We need this 4 Operations to complete in under 250 ms. Is this possible? Are there any optimizations / Config Values we need to set?
P.
Please Log in or Create an account to join the conversation.